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"
52 #include "../benode_t.h"
53 #include "../besched.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
60 #include "bearch_ia32_t.h"
61 #include "ia32_common_transform.h"
62 #include "ia32_nodes_attr.h"
63 #include "ia32_transform.h"
64 #include "ia32_new_nodes.h"
65 #include "ia32_map_regs.h"
66 #include "ia32_dbg_stat.h"
67 #include "ia32_optimize.h"
68 #include "ia32_util.h"
69 #include "ia32_address_mode.h"
70 #include "ia32_architecture.h"
72 #include "gen_ia32_regalloc_if.h"
74 #define SFP_SIGN "0x80000000"
75 #define DFP_SIGN "0x8000000000000000"
76 #define SFP_ABS "0x7FFFFFFF"
77 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
78 #define DFP_INTMAX "9223372036854775807"
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_INT_MAX "ia32_int_max"
86 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
87 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
88 #define ENT_SFP_ABS "IA32_SFP_ABS"
89 #define ENT_DFP_ABS "IA32_DFP_ABS"
90 #define ENT_INT_MAX "IA32_INT_MAX"
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_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
371 static ir_entity *ent_cache[ia32_known_const_max];
373 const char *tp_name, *ent_name, *cnst_str;
381 ent_name = names[kct].ent_name;
382 if (! ent_cache[kct]) {
383 tp_name = names[kct].tp_name;
384 cnst_str = names[kct].cnst_str;
386 switch (names[kct].mode) {
387 case 0: mode = mode_Iu; break;
388 case 1: mode = mode_Lu; break;
389 default: mode = mode_F; break;
391 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
392 tp = new_type_primitive(new_id_from_str(tp_name), mode);
393 /* set the specified alignment */
394 set_type_alignment_bytes(tp, names[kct].align);
396 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
398 set_entity_ld_ident(ent, get_entity_ident(ent));
399 set_entity_visibility(ent, visibility_local);
400 set_entity_variability(ent, variability_constant);
401 set_entity_allocation(ent, allocation_static);
403 /* we create a new entity here: It's initialization must resist on the
405 rem = current_ir_graph;
406 current_ir_graph = get_const_code_irg();
407 cnst = new_Const(mode, tv);
408 current_ir_graph = rem;
410 set_atomic_ent_value(ent, cnst);
412 /* cache the entry */
413 ent_cache[kct] = ent;
416 return ent_cache[kct];
420 * return true if the node is a Proj(Load) and could be used in source address
421 * mode for another node. Will return only true if the @p other node is not
422 * dependent on the memory of the Load (for binary operations use the other
423 * input here, for unary operations use NULL).
425 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
426 ir_node *other, ir_node *other2, match_flags_t flags)
431 /* float constants are always available */
432 if (is_Const(node)) {
433 ir_mode *mode = get_irn_mode(node);
434 if (mode_is_float(mode)) {
435 if (ia32_cg_config.use_sse2) {
436 if (is_simple_sse_Const(node))
439 if (is_simple_x87_Const(node))
442 if (get_irn_n_edges(node) > 1)
450 load = get_Proj_pred(node);
451 pn = get_Proj_proj(node);
452 if (!is_Load(load) || pn != pn_Load_res)
454 if (get_nodes_block(load) != block)
456 /* we only use address mode if we're the only user of the load */
457 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
459 /* in some edge cases with address mode we might reach the load normally
460 * and through some AM sequence, if it is already materialized then we
461 * can't create an AM node from it */
462 if (be_is_transformed(node))
465 /* don't do AM if other node inputs depend on the load (via mem-proj) */
466 if (other != NULL && prevents_AM(block, load, other))
469 if (other2 != NULL && prevents_AM(block, load, other2))
475 typedef struct ia32_address_mode_t ia32_address_mode_t;
476 struct ia32_address_mode_t {
481 ia32_op_type_t op_type;
485 unsigned commutative : 1;
486 unsigned ins_permuted : 1;
489 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
493 /* construct load address */
494 memset(addr, 0, sizeof(addr[0]));
495 ia32_create_address_mode(addr, ptr, 0);
497 noreg_gp = ia32_new_NoReg_gp(env_cg);
498 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
499 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
500 addr->mem = be_transform_node(mem);
503 static void build_address(ia32_address_mode_t *am, ir_node *node,
504 ia32_create_am_flags_t flags)
506 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
507 ia32_address_t *addr = &am->addr;
513 if (is_Const(node)) {
514 ir_entity *entity = create_float_const_entity(node);
515 addr->base = noreg_gp;
516 addr->index = noreg_gp;
517 addr->mem = new_NoMem();
518 addr->symconst_ent = entity;
520 am->ls_mode = get_type_mode(get_entity_type(entity));
521 am->pinned = op_pin_state_floats;
525 load = get_Proj_pred(node);
526 ptr = get_Load_ptr(load);
527 mem = get_Load_mem(load);
528 new_mem = be_transform_node(mem);
529 am->pinned = get_irn_pinned(load);
530 am->ls_mode = get_Load_mode(load);
531 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
534 /* construct load address */
535 ia32_create_address_mode(addr, ptr, flags);
537 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
538 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
542 static void set_address(ir_node *node, const ia32_address_t *addr)
544 set_ia32_am_scale(node, addr->scale);
545 set_ia32_am_sc(node, addr->symconst_ent);
546 set_ia32_am_offs_int(node, addr->offset);
547 if (addr->symconst_sign)
548 set_ia32_am_sc_sign(node);
550 set_ia32_use_frame(node);
551 set_ia32_frame_ent(node, addr->frame_entity);
555 * Apply attributes of a given address mode to a node.
557 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
559 set_address(node, &am->addr);
561 set_ia32_op_type(node, am->op_type);
562 set_ia32_ls_mode(node, am->ls_mode);
563 if (am->pinned == op_pin_state_pinned) {
564 /* beware: some nodes are already pinned and did not allow to change the state */
565 if (get_irn_pinned(node) != op_pin_state_pinned)
566 set_irn_pinned(node, op_pin_state_pinned);
569 set_ia32_commutative(node);
573 * Check, if a given node is a Down-Conv, ie. a integer Conv
574 * from a mode with a mode with more bits to a mode with lesser bits.
575 * Moreover, we return only true if the node has not more than 1 user.
577 * @param node the node
578 * @return non-zero if node is a Down-Conv
580 static int is_downconv(const ir_node *node)
588 /* we only want to skip the conv when we're the only user
589 * (not optimal but for now...)
591 if (get_irn_n_edges(node) > 1)
594 src_mode = get_irn_mode(get_Conv_op(node));
595 dest_mode = get_irn_mode(node);
596 return ia32_mode_needs_gp_reg(src_mode)
597 && ia32_mode_needs_gp_reg(dest_mode)
598 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
601 /* Skip all Down-Conv's on a given node and return the resulting node. */
602 ir_node *ia32_skip_downconv(ir_node *node)
604 while (is_downconv(node))
605 node = get_Conv_op(node);
610 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
612 ir_mode *mode = get_irn_mode(node);
617 if (mode_is_signed(mode)) {
622 block = get_nodes_block(node);
623 dbgi = get_irn_dbg_info(node);
625 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
629 * matches operands of a node into ia32 addressing/operand modes. This covers
630 * usage of source address mode, immediates, operations with non 32-bit modes,
632 * The resulting data is filled into the @p am struct. block is the block
633 * of the node whose arguments are matched. op1, op2 are the first and second
634 * input that are matched (op1 may be NULL). other_op is another unrelated
635 * input that is not matched! but which is needed sometimes to check if AM
636 * for op1/op2 is legal.
637 * @p flags describes the supported modes of the operation in detail.
639 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
640 ir_node *op1, ir_node *op2, ir_node *other_op,
643 ia32_address_t *addr = &am->addr;
644 ir_mode *mode = get_irn_mode(op2);
645 int mode_bits = get_mode_size_bits(mode);
646 ir_node *noreg_gp, *new_op1, *new_op2;
648 unsigned commutative;
649 int use_am_and_immediates;
652 memset(am, 0, sizeof(am[0]));
654 commutative = (flags & match_commutative) != 0;
655 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
656 use_am = (flags & match_am) != 0;
657 use_immediate = (flags & match_immediate) != 0;
658 assert(!use_am_and_immediates || use_immediate);
661 assert(!commutative || op1 != NULL);
662 assert(use_am || !(flags & match_8bit_am));
663 assert(use_am || !(flags & match_16bit_am));
665 if (mode_bits == 8) {
666 if (!(flags & match_8bit_am))
668 /* we don't automatically add upconvs yet */
669 assert((flags & match_mode_neutral) || (flags & match_8bit));
670 } else if (mode_bits == 16) {
671 if (!(flags & match_16bit_am))
673 /* we don't automatically add upconvs yet */
674 assert((flags & match_mode_neutral) || (flags & match_16bit));
677 /* we can simply skip downconvs for mode neutral nodes: the upper bits
678 * can be random for these operations */
679 if (flags & match_mode_neutral) {
680 op2 = ia32_skip_downconv(op2);
682 op1 = ia32_skip_downconv(op1);
686 /* match immediates. firm nodes are normalized: constants are always on the
689 if (!(flags & match_try_am) && use_immediate) {
690 new_op2 = try_create_Immediate(op2, 0);
693 noreg_gp = ia32_new_NoReg_gp(env_cg);
694 if (new_op2 == NULL &&
695 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
696 build_address(am, op2, 0);
697 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
698 if (mode_is_float(mode)) {
699 new_op2 = ia32_new_NoReg_vfp(env_cg);
703 am->op_type = ia32_AddrModeS;
704 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
706 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
708 build_address(am, op1, 0);
710 if (mode_is_float(mode)) {
711 noreg = ia32_new_NoReg_vfp(env_cg);
716 if (new_op2 != NULL) {
719 new_op1 = be_transform_node(op2);
721 am->ins_permuted = 1;
723 am->op_type = ia32_AddrModeS;
725 am->op_type = ia32_Normal;
727 if (flags & match_try_am) {
733 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
735 new_op2 = be_transform_node(op2);
737 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
739 if (addr->base == NULL)
740 addr->base = noreg_gp;
741 if (addr->index == NULL)
742 addr->index = noreg_gp;
743 if (addr->mem == NULL)
744 addr->mem = new_NoMem();
746 am->new_op1 = new_op1;
747 am->new_op2 = new_op2;
748 am->commutative = commutative;
751 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
756 if (am->mem_proj == NULL)
759 /* we have to create a mode_T so the old MemProj can attach to us */
760 mode = get_irn_mode(node);
761 load = get_Proj_pred(am->mem_proj);
763 be_set_transformed_node(load, node);
765 if (mode != mode_T) {
766 set_irn_mode(node, mode_T);
767 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
774 * Construct a standard binary operation, set AM and immediate if required.
776 * @param node The original node for which the binop is created
777 * @param op1 The first operand
778 * @param op2 The second operand
779 * @param func The node constructor function
780 * @return The constructed ia32 node.
782 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
783 construct_binop_func *func, match_flags_t flags)
786 ir_node *block, *new_block, *new_node;
787 ia32_address_mode_t am;
788 ia32_address_t *addr = &am.addr;
790 block = get_nodes_block(node);
791 match_arguments(&am, block, op1, op2, NULL, flags);
793 dbgi = get_irn_dbg_info(node);
794 new_block = be_transform_node(block);
795 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
796 am.new_op1, am.new_op2);
797 set_am_attributes(new_node, &am);
798 /* we can't use source address mode anymore when using immediates */
799 if (!(flags & match_am_and_immediates) &&
800 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
801 set_ia32_am_support(new_node, ia32_am_none);
802 SET_IA32_ORIG_NODE(new_node, node);
804 new_node = fix_mem_proj(new_node, &am);
811 n_ia32_l_binop_right,
812 n_ia32_l_binop_eflags
814 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
815 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
816 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
817 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
818 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
819 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
822 * Construct a binary operation which also consumes the eflags.
824 * @param node The node to transform
825 * @param func The node constructor function
826 * @param flags The match flags
827 * @return The constructor ia32 node
829 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
832 ir_node *src_block = get_nodes_block(node);
833 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
834 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
835 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
837 ir_node *block, *new_node, *new_eflags;
838 ia32_address_mode_t am;
839 ia32_address_t *addr = &am.addr;
841 match_arguments(&am, src_block, op1, op2, eflags, flags);
843 dbgi = get_irn_dbg_info(node);
844 block = be_transform_node(src_block);
845 new_eflags = be_transform_node(eflags);
846 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
847 am.new_op1, am.new_op2, new_eflags);
848 set_am_attributes(new_node, &am);
849 /* we can't use source address mode anymore when using immediates */
850 if (!(flags & match_am_and_immediates) &&
851 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
852 set_ia32_am_support(new_node, ia32_am_none);
853 SET_IA32_ORIG_NODE(new_node, node);
855 new_node = fix_mem_proj(new_node, &am);
860 static ir_node *get_fpcw(void)
863 if (initial_fpcw != NULL)
866 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
867 &ia32_fp_cw_regs[REG_FPCW]);
868 initial_fpcw = be_transform_node(fpcw);
874 * Construct a standard binary operation, set AM and immediate if required.
876 * @param op1 The first operand
877 * @param op2 The second operand
878 * @param func The node constructor function
879 * @return The constructed ia32 node.
881 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
882 construct_binop_float_func *func)
884 ir_mode *mode = get_irn_mode(node);
886 ir_node *block, *new_block, *new_node;
887 ia32_address_mode_t am;
888 ia32_address_t *addr = &am.addr;
889 ia32_x87_attr_t *attr;
890 /* All operations are considered commutative, because there are reverse
892 match_flags_t flags = match_commutative;
894 /* cannot use address mode with long double on x87 */
895 if (get_mode_size_bits(mode) <= 64)
898 block = get_nodes_block(node);
899 match_arguments(&am, block, op1, op2, NULL, flags);
901 dbgi = get_irn_dbg_info(node);
902 new_block = be_transform_node(block);
903 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
904 am.new_op1, am.new_op2, get_fpcw());
905 set_am_attributes(new_node, &am);
907 attr = get_ia32_x87_attr(new_node);
908 attr->attr.data.ins_permuted = am.ins_permuted;
910 SET_IA32_ORIG_NODE(new_node, node);
912 new_node = fix_mem_proj(new_node, &am);
918 * Construct a shift/rotate binary operation, sets AM and immediate if required.
920 * @param op1 The first operand
921 * @param op2 The second operand
922 * @param func The node constructor function
923 * @return The constructed ia32 node.
925 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
926 construct_shift_func *func,
930 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
932 assert(! mode_is_float(get_irn_mode(node)));
933 assert(flags & match_immediate);
934 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
936 if (flags & match_mode_neutral) {
937 op1 = ia32_skip_downconv(op1);
938 new_op1 = be_transform_node(op1);
939 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
940 new_op1 = create_upconv(op1, node);
942 new_op1 = be_transform_node(op1);
945 /* the shift amount can be any mode that is bigger than 5 bits, since all
946 * other bits are ignored anyway */
947 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
948 ir_node *const op = get_Conv_op(op2);
949 if (mode_is_float(get_irn_mode(op)))
952 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
954 new_op2 = create_immediate_or_transform(op2, 0);
956 dbgi = get_irn_dbg_info(node);
957 block = get_nodes_block(node);
958 new_block = be_transform_node(block);
959 new_node = func(dbgi, new_block, new_op1, new_op2);
960 SET_IA32_ORIG_NODE(new_node, node);
962 /* lowered shift instruction may have a dependency operand, handle it here */
963 if (get_irn_arity(node) == 3) {
964 /* we have a dependency */
965 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
966 add_irn_dep(new_node, new_dep);
974 * Construct a standard unary operation, set AM and immediate if required.
976 * @param op The operand
977 * @param func The node constructor function
978 * @return The constructed ia32 node.
980 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
984 ir_node *block, *new_block, *new_op, *new_node;
986 assert(flags == 0 || flags == match_mode_neutral);
987 if (flags & match_mode_neutral) {
988 op = ia32_skip_downconv(op);
991 new_op = be_transform_node(op);
992 dbgi = get_irn_dbg_info(node);
993 block = get_nodes_block(node);
994 new_block = be_transform_node(block);
995 new_node = func(dbgi, new_block, new_op);
997 SET_IA32_ORIG_NODE(new_node, node);
1002 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1003 ia32_address_t *addr)
1005 ir_node *base, *index, *res;
1009 base = ia32_new_NoReg_gp(env_cg);
1011 base = be_transform_node(base);
1014 index = addr->index;
1015 if (index == NULL) {
1016 index = ia32_new_NoReg_gp(env_cg);
1018 index = be_transform_node(index);
1021 res = new_bd_ia32_Lea(dbgi, block, base, index);
1022 set_address(res, addr);
1028 * Returns non-zero if a given address mode has a symbolic or
1029 * numerical offset != 0.
1031 static int am_has_immediates(const ia32_address_t *addr)
1033 return addr->offset != 0 || addr->symconst_ent != NULL
1034 || addr->frame_entity || addr->use_frame;
1038 * Creates an ia32 Add.
1040 * @return the created ia32 Add node
1042 static ir_node *gen_Add(ir_node *node)
1044 ir_mode *mode = get_irn_mode(node);
1045 ir_node *op1 = get_Add_left(node);
1046 ir_node *op2 = get_Add_right(node);
1048 ir_node *block, *new_block, *new_node, *add_immediate_op;
1049 ia32_address_t addr;
1050 ia32_address_mode_t am;
1052 if (mode_is_float(mode)) {
1053 if (ia32_cg_config.use_sse2)
1054 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1055 match_commutative | match_am);
1057 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1060 ia32_mark_non_am(node);
1062 op2 = ia32_skip_downconv(op2);
1063 op1 = ia32_skip_downconv(op1);
1067 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1068 * 1. Add with immediate -> Lea
1069 * 2. Add with possible source address mode -> Add
1070 * 3. Otherwise -> Lea
1072 memset(&addr, 0, sizeof(addr));
1073 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1074 add_immediate_op = NULL;
1076 dbgi = get_irn_dbg_info(node);
1077 block = get_nodes_block(node);
1078 new_block = be_transform_node(block);
1081 if (addr.base == NULL && addr.index == NULL) {
1082 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1083 addr.symconst_sign, addr.offset);
1084 be_dep_on_frame(new_node);
1085 SET_IA32_ORIG_NODE(new_node, node);
1088 /* add with immediate? */
1089 if (addr.index == NULL) {
1090 add_immediate_op = addr.base;
1091 } else if (addr.base == NULL && addr.scale == 0) {
1092 add_immediate_op = addr.index;
1095 if (add_immediate_op != NULL) {
1096 if (!am_has_immediates(&addr)) {
1097 #ifdef DEBUG_libfirm
1098 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1101 return be_transform_node(add_immediate_op);
1104 new_node = create_lea_from_address(dbgi, new_block, &addr);
1105 SET_IA32_ORIG_NODE(new_node, node);
1109 /* test if we can use source address mode */
1110 match_arguments(&am, block, op1, op2, NULL, match_commutative
1111 | match_mode_neutral | match_am | match_immediate | match_try_am);
1113 /* construct an Add with source address mode */
1114 if (am.op_type == ia32_AddrModeS) {
1115 ia32_address_t *am_addr = &am.addr;
1116 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1117 am_addr->index, am_addr->mem, am.new_op1,
1119 set_am_attributes(new_node, &am);
1120 SET_IA32_ORIG_NODE(new_node, node);
1122 new_node = fix_mem_proj(new_node, &am);
1127 /* otherwise construct a lea */
1128 new_node = create_lea_from_address(dbgi, new_block, &addr);
1129 SET_IA32_ORIG_NODE(new_node, node);
1134 * Creates an ia32 Mul.
1136 * @return the created ia32 Mul node
1138 static ir_node *gen_Mul(ir_node *node)
1140 ir_node *op1 = get_Mul_left(node);
1141 ir_node *op2 = get_Mul_right(node);
1142 ir_mode *mode = get_irn_mode(node);
1144 if (mode_is_float(mode)) {
1145 if (ia32_cg_config.use_sse2)
1146 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1147 match_commutative | match_am);
1149 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1151 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1152 match_commutative | match_am | match_mode_neutral |
1153 match_immediate | match_am_and_immediates);
1157 * Creates an ia32 Mulh.
1158 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1159 * this result while Mul returns the lower 32 bit.
1161 * @return the created ia32 Mulh node
1163 static ir_node *gen_Mulh(ir_node *node)
1165 ir_node *block = get_nodes_block(node);
1166 ir_node *new_block = be_transform_node(block);
1167 dbg_info *dbgi = get_irn_dbg_info(node);
1168 ir_node *op1 = get_Mulh_left(node);
1169 ir_node *op2 = get_Mulh_right(node);
1170 ir_mode *mode = get_irn_mode(node);
1172 ir_node *proj_res_high;
1174 if (mode_is_signed(mode)) {
1175 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1176 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1177 mode_Iu, pn_ia32_IMul1OP_res_high);
1179 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1180 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1181 mode_Iu, pn_ia32_Mul_res_high);
1183 return proj_res_high;
1187 * Creates an ia32 And.
1189 * @return The created ia32 And node
1191 static ir_node *gen_And(ir_node *node)
1193 ir_node *op1 = get_And_left(node);
1194 ir_node *op2 = get_And_right(node);
1195 assert(! mode_is_float(get_irn_mode(node)));
1197 /* is it a zero extension? */
1198 if (is_Const(op2)) {
1199 tarval *tv = get_Const_tarval(op2);
1200 long v = get_tarval_long(tv);
1202 if (v == 0xFF || v == 0xFFFF) {
1203 dbg_info *dbgi = get_irn_dbg_info(node);
1204 ir_node *block = get_nodes_block(node);
1211 assert(v == 0xFFFF);
1214 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1219 return gen_binop(node, op1, op2, new_bd_ia32_And,
1220 match_commutative | match_mode_neutral | match_am | match_immediate);
1226 * Creates an ia32 Or.
1228 * @return The created ia32 Or node
1230 static ir_node *gen_Or(ir_node *node)
1232 ir_node *op1 = get_Or_left(node);
1233 ir_node *op2 = get_Or_right(node);
1235 assert (! mode_is_float(get_irn_mode(node)));
1236 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1237 | match_mode_neutral | match_am | match_immediate);
1243 * Creates an ia32 Eor.
1245 * @return The created ia32 Eor node
1247 static ir_node *gen_Eor(ir_node *node)
1249 ir_node *op1 = get_Eor_left(node);
1250 ir_node *op2 = get_Eor_right(node);
1252 assert(! mode_is_float(get_irn_mode(node)));
1253 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1254 | match_mode_neutral | match_am | match_immediate);
1259 * Creates an ia32 Sub.
1261 * @return The created ia32 Sub node
1263 static ir_node *gen_Sub(ir_node *node)
1265 ir_node *op1 = get_Sub_left(node);
1266 ir_node *op2 = get_Sub_right(node);
1267 ir_mode *mode = get_irn_mode(node);
1269 if (mode_is_float(mode)) {
1270 if (ia32_cg_config.use_sse2)
1271 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1273 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1276 if (is_Const(op2)) {
1277 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1281 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1282 | match_am | match_immediate);
1285 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1286 ir_node *const src_val,
1287 ir_node *const src_mem,
1288 ir_node *const am_mem)
1290 if (is_NoMem(am_mem)) {
1291 return be_transform_node(src_mem);
1292 } else if (is_Proj(src_val) &&
1294 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1295 /* avoid memory loop */
1297 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1298 ir_node *const ptr_pred = get_Proj_pred(src_val);
1299 int const arity = get_Sync_n_preds(src_mem);
1304 NEW_ARR_A(ir_node*, ins, arity + 1);
1306 /* NOTE: This sometimes produces dead-code because the old sync in
1307 * src_mem might not be used anymore, we should detect this case
1308 * and kill the sync... */
1309 for (i = arity - 1; i >= 0; --i) {
1310 ir_node *const pred = get_Sync_pred(src_mem, i);
1312 /* avoid memory loop */
1313 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1316 ins[n++] = be_transform_node(pred);
1321 return new_r_Sync(irg, block, n, ins);
1325 ins[0] = be_transform_node(src_mem);
1327 return new_r_Sync(irg, block, 2, ins);
1331 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1332 ir_node *val, const ir_node *orig)
1337 if (ia32_cg_config.use_short_sex_eax) {
1338 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1339 be_dep_on_frame(pval);
1340 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1342 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1343 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1345 SET_IA32_ORIG_NODE(res, orig);
1350 * Generates an ia32 DivMod with additional infrastructure for the
1351 * register allocator if needed.
1353 static ir_node *create_Div(ir_node *node)
1355 dbg_info *dbgi = get_irn_dbg_info(node);
1356 ir_node *block = get_nodes_block(node);
1357 ir_node *new_block = be_transform_node(block);
1364 ir_node *sign_extension;
1365 ia32_address_mode_t am;
1366 ia32_address_t *addr = &am.addr;
1368 /* the upper bits have random contents for smaller modes */
1369 switch (get_irn_opcode(node)) {
1371 op1 = get_Div_left(node);
1372 op2 = get_Div_right(node);
1373 mem = get_Div_mem(node);
1374 mode = get_Div_resmode(node);
1377 op1 = get_Mod_left(node);
1378 op2 = get_Mod_right(node);
1379 mem = get_Mod_mem(node);
1380 mode = get_Mod_resmode(node);
1383 op1 = get_DivMod_left(node);
1384 op2 = get_DivMod_right(node);
1385 mem = get_DivMod_mem(node);
1386 mode = get_DivMod_resmode(node);
1389 panic("invalid divmod node %+F", node);
1392 match_arguments(&am, block, op1, op2, NULL, match_am);
1394 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1395 is the memory of the consumed address. We can have only the second op as address
1396 in Div nodes, so check only op2. */
1397 new_mem = transform_AM_mem(current_ir_graph, block, op2, mem, addr->mem);
1399 if (mode_is_signed(mode)) {
1400 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1401 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1402 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1404 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0);
1405 be_dep_on_frame(sign_extension);
1407 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1408 addr->index, new_mem, am.new_op2,
1409 am.new_op1, sign_extension);
1412 set_irn_pinned(new_node, get_irn_pinned(node));
1414 set_am_attributes(new_node, &am);
1415 SET_IA32_ORIG_NODE(new_node, node);
1417 new_node = fix_mem_proj(new_node, &am);
1423 static ir_node *gen_Mod(ir_node *node)
1425 return create_Div(node);
1428 static ir_node *gen_Div(ir_node *node)
1430 return create_Div(node);
1433 static ir_node *gen_DivMod(ir_node *node)
1435 return create_Div(node);
1441 * Creates an ia32 floating Div.
1443 * @return The created ia32 xDiv node
1445 static ir_node *gen_Quot(ir_node *node)
1447 ir_node *op1 = get_Quot_left(node);
1448 ir_node *op2 = get_Quot_right(node);
1450 if (ia32_cg_config.use_sse2) {
1451 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1453 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1459 * Creates an ia32 Shl.
1461 * @return The created ia32 Shl node
1463 static ir_node *gen_Shl(ir_node *node)
1465 ir_node *left = get_Shl_left(node);
1466 ir_node *right = get_Shl_right(node);
1468 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1469 match_mode_neutral | match_immediate);
1473 * Creates an ia32 Shr.
1475 * @return The created ia32 Shr node
1477 static ir_node *gen_Shr(ir_node *node)
1479 ir_node *left = get_Shr_left(node);
1480 ir_node *right = get_Shr_right(node);
1482 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1488 * Creates an ia32 Sar.
1490 * @return The created ia32 Shrs node
1492 static ir_node *gen_Shrs(ir_node *node)
1494 ir_node *left = get_Shrs_left(node);
1495 ir_node *right = get_Shrs_right(node);
1496 ir_mode *mode = get_irn_mode(node);
1498 if (is_Const(right) && mode == mode_Is) {
1499 tarval *tv = get_Const_tarval(right);
1500 long val = get_tarval_long(tv);
1502 /* this is a sign extension */
1503 dbg_info *dbgi = get_irn_dbg_info(node);
1504 ir_node *block = be_transform_node(get_nodes_block(node));
1505 ir_node *new_op = be_transform_node(left);
1507 return create_sex_32_64(dbgi, block, new_op, node);
1511 /* 8 or 16 bit sign extension? */
1512 if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1513 ir_node *shl_left = get_Shl_left(left);
1514 ir_node *shl_right = get_Shl_right(left);
1515 if (is_Const(shl_right)) {
1516 tarval *tv1 = get_Const_tarval(right);
1517 tarval *tv2 = get_Const_tarval(shl_right);
1518 if (tv1 == tv2 && tarval_is_long(tv1)) {
1519 long val = get_tarval_long(tv1);
1520 if (val == 16 || val == 24) {
1521 dbg_info *dbgi = get_irn_dbg_info(node);
1522 ir_node *block = get_nodes_block(node);
1532 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1541 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1547 * Creates an ia32 Rol.
1549 * @param op1 The first operator
1550 * @param op2 The second operator
1551 * @return The created ia32 RotL node
1553 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1555 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1561 * Creates an ia32 Ror.
1562 * NOTE: There is no RotR with immediate because this would always be a RotL
1563 * "imm-mode_size_bits" which can be pre-calculated.
1565 * @param op1 The first operator
1566 * @param op2 The second operator
1567 * @return The created ia32 RotR node
1569 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1571 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1577 * Creates an ia32 RotR or RotL (depending on the found pattern).
1579 * @return The created ia32 RotL or RotR node
1581 static ir_node *gen_Rotl(ir_node *node)
1583 ir_node *rotate = NULL;
1584 ir_node *op1 = get_Rotl_left(node);
1585 ir_node *op2 = get_Rotl_right(node);
1587 /* Firm has only RotL, so we are looking for a right (op2)
1588 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1589 that means we can create a RotR instead of an Add and a RotL */
1593 ir_node *left = get_Add_left(add);
1594 ir_node *right = get_Add_right(add);
1595 if (is_Const(right)) {
1596 tarval *tv = get_Const_tarval(right);
1597 ir_mode *mode = get_irn_mode(node);
1598 long bits = get_mode_size_bits(mode);
1600 if (is_Minus(left) &&
1601 tarval_is_long(tv) &&
1602 get_tarval_long(tv) == bits &&
1605 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1606 rotate = gen_Ror(node, op1, get_Minus_op(left));
1611 if (rotate == NULL) {
1612 rotate = gen_Rol(node, op1, op2);
1621 * Transforms a Minus node.
1623 * @return The created ia32 Minus node
1625 static ir_node *gen_Minus(ir_node *node)
1627 ir_node *op = get_Minus_op(node);
1628 ir_node *block = be_transform_node(get_nodes_block(node));
1629 dbg_info *dbgi = get_irn_dbg_info(node);
1630 ir_mode *mode = get_irn_mode(node);
1635 if (mode_is_float(mode)) {
1636 ir_node *new_op = be_transform_node(op);
1637 if (ia32_cg_config.use_sse2) {
1638 /* TODO: non-optimal... if we have many xXors, then we should
1639 * rather create a load for the const and use that instead of
1640 * several AM nodes... */
1641 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1642 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1643 ir_node *nomem = new_NoMem();
1645 new_node = new_bd_ia32_xXor(dbgi, block, noreg_gp, noreg_gp,
1646 nomem, new_op, noreg_xmm);
1648 size = get_mode_size_bits(mode);
1649 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1651 set_ia32_am_sc(new_node, ent);
1652 set_ia32_op_type(new_node, ia32_AddrModeS);
1653 set_ia32_ls_mode(new_node, mode);
1655 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1658 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1661 SET_IA32_ORIG_NODE(new_node, node);
1667 * Transforms a Not node.
1669 * @return The created ia32 Not node
1671 static ir_node *gen_Not(ir_node *node)
1673 ir_node *op = get_Not_op(node);
1675 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1676 assert (! mode_is_float(get_irn_mode(node)));
1678 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1684 * Transforms an Abs node.
1686 * @return The created ia32 Abs node
1688 static ir_node *gen_Abs(ir_node *node)
1690 ir_node *block = get_nodes_block(node);
1691 ir_node *new_block = be_transform_node(block);
1692 ir_node *op = get_Abs_op(node);
1693 dbg_info *dbgi = get_irn_dbg_info(node);
1694 ir_mode *mode = get_irn_mode(node);
1695 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1696 ir_node *nomem = new_NoMem();
1702 if (mode_is_float(mode)) {
1703 new_op = be_transform_node(op);
1705 if (ia32_cg_config.use_sse2) {
1706 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1707 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_gp, noreg_gp,
1708 nomem, new_op, noreg_fp);
1710 size = get_mode_size_bits(mode);
1711 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1713 set_ia32_am_sc(new_node, ent);
1715 SET_IA32_ORIG_NODE(new_node, node);
1717 set_ia32_op_type(new_node, ia32_AddrModeS);
1718 set_ia32_ls_mode(new_node, mode);
1720 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1721 SET_IA32_ORIG_NODE(new_node, node);
1724 ir_node *xor, *sign_extension;
1726 if (get_mode_size_bits(mode) == 32) {
1727 new_op = be_transform_node(op);
1729 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1732 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1734 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_gp, noreg_gp,
1735 nomem, new_op, sign_extension);
1736 SET_IA32_ORIG_NODE(xor, node);
1738 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_gp, noreg_gp,
1739 nomem, xor, sign_extension);
1740 SET_IA32_ORIG_NODE(new_node, node);
1747 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1749 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1751 dbg_info *dbgi = get_irn_dbg_info(cmp);
1752 ir_node *block = get_nodes_block(cmp);
1753 ir_node *new_block = be_transform_node(block);
1754 ir_node *op1 = be_transform_node(x);
1755 ir_node *op2 = be_transform_node(n);
1757 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1761 * Transform a node returning a "flag" result.
1763 * @param node the node to transform
1764 * @param pnc_out the compare mode to use
1766 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1775 /* we have a Cmp as input */
1776 if (is_Proj(node)) {
1777 ir_node *pred = get_Proj_pred(node);
1779 pn_Cmp pnc = get_Proj_proj(node);
1780 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1781 ir_node *l = get_Cmp_left(pred);
1782 ir_node *r = get_Cmp_right(pred);
1784 ir_node *la = get_And_left(l);
1785 ir_node *ra = get_And_right(l);
1787 ir_node *c = get_Shl_left(la);
1788 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1789 /* (1 << n) & ra) */
1790 ir_node *n = get_Shl_right(la);
1791 flags = gen_bt(pred, ra, n);
1792 /* we must generate a Jc/Jnc jump */
1793 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1796 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1801 ir_node *c = get_Shl_left(ra);
1802 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1803 /* la & (1 << n)) */
1804 ir_node *n = get_Shl_right(ra);
1805 flags = gen_bt(pred, la, n);
1806 /* we must generate a Jc/Jnc jump */
1807 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1810 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1816 flags = be_transform_node(pred);
1822 /* a mode_b value, we have to compare it against 0 */
1823 dbgi = get_irn_dbg_info(node);
1824 new_block = be_transform_node(get_nodes_block(node));
1825 new_op = be_transform_node(node);
1826 noreg = ia32_new_NoReg_gp(env_cg);
1827 nomem = new_NoMem();
1828 flags = new_bd_ia32_Test(dbgi, new_block, noreg, noreg, nomem, new_op,
1829 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1830 *pnc_out = pn_Cmp_Lg;
1835 * Transforms a Load.
1837 * @return the created ia32 Load node
1839 static ir_node *gen_Load(ir_node *node)
1841 ir_node *old_block = get_nodes_block(node);
1842 ir_node *block = be_transform_node(old_block);
1843 ir_node *ptr = get_Load_ptr(node);
1844 ir_node *mem = get_Load_mem(node);
1845 ir_node *new_mem = be_transform_node(mem);
1848 dbg_info *dbgi = get_irn_dbg_info(node);
1849 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1850 ir_mode *mode = get_Load_mode(node);
1853 ia32_address_t addr;
1855 /* construct load address */
1856 memset(&addr, 0, sizeof(addr));
1857 ia32_create_address_mode(&addr, ptr, 0);
1864 base = be_transform_node(base);
1867 if (index == NULL) {
1870 index = be_transform_node(index);
1873 if (mode_is_float(mode)) {
1874 if (ia32_cg_config.use_sse2) {
1875 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1877 res_mode = mode_xmm;
1879 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1881 res_mode = mode_vfp;
1884 assert(mode != mode_b);
1886 /* create a conv node with address mode for smaller modes */
1887 if (get_mode_size_bits(mode) < 32) {
1888 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1889 new_mem, noreg, mode);
1891 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1896 set_irn_pinned(new_node, get_irn_pinned(node));
1897 set_ia32_op_type(new_node, ia32_AddrModeS);
1898 set_ia32_ls_mode(new_node, mode);
1899 set_address(new_node, &addr);
1901 if (get_irn_pinned(node) == op_pin_state_floats) {
1902 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1903 && pn_ia32_vfld_res == pn_ia32_Load_res
1904 && pn_ia32_Load_res == pn_ia32_res);
1905 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1908 SET_IA32_ORIG_NODE(new_node, node);
1910 be_dep_on_frame(new_node);
1914 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1915 ir_node *ptr, ir_node *other)
1922 /* we only use address mode if we're the only user of the load */
1923 if (get_irn_n_edges(node) > 1)
1926 load = get_Proj_pred(node);
1929 if (get_nodes_block(load) != block)
1932 /* store should have the same pointer as the load */
1933 if (get_Load_ptr(load) != ptr)
1936 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1937 if (other != NULL &&
1938 get_nodes_block(other) == block &&
1939 heights_reachable_in_block(heights, other, load)) {
1943 if (prevents_AM(block, load, mem))
1945 /* Store should be attached to the load via mem */
1946 assert(heights_reachable_in_block(heights, mem, load));
1951 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1952 ir_node *mem, ir_node *ptr, ir_mode *mode,
1953 construct_binop_dest_func *func,
1954 construct_binop_dest_func *func8bit,
1955 match_flags_t flags)
1957 ir_node *src_block = get_nodes_block(node);
1959 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1966 ia32_address_mode_t am;
1967 ia32_address_t *addr = &am.addr;
1968 memset(&am, 0, sizeof(am));
1970 assert(flags & match_dest_am);
1971 assert(flags & match_immediate); /* there is no destam node without... */
1972 commutative = (flags & match_commutative) != 0;
1974 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1975 build_address(&am, op1, ia32_create_am_double_use);
1976 new_op = create_immediate_or_transform(op2, 0);
1977 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1978 build_address(&am, op2, ia32_create_am_double_use);
1979 new_op = create_immediate_or_transform(op1, 0);
1984 if (addr->base == NULL)
1985 addr->base = noreg_gp;
1986 if (addr->index == NULL)
1987 addr->index = noreg_gp;
1988 if (addr->mem == NULL)
1989 addr->mem = new_NoMem();
1991 dbgi = get_irn_dbg_info(node);
1992 block = be_transform_node(src_block);
1993 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
1995 if (get_mode_size_bits(mode) == 8) {
1996 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
1998 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2000 set_address(new_node, addr);
2001 set_ia32_op_type(new_node, ia32_AddrModeD);
2002 set_ia32_ls_mode(new_node, mode);
2003 SET_IA32_ORIG_NODE(new_node, node);
2005 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2006 mem_proj = be_transform_node(am.mem_proj);
2007 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2012 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2013 ir_node *ptr, ir_mode *mode,
2014 construct_unop_dest_func *func)
2016 ir_node *src_block = get_nodes_block(node);
2022 ia32_address_mode_t am;
2023 ia32_address_t *addr = &am.addr;
2025 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2028 memset(&am, 0, sizeof(am));
2029 build_address(&am, op, ia32_create_am_double_use);
2031 dbgi = get_irn_dbg_info(node);
2032 block = be_transform_node(src_block);
2033 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2034 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2035 set_address(new_node, addr);
2036 set_ia32_op_type(new_node, ia32_AddrModeD);
2037 set_ia32_ls_mode(new_node, mode);
2038 SET_IA32_ORIG_NODE(new_node, node);
2040 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2041 mem_proj = be_transform_node(am.mem_proj);
2042 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2047 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2049 ir_mode *mode = get_irn_mode(node);
2050 ir_node *mux_true = get_Mux_true(node);
2051 ir_node *mux_false = get_Mux_false(node);
2061 ia32_address_t addr;
2063 if (get_mode_size_bits(mode) != 8)
2066 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2068 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2074 build_address_ptr(&addr, ptr, mem);
2076 dbgi = get_irn_dbg_info(node);
2077 block = get_nodes_block(node);
2078 new_block = be_transform_node(block);
2079 cond = get_Mux_sel(node);
2080 flags = get_flags_node(cond, &pnc);
2081 new_mem = be_transform_node(mem);
2082 new_node = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2083 addr.index, addr.mem, flags, pnc, negated);
2084 set_address(new_node, &addr);
2085 set_ia32_op_type(new_node, ia32_AddrModeD);
2086 set_ia32_ls_mode(new_node, mode);
2087 SET_IA32_ORIG_NODE(new_node, node);
2092 static ir_node *try_create_dest_am(ir_node *node)
2094 ir_node *val = get_Store_value(node);
2095 ir_node *mem = get_Store_mem(node);
2096 ir_node *ptr = get_Store_ptr(node);
2097 ir_mode *mode = get_irn_mode(val);
2098 unsigned bits = get_mode_size_bits(mode);
2103 /* handle only GP modes for now... */
2104 if (!ia32_mode_needs_gp_reg(mode))
2108 /* store must be the only user of the val node */
2109 if (get_irn_n_edges(val) > 1)
2111 /* skip pointless convs */
2113 ir_node *conv_op = get_Conv_op(val);
2114 ir_mode *pred_mode = get_irn_mode(conv_op);
2115 if (!ia32_mode_needs_gp_reg(pred_mode))
2117 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2125 /* value must be in the same block */
2126 if (get_nodes_block(node) != get_nodes_block(val))
2129 switch (get_irn_opcode(val)) {
2131 op1 = get_Add_left(val);
2132 op2 = get_Add_right(val);
2133 if (ia32_cg_config.use_incdec) {
2134 if (is_Const_1(op2)) {
2135 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2137 } else if (is_Const_Minus_1(op2)) {
2138 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2142 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2143 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2144 match_dest_am | match_commutative |
2148 op1 = get_Sub_left(val);
2149 op2 = get_Sub_right(val);
2150 if (is_Const(op2)) {
2151 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2153 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2154 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2155 match_dest_am | match_immediate);
2158 op1 = get_And_left(val);
2159 op2 = get_And_right(val);
2160 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2161 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2162 match_dest_am | match_commutative |
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_dest_am | match_commutative |
2174 op1 = get_Eor_left(val);
2175 op2 = get_Eor_right(val);
2176 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2177 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2178 match_dest_am | match_commutative |
2182 op1 = get_Shl_left(val);
2183 op2 = get_Shl_right(val);
2184 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2185 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2186 match_dest_am | match_immediate);
2189 op1 = get_Shr_left(val);
2190 op2 = get_Shr_right(val);
2191 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2192 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2193 match_dest_am | match_immediate);
2196 op1 = get_Shrs_left(val);
2197 op2 = get_Shrs_right(val);
2198 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2199 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2200 match_dest_am | match_immediate);
2203 op1 = get_Rotl_left(val);
2204 op2 = get_Rotl_right(val);
2205 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2206 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2207 match_dest_am | match_immediate);
2209 /* TODO: match ROR patterns... */
2211 new_node = try_create_SetMem(val, ptr, mem);
2214 op1 = get_Minus_op(val);
2215 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2218 /* should be lowered already */
2219 assert(mode != mode_b);
2220 op1 = get_Not_op(val);
2221 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2227 if (new_node != NULL) {
2228 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2229 get_irn_pinned(node) == op_pin_state_pinned) {
2230 set_irn_pinned(new_node, op_pin_state_pinned);
2237 static int is_float_to_int_conv(const ir_node *node)
2239 ir_mode *mode = get_irn_mode(node);
2243 if (mode != mode_Is && mode != mode_Hs)
2248 conv_op = get_Conv_op(node);
2249 conv_mode = get_irn_mode(conv_op);
2251 if (!mode_is_float(conv_mode))
2258 * Transform a Store(floatConst) into a sequence of
2261 * @return the created ia32 Store node
2263 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2265 ir_mode *mode = get_irn_mode(cns);
2266 unsigned size = get_mode_size_bytes(mode);
2267 tarval *tv = get_Const_tarval(cns);
2268 ir_node *block = get_nodes_block(node);
2269 ir_node *new_block = be_transform_node(block);
2270 ir_node *ptr = get_Store_ptr(node);
2271 ir_node *mem = get_Store_mem(node);
2272 dbg_info *dbgi = get_irn_dbg_info(node);
2276 ia32_address_t addr;
2278 assert(size % 4 == 0);
2281 build_address_ptr(&addr, ptr, mem);
2285 get_tarval_sub_bits(tv, ofs) |
2286 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2287 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2288 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2289 ir_node *imm = create_Immediate(NULL, 0, val);
2291 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2292 addr.index, addr.mem, imm);
2294 set_irn_pinned(new_node, get_irn_pinned(node));
2295 set_ia32_op_type(new_node, ia32_AddrModeD);
2296 set_ia32_ls_mode(new_node, mode_Iu);
2297 set_address(new_node, &addr);
2298 SET_IA32_ORIG_NODE(new_node, node);
2301 ins[i++] = new_node;
2306 } while (size != 0);
2309 return new_rd_Sync(dbgi, current_ir_graph, new_block, i, ins);
2316 * Generate a vfist or vfisttp instruction.
2318 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2319 ir_node *mem, ir_node *val, ir_node **fist)
2323 if (ia32_cg_config.use_fisttp) {
2324 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2325 if other users exists */
2326 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2327 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2328 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2329 be_new_Keep(reg_class, irg, block, 1, &value);
2331 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2334 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2337 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2343 * Transforms a general (no special case) Store.
2345 * @return the created ia32 Store node
2347 static ir_node *gen_general_Store(ir_node *node)
2349 ir_node *val = get_Store_value(node);
2350 ir_mode *mode = get_irn_mode(val);
2351 ir_node *block = get_nodes_block(node);
2352 ir_node *new_block = be_transform_node(block);
2353 ir_node *ptr = get_Store_ptr(node);
2354 ir_node *mem = get_Store_mem(node);
2355 dbg_info *dbgi = get_irn_dbg_info(node);
2356 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2357 ir_node *new_val, *new_node, *store;
2358 ia32_address_t addr;
2360 /* check for destination address mode */
2361 new_node = try_create_dest_am(node);
2362 if (new_node != NULL)
2365 /* construct store address */
2366 memset(&addr, 0, sizeof(addr));
2367 ia32_create_address_mode(&addr, ptr, 0);
2369 if (addr.base == NULL) {
2372 addr.base = be_transform_node(addr.base);
2375 if (addr.index == NULL) {
2378 addr.index = be_transform_node(addr.index);
2380 addr.mem = be_transform_node(mem);
2382 if (mode_is_float(mode)) {
2383 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2385 while (is_Conv(val) && mode == get_irn_mode(val)) {
2386 ir_node *op = get_Conv_op(val);
2387 if (!mode_is_float(get_irn_mode(op)))
2391 new_val = be_transform_node(val);
2392 if (ia32_cg_config.use_sse2) {
2393 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2394 addr.index, addr.mem, new_val);
2396 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2397 addr.index, addr.mem, new_val, mode);
2400 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2401 val = get_Conv_op(val);
2403 /* TODO: is this optimisation still necessary at all (middleend)? */
2404 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2405 while (is_Conv(val)) {
2406 ir_node *op = get_Conv_op(val);
2407 if (!mode_is_float(get_irn_mode(op)))
2409 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2413 new_val = be_transform_node(val);
2414 new_node = gen_vfist(dbgi, current_ir_graph, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2416 new_val = create_immediate_or_transform(val, 0);
2417 assert(mode != mode_b);
2419 if (get_mode_size_bits(mode) == 8) {
2420 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2421 addr.index, addr.mem, new_val);
2423 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2424 addr.index, addr.mem, new_val);
2429 set_irn_pinned(store, get_irn_pinned(node));
2430 set_ia32_op_type(store, ia32_AddrModeD);
2431 set_ia32_ls_mode(store, mode);
2433 set_address(store, &addr);
2434 SET_IA32_ORIG_NODE(store, node);
2440 * Transforms a Store.
2442 * @return the created ia32 Store node
2444 static ir_node *gen_Store(ir_node *node)
2446 ir_node *val = get_Store_value(node);
2447 ir_mode *mode = get_irn_mode(val);
2449 if (mode_is_float(mode) && is_Const(val)) {
2450 /* We can transform every floating const store
2451 into a sequence of integer stores.
2452 If the constant is already in a register,
2453 it would be better to use it, but we don't
2454 have this information here. */
2455 return gen_float_const_Store(node, val);
2457 return gen_general_Store(node);
2461 * Transforms a Switch.
2463 * @return the created ia32 SwitchJmp node
2465 static ir_node *create_Switch(ir_node *node)
2467 dbg_info *dbgi = get_irn_dbg_info(node);
2468 ir_node *block = be_transform_node(get_nodes_block(node));
2469 ir_node *sel = get_Cond_selector(node);
2470 ir_node *new_sel = be_transform_node(sel);
2471 int switch_min = INT_MAX;
2472 int switch_max = INT_MIN;
2473 long default_pn = get_Cond_defaultProj(node);
2475 const ir_edge_t *edge;
2477 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2479 /* determine the smallest switch case value */
2480 foreach_out_edge(node, edge) {
2481 ir_node *proj = get_edge_src_irn(edge);
2482 long pn = get_Proj_proj(proj);
2483 if (pn == default_pn)
2486 if (pn < switch_min)
2488 if (pn > switch_max)
2492 if ((unsigned) (switch_max - switch_min) > 256000) {
2493 panic("Size of switch %+F bigger than 256000", node);
2496 if (switch_min != 0) {
2497 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2499 /* if smallest switch case is not 0 we need an additional sub */
2500 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg);
2501 add_ia32_am_offs_int(new_sel, -switch_min);
2502 set_ia32_op_type(new_sel, ia32_AddrModeS);
2504 SET_IA32_ORIG_NODE(new_sel, node);
2507 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2508 SET_IA32_ORIG_NODE(new_node, node);
2514 * Transform a Cond node.
2516 static ir_node *gen_Cond(ir_node *node)
2518 ir_node *block = get_nodes_block(node);
2519 ir_node *new_block = be_transform_node(block);
2520 dbg_info *dbgi = get_irn_dbg_info(node);
2521 ir_node *sel = get_Cond_selector(node);
2522 ir_mode *sel_mode = get_irn_mode(sel);
2523 ir_node *flags = NULL;
2527 if (sel_mode != mode_b) {
2528 return create_Switch(node);
2531 /* we get flags from a Cmp */
2532 flags = get_flags_node(sel, &pnc);
2534 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2535 SET_IA32_ORIG_NODE(new_node, node);
2540 static ir_node *gen_be_Copy(ir_node *node)
2542 ir_node *new_node = be_duplicate_node(node);
2543 ir_mode *mode = get_irn_mode(new_node);
2545 if (ia32_mode_needs_gp_reg(mode)) {
2546 set_irn_mode(new_node, mode_Iu);
2552 static ir_node *create_Fucom(ir_node *node)
2554 dbg_info *dbgi = get_irn_dbg_info(node);
2555 ir_node *block = get_nodes_block(node);
2556 ir_node *new_block = be_transform_node(block);
2557 ir_node *left = get_Cmp_left(node);
2558 ir_node *new_left = be_transform_node(left);
2559 ir_node *right = get_Cmp_right(node);
2563 if (ia32_cg_config.use_fucomi) {
2564 new_right = be_transform_node(right);
2565 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2567 set_ia32_commutative(new_node);
2568 SET_IA32_ORIG_NODE(new_node, node);
2570 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2571 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2573 new_right = be_transform_node(right);
2574 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2577 set_ia32_commutative(new_node);
2579 SET_IA32_ORIG_NODE(new_node, node);
2581 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2582 SET_IA32_ORIG_NODE(new_node, node);
2588 static ir_node *create_Ucomi(ir_node *node)
2590 dbg_info *dbgi = get_irn_dbg_info(node);
2591 ir_node *src_block = get_nodes_block(node);
2592 ir_node *new_block = be_transform_node(src_block);
2593 ir_node *left = get_Cmp_left(node);
2594 ir_node *right = get_Cmp_right(node);
2596 ia32_address_mode_t am;
2597 ia32_address_t *addr = &am.addr;
2599 match_arguments(&am, src_block, left, right, NULL,
2600 match_commutative | match_am);
2602 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2603 addr->mem, am.new_op1, am.new_op2,
2605 set_am_attributes(new_node, &am);
2607 SET_IA32_ORIG_NODE(new_node, node);
2609 new_node = fix_mem_proj(new_node, &am);
2615 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2616 * to fold an and into a test node
2618 static bool can_fold_test_and(ir_node *node)
2620 const ir_edge_t *edge;
2622 /** we can only have eq and lg projs */
2623 foreach_out_edge(node, edge) {
2624 ir_node *proj = get_edge_src_irn(edge);
2625 pn_Cmp pnc = get_Proj_proj(proj);
2626 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2634 * returns true if it is assured, that the upper bits of a node are "clean"
2635 * which means for a 16 or 8 bit value, that the upper bits in the register
2636 * are 0 for unsigned and a copy of the last significant bit for signed
2639 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2641 assert(ia32_mode_needs_gp_reg(mode));
2642 if (get_mode_size_bits(mode) >= 32)
2645 if (is_Proj(transformed_node))
2646 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2648 switch (get_ia32_irn_opcode(transformed_node)) {
2649 case iro_ia32_Conv_I2I:
2650 case iro_ia32_Conv_I2I8Bit: {
2651 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2652 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2654 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2661 if (mode_is_signed(mode)) {
2662 return false; /* TODO handle signed modes */
2664 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2665 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2666 const ia32_immediate_attr_t *attr
2667 = get_ia32_immediate_attr_const(right);
2668 if (attr->symconst == 0 &&
2669 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2673 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2677 /* TODO too conservative if shift amount is constant */
2678 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2681 if (!mode_is_signed(mode)) {
2683 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2684 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2686 /* TODO if one is known to be zero extended, then || is sufficient */
2691 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2692 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2694 case iro_ia32_Const:
2695 case iro_ia32_Immediate: {
2696 const ia32_immediate_attr_t *attr =
2697 get_ia32_immediate_attr_const(transformed_node);
2698 if (mode_is_signed(mode)) {
2699 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2700 return shifted == 0 || shifted == -1;
2702 unsigned long shifted = (unsigned long)attr->offset;
2703 shifted >>= get_mode_size_bits(mode);
2704 return shifted == 0;
2714 * Generate code for a Cmp.
2716 static ir_node *gen_Cmp(ir_node *node)
2718 dbg_info *dbgi = get_irn_dbg_info(node);
2719 ir_node *block = get_nodes_block(node);
2720 ir_node *new_block = be_transform_node(block);
2721 ir_node *left = get_Cmp_left(node);
2722 ir_node *right = get_Cmp_right(node);
2723 ir_mode *cmp_mode = get_irn_mode(left);
2725 ia32_address_mode_t am;
2726 ia32_address_t *addr = &am.addr;
2729 if (mode_is_float(cmp_mode)) {
2730 if (ia32_cg_config.use_sse2) {
2731 return create_Ucomi(node);
2733 return create_Fucom(node);
2737 assert(ia32_mode_needs_gp_reg(cmp_mode));
2739 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2740 cmp_unsigned = !mode_is_signed(cmp_mode);
2741 if (is_Const_0(right) &&
2743 get_irn_n_edges(left) == 1 &&
2744 can_fold_test_and(node)) {
2745 /* Test(and_left, and_right) */
2746 ir_node *and_left = get_And_left(left);
2747 ir_node *and_right = get_And_right(left);
2749 /* matze: code here used mode instead of cmd_mode, I think it is always
2750 * the same as cmp_mode, but I leave this here to see if this is really
2753 assert(get_irn_mode(and_left) == cmp_mode);
2755 match_arguments(&am, block, and_left, and_right, NULL,
2757 match_am | match_8bit_am | match_16bit_am |
2758 match_am_and_immediates | match_immediate |
2759 match_8bit | match_16bit);
2761 /* use 32bit compare mode if possible since the opcode is smaller */
2762 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2763 upper_bits_clean(am.new_op2, cmp_mode)) {
2764 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2767 if (get_mode_size_bits(cmp_mode) == 8) {
2768 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2769 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2772 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2773 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2776 /* Cmp(left, right) */
2777 match_arguments(&am, block, left, right, NULL,
2778 match_commutative | match_am | match_8bit_am |
2779 match_16bit_am | match_am_and_immediates |
2780 match_immediate | match_8bit | match_16bit);
2781 /* use 32bit compare mode if possible since the opcode is smaller */
2782 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2783 upper_bits_clean(am.new_op2, cmp_mode)) {
2784 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2787 if (get_mode_size_bits(cmp_mode) == 8) {
2788 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2789 addr->index, addr->mem, am.new_op1,
2790 am.new_op2, am.ins_permuted,
2793 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2794 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2797 set_am_attributes(new_node, &am);
2798 set_ia32_ls_mode(new_node, cmp_mode);
2800 SET_IA32_ORIG_NODE(new_node, node);
2802 new_node = fix_mem_proj(new_node, &am);
2807 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2810 dbg_info *dbgi = get_irn_dbg_info(node);
2811 ir_node *block = get_nodes_block(node);
2812 ir_node *new_block = be_transform_node(block);
2813 ir_node *val_true = get_Mux_true(node);
2814 ir_node *val_false = get_Mux_false(node);
2816 match_flags_t match_flags;
2817 ia32_address_mode_t am;
2818 ia32_address_t *addr;
2820 assert(ia32_cg_config.use_cmov);
2821 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2825 match_flags = match_commutative | match_am | match_16bit_am |
2828 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2830 new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2831 addr->mem, am.new_op1, am.new_op2, new_flags,
2832 am.ins_permuted, pnc);
2833 set_am_attributes(new_node, &am);
2835 SET_IA32_ORIG_NODE(new_node, node);
2837 new_node = fix_mem_proj(new_node, &am);
2843 * Creates a ia32 Setcc instruction.
2845 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2846 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2849 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2850 ir_node *nomem = new_NoMem();
2851 ir_mode *mode = get_irn_mode(orig_node);
2854 new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2855 SET_IA32_ORIG_NODE(new_node, orig_node);
2857 /* we might need to conv the result up */
2858 if (get_mode_size_bits(mode) > 8) {
2859 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg, noreg,
2860 nomem, new_node, mode_Bu);
2861 SET_IA32_ORIG_NODE(new_node, orig_node);
2868 * Create instruction for an unsigned Difference or Zero.
2870 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2872 ir_graph *irg = current_ir_graph;
2873 ir_mode *mode = get_irn_mode(psi);
2874 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2877 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2878 match_mode_neutral | match_am | match_immediate | match_two_users);
2880 block = get_nodes_block(new_node);
2882 if (is_Proj(new_node)) {
2883 sub = get_Proj_pred(new_node);
2884 assert(is_ia32_Sub(sub));
2887 set_irn_mode(sub, mode_T);
2888 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2890 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2892 dbgi = get_irn_dbg_info(psi);
2893 noreg = ia32_new_NoReg_gp(env_cg);
2894 tmpreg = new_bd_ia32_ProduceVal(dbgi, block);
2895 nomem = new_NoMem();
2896 sbb = new_bd_ia32_Sbb(dbgi, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2898 new_node = new_bd_ia32_And(dbgi, block, noreg, noreg, nomem, new_node, sbb);
2899 set_ia32_commutative(new_node);
2904 * Transforms a Mux node into CMov.
2906 * @return The transformed node.
2908 static ir_node *gen_Mux(ir_node *node)
2910 dbg_info *dbgi = get_irn_dbg_info(node);
2911 ir_node *block = get_nodes_block(node);
2912 ir_node *new_block = be_transform_node(block);
2913 ir_node *mux_true = get_Mux_true(node);
2914 ir_node *mux_false = get_Mux_false(node);
2915 ir_node *cond = get_Mux_sel(node);
2916 ir_mode *mode = get_irn_mode(node);
2919 assert(get_irn_mode(cond) == mode_b);
2921 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2922 if (mode_is_float(mode)) {
2923 ir_node *cmp = get_Proj_pred(cond);
2924 ir_node *cmp_left = get_Cmp_left(cmp);
2925 ir_node *cmp_right = get_Cmp_right(cmp);
2926 pn_Cmp pnc = get_Proj_proj(cond);
2928 if (ia32_cg_config.use_sse2) {
2929 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2930 if (cmp_left == mux_true && cmp_right == mux_false) {
2931 /* Mux(a <= b, a, b) => MIN */
2932 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2933 match_commutative | match_am | match_two_users);
2934 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2935 /* Mux(a <= b, b, a) => MAX */
2936 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2937 match_commutative | match_am | match_two_users);
2939 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2940 if (cmp_left == mux_true && cmp_right == mux_false) {
2941 /* Mux(a >= b, a, b) => MAX */
2942 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2943 match_commutative | match_am | match_two_users);
2944 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2945 /* Mux(a >= b, b, a) => MIN */
2946 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2947 match_commutative | match_am | match_two_users);
2951 panic("cannot transform floating point Mux");
2957 assert(ia32_mode_needs_gp_reg(mode));
2959 if (is_Proj(cond)) {
2960 ir_node *cmp = get_Proj_pred(cond);
2962 ir_node *cmp_left = get_Cmp_left(cmp);
2963 ir_node *cmp_right = get_Cmp_right(cmp);
2964 pn_Cmp pnc = get_Proj_proj(cond);
2966 /* check for unsigned Doz first */
2967 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2968 is_Const_0(mux_false) && is_Sub(mux_true) &&
2969 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2970 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2971 return create_Doz(node, cmp_left, cmp_right);
2972 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2973 is_Const_0(mux_true) && is_Sub(mux_false) &&
2974 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2975 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2976 return create_Doz(node, cmp_left, cmp_right);
2981 flags = get_flags_node(cond, &pnc);
2983 if (is_Const(mux_true) && is_Const(mux_false)) {
2984 /* both are const, good */
2985 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2986 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2987 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2988 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2990 /* Not that simple. */
2995 new_node = create_CMov(node, cond, flags, pnc);
3003 * Create a conversion from x87 state register to general purpose.
3005 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3007 ir_node *block = be_transform_node(get_nodes_block(node));
3008 ir_node *op = get_Conv_op(node);
3009 ir_node *new_op = be_transform_node(op);
3010 ia32_code_gen_t *cg = env_cg;
3011 ir_graph *irg = current_ir_graph;
3012 dbg_info *dbgi = get_irn_dbg_info(node);
3013 ir_node *noreg = ia32_new_NoReg_gp(cg);
3014 ir_mode *mode = get_irn_mode(node);
3015 ir_node *fist, *load, *mem;
3017 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3018 set_irn_pinned(fist, op_pin_state_floats);
3019 set_ia32_use_frame(fist);
3020 set_ia32_op_type(fist, ia32_AddrModeD);
3022 assert(get_mode_size_bits(mode) <= 32);
3023 /* exception we can only store signed 32 bit integers, so for unsigned
3024 we store a 64bit (signed) integer and load the lower bits */
3025 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3026 set_ia32_ls_mode(fist, mode_Ls);
3028 set_ia32_ls_mode(fist, mode_Is);
3030 SET_IA32_ORIG_NODE(fist, node);
3033 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg, mem);
3035 set_irn_pinned(load, op_pin_state_floats);
3036 set_ia32_use_frame(load);
3037 set_ia32_op_type(load, ia32_AddrModeS);
3038 set_ia32_ls_mode(load, mode_Is);
3039 if (get_ia32_ls_mode(fist) == mode_Ls) {
3040 ia32_attr_t *attr = get_ia32_attr(load);
3041 attr->data.need_64bit_stackent = 1;
3043 ia32_attr_t *attr = get_ia32_attr(load);
3044 attr->data.need_32bit_stackent = 1;
3046 SET_IA32_ORIG_NODE(load, node);
3048 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3052 * Creates a x87 strict Conv by placing a Store and a Load
3054 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3056 ir_node *block = get_nodes_block(node);
3057 ir_graph *irg = current_ir_graph;
3058 dbg_info *dbgi = get_irn_dbg_info(node);
3059 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3060 ir_node *nomem = new_NoMem();
3061 ir_node *frame = get_irg_frame(irg);
3062 ir_node *store, *load;
3065 store = new_bd_ia32_vfst(dbgi, block, frame, noreg, nomem, node, tgt_mode);
3066 set_ia32_use_frame(store);
3067 set_ia32_op_type(store, ia32_AddrModeD);
3068 SET_IA32_ORIG_NODE(store, node);
3070 load = new_bd_ia32_vfld(dbgi, block, frame, noreg, store, tgt_mode);
3071 set_ia32_use_frame(load);
3072 set_ia32_op_type(load, ia32_AddrModeS);
3073 SET_IA32_ORIG_NODE(load, node);
3075 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3080 * Create a conversion from general purpose to x87 register
3082 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3084 ir_node *src_block = get_nodes_block(node);
3085 ir_node *block = be_transform_node(src_block);
3086 ir_graph *irg = current_ir_graph;
3087 dbg_info *dbgi = get_irn_dbg_info(node);
3088 ir_node *op = get_Conv_op(node);
3089 ir_node *new_op = NULL;
3093 ir_mode *store_mode;
3099 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3100 if (src_mode == mode_Is || src_mode == mode_Hs) {
3101 ia32_address_mode_t am;
3103 match_arguments(&am, src_block, NULL, op, NULL,
3104 match_am | match_try_am | match_16bit | match_16bit_am);
3105 if (am.op_type == ia32_AddrModeS) {
3106 ia32_address_t *addr = &am.addr;
3108 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index,
3110 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3113 set_am_attributes(fild, &am);
3114 SET_IA32_ORIG_NODE(fild, node);
3116 fix_mem_proj(fild, &am);
3121 if (new_op == NULL) {
3122 new_op = be_transform_node(op);
3125 noreg = ia32_new_NoReg_gp(env_cg);
3126 nomem = new_NoMem();
3127 mode = get_irn_mode(op);
3129 /* first convert to 32 bit signed if necessary */
3130 src_bits = get_mode_size_bits(src_mode);
3131 if (src_bits == 8) {
3132 new_op = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg, noreg, nomem,
3134 SET_IA32_ORIG_NODE(new_op, node);
3136 } else if (src_bits < 32) {
3137 new_op = new_bd_ia32_Conv_I2I(dbgi, block, noreg, noreg, nomem,
3139 SET_IA32_ORIG_NODE(new_op, node);
3143 assert(get_mode_size_bits(mode) == 32);
3146 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg, nomem,
3149 set_ia32_use_frame(store);
3150 set_ia32_op_type(store, ia32_AddrModeD);
3151 set_ia32_ls_mode(store, mode_Iu);
3153 /* exception for 32bit unsigned, do a 64bit spill+load */
3154 if (!mode_is_signed(mode)) {
3157 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3159 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3160 noreg, nomem, zero_const);
3162 set_ia32_use_frame(zero_store);
3163 set_ia32_op_type(zero_store, ia32_AddrModeD);
3164 add_ia32_am_offs_int(zero_store, 4);
3165 set_ia32_ls_mode(zero_store, mode_Iu);
3170 store = new_rd_Sync(dbgi, irg, block, 2, in);
3171 store_mode = mode_Ls;
3173 store_mode = mode_Is;
3177 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg, store);
3179 set_ia32_use_frame(fild);
3180 set_ia32_op_type(fild, ia32_AddrModeS);
3181 set_ia32_ls_mode(fild, store_mode);
3183 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3189 * Create a conversion from one integer mode into another one
3191 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3192 dbg_info *dbgi, ir_node *block, ir_node *op,
3195 int src_bits = get_mode_size_bits(src_mode);
3196 int tgt_bits = get_mode_size_bits(tgt_mode);
3197 ir_node *new_block = be_transform_node(block);
3199 ir_mode *smaller_mode;
3201 ia32_address_mode_t am;
3202 ia32_address_t *addr = &am.addr;
3205 if (src_bits < tgt_bits) {
3206 smaller_mode = src_mode;
3207 smaller_bits = src_bits;
3209 smaller_mode = tgt_mode;
3210 smaller_bits = tgt_bits;
3213 #ifdef DEBUG_libfirm
3215 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3220 match_arguments(&am, block, NULL, op, NULL,
3221 match_8bit | match_16bit |
3222 match_am | match_8bit_am | match_16bit_am);
3224 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3225 /* unnecessary conv. in theory it shouldn't have been AM */
3226 assert(is_ia32_NoReg_GP(addr->base));
3227 assert(is_ia32_NoReg_GP(addr->index));
3228 assert(is_NoMem(addr->mem));
3229 assert(am.addr.offset == 0);
3230 assert(am.addr.symconst_ent == NULL);
3234 if (smaller_bits == 8) {
3235 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, addr->base,
3236 addr->index, addr->mem, am.new_op2,
3239 new_node = new_bd_ia32_Conv_I2I(dbgi, new_block, addr->base,
3240 addr->index, addr->mem, am.new_op2,
3243 set_am_attributes(new_node, &am);
3244 /* match_arguments assume that out-mode = in-mode, this isn't true here
3246 set_ia32_ls_mode(new_node, smaller_mode);
3247 SET_IA32_ORIG_NODE(new_node, node);
3248 new_node = fix_mem_proj(new_node, &am);
3253 * Transforms a Conv node.
3255 * @return The created ia32 Conv node
3257 static ir_node *gen_Conv(ir_node *node)
3259 ir_node *block = get_nodes_block(node);
3260 ir_node *new_block = be_transform_node(block);
3261 ir_node *op = get_Conv_op(node);
3262 ir_node *new_op = NULL;
3263 dbg_info *dbgi = get_irn_dbg_info(node);
3264 ir_mode *src_mode = get_irn_mode(op);
3265 ir_mode *tgt_mode = get_irn_mode(node);
3266 int src_bits = get_mode_size_bits(src_mode);
3267 int tgt_bits = get_mode_size_bits(tgt_mode);
3268 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3269 ir_node *nomem = new_NoMem();
3270 ir_node *res = NULL;
3272 if (src_mode == mode_b) {
3273 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3274 /* nothing to do, we already model bools as 0/1 ints */
3275 return be_transform_node(op);
3278 if (src_mode == tgt_mode) {
3279 if (get_Conv_strict(node)) {
3280 if (ia32_cg_config.use_sse2) {
3281 /* when we are in SSE mode, we can kill all strict no-op conversion */
3282 return be_transform_node(op);
3285 /* this should be optimized already, but who knows... */
3286 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3287 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3288 return be_transform_node(op);
3292 if (mode_is_float(src_mode)) {
3293 new_op = be_transform_node(op);
3294 /* we convert from float ... */
3295 if (mode_is_float(tgt_mode)) {
3296 if (src_mode == mode_E && tgt_mode == mode_D
3297 && !get_Conv_strict(node)) {
3298 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3303 if (ia32_cg_config.use_sse2) {
3304 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3305 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg, noreg,
3307 set_ia32_ls_mode(res, tgt_mode);
3309 if (get_Conv_strict(node)) {
3310 res = gen_x87_strict_conv(tgt_mode, new_op);
3311 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3314 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3319 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3320 if (ia32_cg_config.use_sse2) {
3321 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg, noreg,
3323 set_ia32_ls_mode(res, src_mode);
3325 return gen_x87_fp_to_gp(node);
3329 /* we convert from int ... */
3330 if (mode_is_float(tgt_mode)) {
3332 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3333 if (ia32_cg_config.use_sse2) {
3334 new_op = be_transform_node(op);
3335 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg, noreg,
3337 set_ia32_ls_mode(res, tgt_mode);
3339 res = gen_x87_gp_to_fp(node, src_mode);
3340 if (get_Conv_strict(node)) {
3341 /* The strict-Conv is only necessary, if the int mode has more bits
3342 * than the float mantissa */
3343 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3344 size_t float_mantissa;
3345 /* FIXME There is no way to get the mantissa size of a mode */
3346 switch (get_mode_size_bits(tgt_mode)) {
3347 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3348 case 64: float_mantissa = 52 + 1; break;
3350 case 96: float_mantissa = 64; break;
3351 default: float_mantissa = 0; break;
3353 if (float_mantissa < int_mantissa) {
3354 res = gen_x87_strict_conv(tgt_mode, res);
3355 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3360 } else if (tgt_mode == mode_b) {
3361 /* mode_b lowering already took care that we only have 0/1 values */
3362 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3363 src_mode, tgt_mode));
3364 return be_transform_node(op);
3367 if (src_bits == tgt_bits) {
3368 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3369 src_mode, tgt_mode));
3370 return be_transform_node(op);
3373 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3381 static ir_node *create_immediate_or_transform(ir_node *node,
3382 char immediate_constraint_type)
3384 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3385 if (new_node == NULL) {
3386 new_node = be_transform_node(node);
3392 * Transforms a FrameAddr into an ia32 Add.
3394 static ir_node *gen_be_FrameAddr(ir_node *node)
3396 ir_node *block = be_transform_node(get_nodes_block(node));
3397 ir_node *op = be_get_FrameAddr_frame(node);
3398 ir_node *new_op = be_transform_node(op);
3399 dbg_info *dbgi = get_irn_dbg_info(node);
3400 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3403 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg);
3404 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3405 set_ia32_use_frame(new_node);
3407 SET_IA32_ORIG_NODE(new_node, node);
3413 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3415 static ir_node *gen_be_Return(ir_node *node)
3417 ir_graph *irg = current_ir_graph;
3418 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3419 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3420 ir_entity *ent = get_irg_entity(irg);
3421 ir_type *tp = get_entity_type(ent);
3426 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3427 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3430 int pn_ret_val, pn_ret_mem, arity, i;
3432 assert(ret_val != NULL);
3433 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3434 return be_duplicate_node(node);
3437 res_type = get_method_res_type(tp, 0);
3439 if (! is_Primitive_type(res_type)) {
3440 return be_duplicate_node(node);
3443 mode = get_type_mode(res_type);
3444 if (! mode_is_float(mode)) {
3445 return be_duplicate_node(node);
3448 assert(get_method_n_ress(tp) == 1);
3450 pn_ret_val = get_Proj_proj(ret_val);
3451 pn_ret_mem = get_Proj_proj(ret_mem);
3453 /* get the Barrier */
3454 barrier = get_Proj_pred(ret_val);
3456 /* get result input of the Barrier */
3457 ret_val = get_irn_n(barrier, pn_ret_val);
3458 new_ret_val = be_transform_node(ret_val);
3460 /* get memory input of the Barrier */
3461 ret_mem = get_irn_n(barrier, pn_ret_mem);
3462 new_ret_mem = be_transform_node(ret_mem);
3464 frame = get_irg_frame(irg);
3466 dbgi = get_irn_dbg_info(barrier);
3467 block = be_transform_node(get_nodes_block(barrier));
3469 noreg = ia32_new_NoReg_gp(env_cg);
3471 /* store xmm0 onto stack */
3472 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg,
3473 new_ret_mem, new_ret_val);
3474 set_ia32_ls_mode(sse_store, mode);
3475 set_ia32_op_type(sse_store, ia32_AddrModeD);
3476 set_ia32_use_frame(sse_store);
3478 /* load into x87 register */
3479 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg, sse_store, mode);
3480 set_ia32_op_type(fld, ia32_AddrModeS);
3481 set_ia32_use_frame(fld);
3483 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3484 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3486 /* create a new barrier */
3487 arity = get_irn_arity(barrier);
3488 in = ALLOCAN(ir_node*, arity);
3489 for (i = 0; i < arity; ++i) {
3492 if (i == pn_ret_val) {
3494 } else if (i == pn_ret_mem) {
3497 ir_node *in = get_irn_n(barrier, i);
3498 new_in = be_transform_node(in);
3503 new_barrier = new_ir_node(dbgi, irg, block,
3504 get_irn_op(barrier), get_irn_mode(barrier),
3506 copy_node_attr(barrier, new_barrier);
3507 be_duplicate_deps(barrier, new_barrier);
3508 be_set_transformed_node(barrier, new_barrier);
3510 /* transform normally */
3511 return be_duplicate_node(node);
3515 * Transform a be_AddSP into an ia32_SubSP.
3517 static ir_node *gen_be_AddSP(ir_node *node)
3519 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3520 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3522 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3523 match_am | match_immediate);
3527 * Transform a be_SubSP into an ia32_AddSP
3529 static ir_node *gen_be_SubSP(ir_node *node)
3531 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3532 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3534 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3535 match_am | match_immediate);
3539 * Change some phi modes
3541 static ir_node *gen_Phi(ir_node *node)
3543 ir_node *block = be_transform_node(get_nodes_block(node));
3544 ir_graph *irg = current_ir_graph;
3545 dbg_info *dbgi = get_irn_dbg_info(node);
3546 ir_mode *mode = get_irn_mode(node);
3549 if (ia32_mode_needs_gp_reg(mode)) {
3550 /* we shouldn't have any 64bit stuff around anymore */
3551 assert(get_mode_size_bits(mode) <= 32);
3552 /* all integer operations are on 32bit registers now */
3554 } else if (mode_is_float(mode)) {
3555 if (ia32_cg_config.use_sse2) {
3562 /* phi nodes allow loops, so we use the old arguments for now
3563 * and fix this later */
3564 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3565 get_irn_in(node) + 1);
3566 copy_node_attr(node, phi);
3567 be_duplicate_deps(node, phi);
3569 be_enqueue_preds(node);
3577 static ir_node *gen_IJmp(ir_node *node)
3579 ir_node *block = get_nodes_block(node);
3580 ir_node *new_block = be_transform_node(block);
3581 dbg_info *dbgi = get_irn_dbg_info(node);
3582 ir_node *op = get_IJmp_target(node);
3584 ia32_address_mode_t am;
3585 ia32_address_t *addr = &am.addr;
3587 assert(get_irn_mode(op) == mode_P);
3589 match_arguments(&am, block, NULL, op, NULL,
3590 match_am | match_8bit_am | match_16bit_am |
3591 match_immediate | match_8bit | match_16bit);
3593 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3594 addr->mem, am.new_op2);
3595 set_am_attributes(new_node, &am);
3596 SET_IA32_ORIG_NODE(new_node, node);
3598 new_node = fix_mem_proj(new_node, &am);
3604 * Transform a Bound node.
3606 static ir_node *gen_Bound(ir_node *node)
3609 ir_node *lower = get_Bound_lower(node);
3610 dbg_info *dbgi = get_irn_dbg_info(node);
3612 if (is_Const_0(lower)) {
3613 /* typical case for Java */
3614 ir_node *sub, *res, *flags, *block;
3615 ir_graph *irg = current_ir_graph;
3617 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3618 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3620 block = get_nodes_block(res);
3621 if (! is_Proj(res)) {
3623 set_irn_mode(sub, mode_T);
3624 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3626 sub = get_Proj_pred(res);
3628 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3629 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3630 SET_IA32_ORIG_NODE(new_node, node);
3632 panic("generic Bound not supported in ia32 Backend");
3638 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3640 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3641 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3643 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3644 match_immediate | match_mode_neutral);
3647 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3649 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3650 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3651 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3655 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3657 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3658 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3659 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3663 static ir_node *gen_ia32_l_Add(ir_node *node)
3665 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3666 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3667 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3668 match_commutative | match_am | match_immediate |
3669 match_mode_neutral);
3671 if (is_Proj(lowered)) {
3672 lowered = get_Proj_pred(lowered);
3674 assert(is_ia32_Add(lowered));
3675 set_irn_mode(lowered, mode_T);
3681 static ir_node *gen_ia32_l_Adc(ir_node *node)
3683 return gen_binop_flags(node, new_bd_ia32_Adc,
3684 match_commutative | match_am | match_immediate |
3685 match_mode_neutral);
3689 * Transforms a l_MulS into a "real" MulS node.
3691 * @return the created ia32 Mul node
3693 static ir_node *gen_ia32_l_Mul(ir_node *node)
3695 ir_node *left = get_binop_left(node);
3696 ir_node *right = get_binop_right(node);
3698 return gen_binop(node, left, right, new_bd_ia32_Mul,
3699 match_commutative | match_am | match_mode_neutral);
3703 * Transforms a l_IMulS into a "real" IMul1OPS node.
3705 * @return the created ia32 IMul1OP node
3707 static ir_node *gen_ia32_l_IMul(ir_node *node)
3709 ir_node *left = get_binop_left(node);
3710 ir_node *right = get_binop_right(node);
3712 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3713 match_commutative | match_am | match_mode_neutral);
3716 static ir_node *gen_ia32_l_Sub(ir_node *node)
3718 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3719 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3720 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3721 match_am | match_immediate | match_mode_neutral);
3723 if (is_Proj(lowered)) {
3724 lowered = get_Proj_pred(lowered);
3726 assert(is_ia32_Sub(lowered));
3727 set_irn_mode(lowered, mode_T);
3733 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3735 return gen_binop_flags(node, new_bd_ia32_Sbb,
3736 match_am | match_immediate | match_mode_neutral);
3740 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3741 * op1 - target to be shifted
3742 * op2 - contains bits to be shifted into target
3744 * Only op3 can be an immediate.
3746 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3747 ir_node *low, ir_node *count)
3749 ir_node *block = get_nodes_block(node);
3750 ir_node *new_block = be_transform_node(block);
3751 dbg_info *dbgi = get_irn_dbg_info(node);
3752 ir_node *new_high = be_transform_node(high);
3753 ir_node *new_low = be_transform_node(low);
3757 /* the shift amount can be any mode that is bigger than 5 bits, since all
3758 * other bits are ignored anyway */
3759 while (is_Conv(count) &&
3760 get_irn_n_edges(count) == 1 &&
3761 mode_is_int(get_irn_mode(count))) {
3762 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3763 count = get_Conv_op(count);
3765 new_count = create_immediate_or_transform(count, 0);
3767 if (is_ia32_l_ShlD(node)) {
3768 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3771 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3774 SET_IA32_ORIG_NODE(new_node, node);
3779 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3781 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3782 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3783 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3784 return gen_lowered_64bit_shifts(node, high, low, count);
3787 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3789 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3790 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3791 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3792 return gen_lowered_64bit_shifts(node, high, low, count);
3795 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3797 ir_node *src_block = get_nodes_block(node);
3798 ir_node *block = be_transform_node(src_block);
3799 ir_graph *irg = current_ir_graph;
3800 dbg_info *dbgi = get_irn_dbg_info(node);
3801 ir_node *frame = get_irg_frame(irg);
3802 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3803 ir_node *nomem = new_NoMem();
3804 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3805 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3806 ir_node *new_val_low = be_transform_node(val_low);
3807 ir_node *new_val_high = be_transform_node(val_high);
3812 ir_node *store_high;
3814 if (!mode_is_signed(get_irn_mode(val_high))) {
3815 panic("unsigned long long -> float not supported yet (%+F)", node);
3819 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3821 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3823 SET_IA32_ORIG_NODE(store_low, node);
3824 SET_IA32_ORIG_NODE(store_high, node);
3826 set_ia32_use_frame(store_low);
3827 set_ia32_use_frame(store_high);
3828 set_ia32_op_type(store_low, ia32_AddrModeD);
3829 set_ia32_op_type(store_high, ia32_AddrModeD);
3830 set_ia32_ls_mode(store_low, mode_Iu);
3831 set_ia32_ls_mode(store_high, mode_Is);
3832 add_ia32_am_offs_int(store_high, 4);
3836 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3839 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg, sync);
3841 set_ia32_use_frame(fild);
3842 set_ia32_op_type(fild, ia32_AddrModeS);
3843 set_ia32_ls_mode(fild, mode_Ls);
3845 SET_IA32_ORIG_NODE(fild, node);
3847 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3850 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3852 ir_node *src_block = get_nodes_block(node);
3853 ir_node *block = be_transform_node(src_block);
3854 ir_graph *irg = current_ir_graph;
3855 dbg_info *dbgi = get_irn_dbg_info(node);
3856 ir_node *frame = get_irg_frame(irg);
3857 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3858 ir_node *nomem = new_NoMem();
3859 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3860 ir_node *new_val = be_transform_node(val);
3861 ir_node *fist, *mem;
3863 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3864 SET_IA32_ORIG_NODE(fist, node);
3865 set_ia32_use_frame(fist);
3866 set_ia32_op_type(fist, ia32_AddrModeD);
3867 set_ia32_ls_mode(fist, mode_Ls);
3873 * the BAD transformer.
3875 static ir_node *bad_transform(ir_node *node)
3877 panic("No transform function for %+F available.", node);
3881 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3883 ir_graph *irg = current_ir_graph;
3884 ir_node *block = be_transform_node(get_nodes_block(node));
3885 ir_node *pred = get_Proj_pred(node);
3886 ir_node *new_pred = be_transform_node(pred);
3887 ir_node *frame = get_irg_frame(irg);
3888 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3889 dbg_info *dbgi = get_irn_dbg_info(node);
3890 long pn = get_Proj_proj(node);
3895 load = new_bd_ia32_Load(dbgi, block, frame, noreg, new_pred);
3896 SET_IA32_ORIG_NODE(load, node);
3897 set_ia32_use_frame(load);
3898 set_ia32_op_type(load, ia32_AddrModeS);
3899 set_ia32_ls_mode(load, mode_Iu);
3900 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3901 * 32 bit from it with this particular load */
3902 attr = get_ia32_attr(load);
3903 attr->data.need_64bit_stackent = 1;
3905 if (pn == pn_ia32_l_FloattoLL_res_high) {
3906 add_ia32_am_offs_int(load, 4);
3908 assert(pn == pn_ia32_l_FloattoLL_res_low);
3911 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3917 * Transform the Projs of an AddSP.
3919 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3921 ir_node *block = be_transform_node(get_nodes_block(node));
3922 ir_node *pred = get_Proj_pred(node);
3923 ir_node *new_pred = be_transform_node(pred);
3924 ir_graph *irg = current_ir_graph;
3925 dbg_info *dbgi = get_irn_dbg_info(node);
3926 long proj = get_Proj_proj(node);
3928 if (proj == pn_be_AddSP_sp) {
3929 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3930 pn_ia32_SubSP_stack);
3931 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3933 } else if (proj == pn_be_AddSP_res) {
3934 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3935 pn_ia32_SubSP_addr);
3936 } else if (proj == pn_be_AddSP_M) {
3937 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3940 panic("No idea how to transform proj->AddSP");
3944 * Transform the Projs of a SubSP.
3946 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3948 ir_node *block = be_transform_node(get_nodes_block(node));
3949 ir_node *pred = get_Proj_pred(node);
3950 ir_node *new_pred = be_transform_node(pred);
3951 ir_graph *irg = current_ir_graph;
3952 dbg_info *dbgi = get_irn_dbg_info(node);
3953 long proj = get_Proj_proj(node);
3955 if (proj == pn_be_SubSP_sp) {
3956 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3957 pn_ia32_AddSP_stack);
3958 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3960 } else if (proj == pn_be_SubSP_M) {
3961 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3964 panic("No idea how to transform proj->SubSP");
3968 * Transform and renumber the Projs from a Load.
3970 static ir_node *gen_Proj_Load(ir_node *node)
3973 ir_node *block = be_transform_node(get_nodes_block(node));
3974 ir_node *pred = get_Proj_pred(node);
3975 ir_graph *irg = current_ir_graph;
3976 dbg_info *dbgi = get_irn_dbg_info(node);
3977 long proj = get_Proj_proj(node);
3979 /* loads might be part of source address mode matches, so we don't
3980 * transform the ProjMs yet (with the exception of loads whose result is
3983 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
3986 /* this is needed, because sometimes we have loops that are only
3987 reachable through the ProjM */
3988 be_enqueue_preds(node);
3989 /* do it in 2 steps, to silence firm verifier */
3990 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
3991 set_Proj_proj(res, pn_ia32_mem);
3995 /* renumber the proj */
3996 new_pred = be_transform_node(pred);
3997 if (is_ia32_Load(new_pred)) {
4000 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4002 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4003 case pn_Load_X_regular:
4004 return new_rd_Jmp(dbgi, irg, block);
4005 case pn_Load_X_except:
4006 /* This Load might raise an exception. Mark it. */
4007 set_ia32_exc_label(new_pred, 1);
4008 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4012 } else if (is_ia32_Conv_I2I(new_pred) ||
4013 is_ia32_Conv_I2I8Bit(new_pred)) {
4014 set_irn_mode(new_pred, mode_T);
4015 if (proj == pn_Load_res) {
4016 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4017 } else if (proj == pn_Load_M) {
4018 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4020 } else if (is_ia32_xLoad(new_pred)) {
4023 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4025 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4026 case pn_Load_X_regular:
4027 return new_rd_Jmp(dbgi, irg, block);
4028 case pn_Load_X_except:
4029 /* This Load might raise an exception. Mark it. */
4030 set_ia32_exc_label(new_pred, 1);
4031 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4035 } else if (is_ia32_vfld(new_pred)) {
4038 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4040 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4041 case pn_Load_X_regular:
4042 return new_rd_Jmp(dbgi, irg, block);
4043 case pn_Load_X_except:
4044 /* This Load might raise an exception. Mark it. */
4045 set_ia32_exc_label(new_pred, 1);
4046 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4051 /* can happen for ProJMs when source address mode happened for the
4054 /* however it should not be the result proj, as that would mean the
4055 load had multiple users and should not have been used for
4057 if (proj != pn_Load_M) {
4058 panic("internal error: transformed node not a Load");
4060 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4063 panic("No idea how to transform proj");
4067 * Transform and renumber the Projs from a DivMod like instruction.
4069 static ir_node *gen_Proj_DivMod(ir_node *node)
4071 ir_node *block = be_transform_node(get_nodes_block(node));
4072 ir_node *pred = get_Proj_pred(node);
4073 ir_node *new_pred = be_transform_node(pred);
4074 ir_graph *irg = current_ir_graph;
4075 dbg_info *dbgi = get_irn_dbg_info(node);
4076 long proj = get_Proj_proj(node);
4078 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4080 switch (get_irn_opcode(pred)) {
4084 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4086 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4087 case pn_Div_X_regular:
4088 return new_rd_Jmp(dbgi, irg, block);
4089 case pn_Div_X_except:
4090 set_ia32_exc_label(new_pred, 1);
4091 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4099 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4101 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4102 case pn_Mod_X_except:
4103 set_ia32_exc_label(new_pred, 1);
4104 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4112 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4113 case pn_DivMod_res_div:
4114 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4115 case pn_DivMod_res_mod:
4116 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4117 case pn_DivMod_X_regular:
4118 return new_rd_Jmp(dbgi, irg, block);
4119 case pn_DivMod_X_except:
4120 set_ia32_exc_label(new_pred, 1);
4121 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4130 panic("No idea how to transform proj->DivMod");
4134 * Transform and renumber the Projs from a CopyB.
4136 static ir_node *gen_Proj_CopyB(ir_node *node)
4138 ir_node *block = be_transform_node(get_nodes_block(node));
4139 ir_node *pred = get_Proj_pred(node);
4140 ir_node *new_pred = be_transform_node(pred);
4141 ir_graph *irg = current_ir_graph;
4142 dbg_info *dbgi = get_irn_dbg_info(node);
4143 long proj = get_Proj_proj(node);
4146 case pn_CopyB_M_regular:
4147 if (is_ia32_CopyB_i(new_pred)) {
4148 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4149 } else if (is_ia32_CopyB(new_pred)) {
4150 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4157 panic("No idea how to transform proj->CopyB");
4161 * Transform and renumber the Projs from a Quot.
4163 static ir_node *gen_Proj_Quot(ir_node *node)
4165 ir_node *block = be_transform_node(get_nodes_block(node));
4166 ir_node *pred = get_Proj_pred(node);
4167 ir_node *new_pred = be_transform_node(pred);
4168 ir_graph *irg = current_ir_graph;
4169 dbg_info *dbgi = get_irn_dbg_info(node);
4170 long proj = get_Proj_proj(node);
4174 if (is_ia32_xDiv(new_pred)) {
4175 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4176 } else if (is_ia32_vfdiv(new_pred)) {
4177 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4181 if (is_ia32_xDiv(new_pred)) {
4182 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4183 } else if (is_ia32_vfdiv(new_pred)) {
4184 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4187 case pn_Quot_X_regular:
4188 case pn_Quot_X_except:
4193 panic("No idea how to transform proj->Quot");
4196 static ir_node *gen_be_Call(ir_node *node)
4198 dbg_info *const dbgi = get_irn_dbg_info(node);
4199 ir_graph *const irg = current_ir_graph;
4200 ir_node *const src_block = get_nodes_block(node);
4201 ir_node *const block = be_transform_node(src_block);
4202 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4203 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4204 ir_node *const sp = be_transform_node(src_sp);
4205 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4206 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4207 ia32_address_mode_t am;
4208 ia32_address_t *const addr = &am.addr;
4213 ir_node * eax = noreg;
4214 ir_node * ecx = noreg;
4215 ir_node * edx = noreg;
4216 unsigned const pop = be_Call_get_pop(node);
4217 ir_type *const call_tp = be_Call_get_type(node);
4219 /* Run the x87 simulator if the call returns a float value */
4220 if (get_method_n_ress(call_tp) > 0) {
4221 ir_type *const res_type = get_method_res_type(call_tp, 0);
4222 ir_mode *const res_mode = get_type_mode(res_type);
4224 if (res_mode != NULL && mode_is_float(res_mode)) {
4225 env_cg->do_x87_sim = 1;
4229 /* We do not want be_Call direct calls */
4230 assert(be_Call_get_entity(node) == NULL);
4232 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4233 match_am | match_immediate);
4235 i = get_irn_arity(node) - 1;
4236 fpcw = be_transform_node(get_irn_n(node, i--));
4237 for (; i >= be_pos_Call_first_arg; --i) {
4238 arch_register_req_t const *const req = arch_get_register_req(node, i);
4239 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4241 assert(req->type == arch_register_req_type_limited);
4242 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4244 switch (*req->limited) {
4245 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4246 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4247 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4248 default: panic("Invalid GP register for register parameter");
4252 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4253 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4254 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4255 set_am_attributes(call, &am);
4256 call = fix_mem_proj(call, &am);
4258 if (get_irn_pinned(node) == op_pin_state_pinned)
4259 set_irn_pinned(call, op_pin_state_pinned);
4261 SET_IA32_ORIG_NODE(call, node);
4265 static ir_node *gen_be_IncSP(ir_node *node)
4267 ir_node *res = be_duplicate_node(node);
4268 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4274 * Transform the Projs from a be_Call.
4276 static ir_node *gen_Proj_be_Call(ir_node *node)
4278 ir_node *block = be_transform_node(get_nodes_block(node));
4279 ir_node *call = get_Proj_pred(node);
4280 ir_node *new_call = be_transform_node(call);
4281 ir_graph *irg = current_ir_graph;
4282 dbg_info *dbgi = get_irn_dbg_info(node);
4283 ir_type *method_type = be_Call_get_type(call);
4284 int n_res = get_method_n_ress(method_type);
4285 long proj = get_Proj_proj(node);
4286 ir_mode *mode = get_irn_mode(node);
4290 /* The following is kinda tricky: If we're using SSE, then we have to
4291 * move the result value of the call in floating point registers to an
4292 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4293 * after the call, we have to make sure to correctly make the
4294 * MemProj and the result Proj use these 2 nodes
4296 if (proj == pn_be_Call_M_regular) {
4297 // get new node for result, are we doing the sse load/store hack?
4298 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4299 ir_node *call_res_new;
4300 ir_node *call_res_pred = NULL;
4302 if (call_res != NULL) {
4303 call_res_new = be_transform_node(call_res);
4304 call_res_pred = get_Proj_pred(call_res_new);
4307 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4308 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4311 assert(is_ia32_xLoad(call_res_pred));
4312 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4316 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4317 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4319 ir_node *frame = get_irg_frame(irg);
4320 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4322 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4325 /* in case there is no memory output: create one to serialize the copy
4327 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4328 pn_be_Call_M_regular);
4329 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4330 pn_be_Call_first_res);
4332 /* store st(0) onto stack */
4333 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg, call_mem,
4335 set_ia32_op_type(fstp, ia32_AddrModeD);
4336 set_ia32_use_frame(fstp);
4338 /* load into SSE register */
4339 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg, fstp, mode);
4340 set_ia32_op_type(sse_load, ia32_AddrModeS);
4341 set_ia32_use_frame(sse_load);
4343 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4349 /* transform call modes */
4350 if (mode_is_data(mode)) {
4351 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4355 /* Map from be_Call to ia32_Call proj number */
4356 if (proj == pn_be_Call_sp) {
4357 proj = pn_ia32_Call_stack;
4358 } else if (proj == pn_be_Call_M_regular) {
4359 proj = pn_ia32_Call_M;
4361 arch_register_req_t const *const req = arch_get_register_req_out(node);
4362 int const n_outs = arch_irn_get_n_outs(new_call);
4365 assert(proj >= pn_be_Call_first_res);
4366 assert(req->type & arch_register_req_type_limited);
4368 for (i = 0; i < n_outs; ++i) {
4369 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4371 if (!(new_req->type & arch_register_req_type_limited) ||
4372 new_req->cls != req->cls ||
4373 *new_req->limited != *req->limited)
4382 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4384 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4386 case pn_ia32_Call_stack:
4387 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4390 case pn_ia32_Call_fpcw:
4391 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4399 * Transform the Projs from a Cmp.
4401 static ir_node *gen_Proj_Cmp(ir_node *node)
4403 /* this probably means not all mode_b nodes were lowered... */
4404 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4409 * Transform the Projs from a Bound.
4411 static ir_node *gen_Proj_Bound(ir_node *node)
4413 ir_node *new_node, *block;
4414 ir_node *pred = get_Proj_pred(node);
4416 switch (get_Proj_proj(node)) {
4418 return be_transform_node(get_Bound_mem(pred));
4419 case pn_Bound_X_regular:
4420 new_node = be_transform_node(pred);
4421 block = get_nodes_block(new_node);
4422 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4423 case pn_Bound_X_except:
4424 new_node = be_transform_node(pred);
4425 block = get_nodes_block(new_node);
4426 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4428 return be_transform_node(get_Bound_index(pred));
4430 panic("unsupported Proj from Bound");
4434 static ir_node *gen_Proj_ASM(ir_node *node)
4440 if (get_irn_mode(node) != mode_M)
4441 return be_duplicate_node(node);
4443 pred = get_Proj_pred(node);
4444 new_pred = be_transform_node(pred);
4445 block = get_nodes_block(new_pred);
4446 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4447 arch_irn_get_n_outs(new_pred) + 1);
4451 * Transform and potentially renumber Proj nodes.
4453 static ir_node *gen_Proj(ir_node *node)
4455 ir_node *pred = get_Proj_pred(node);
4458 switch (get_irn_opcode(pred)) {
4460 proj = get_Proj_proj(node);
4461 if (proj == pn_Store_M) {
4462 return be_transform_node(pred);
4464 panic("No idea how to transform proj->Store");
4467 return gen_Proj_Load(node);
4469 return gen_Proj_ASM(node);
4473 return gen_Proj_DivMod(node);
4475 return gen_Proj_CopyB(node);
4477 return gen_Proj_Quot(node);
4479 return gen_Proj_be_SubSP(node);
4481 return gen_Proj_be_AddSP(node);
4483 return gen_Proj_be_Call(node);
4485 return gen_Proj_Cmp(node);
4487 return gen_Proj_Bound(node);
4489 proj = get_Proj_proj(node);
4491 case pn_Start_X_initial_exec: {
4492 ir_node *block = get_nodes_block(pred);
4493 ir_node *new_block = be_transform_node(block);
4494 dbg_info *dbgi = get_irn_dbg_info(node);
4495 /* we exchange the ProjX with a jump */
4496 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4501 case pn_Start_P_tls:
4502 return gen_Proj_tls(node);
4507 if (is_ia32_l_FloattoLL(pred)) {
4508 return gen_Proj_l_FloattoLL(node);
4510 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4514 ir_mode *mode = get_irn_mode(node);
4515 if (ia32_mode_needs_gp_reg(mode)) {
4516 ir_node *new_pred = be_transform_node(pred);
4517 ir_node *block = be_transform_node(get_nodes_block(node));
4518 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4519 mode_Iu, get_Proj_proj(node));
4520 #ifdef DEBUG_libfirm
4521 new_proj->node_nr = node->node_nr;
4527 return be_duplicate_node(node);
4531 * Enters all transform functions into the generic pointer
4533 static void register_transformers(void)
4537 /* first clear the generic function pointer for all ops */
4538 clear_irp_opcodes_generic_func();
4540 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4541 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4579 /* transform ops from intrinsic lowering */
4591 GEN(ia32_l_LLtoFloat);
4592 GEN(ia32_l_FloattoLL);
4598 /* we should never see these nodes */
4613 /* handle generic backend nodes */
4622 op_Mulh = get_op_Mulh();
4631 * Pre-transform all unknown and noreg nodes.
4633 static void ia32_pretransform_node(void)
4635 ia32_code_gen_t *cg = env_cg;
4637 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4638 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4639 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4640 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4641 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4642 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4647 * Walker, checks if all ia32 nodes producing more than one result have their
4648 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4650 static void add_missing_keep_walker(ir_node *node, void *data)
4653 unsigned found_projs = 0;
4654 const ir_edge_t *edge;
4655 ir_mode *mode = get_irn_mode(node);
4660 if (!is_ia32_irn(node))
4663 n_outs = arch_irn_get_n_outs(node);
4666 if (is_ia32_SwitchJmp(node))
4669 assert(n_outs < (int) sizeof(unsigned) * 8);
4670 foreach_out_edge(node, edge) {
4671 ir_node *proj = get_edge_src_irn(edge);
4674 /* The node could be kept */
4678 if (get_irn_mode(proj) == mode_M)
4681 pn = get_Proj_proj(proj);
4682 assert(pn < n_outs);
4683 found_projs |= 1 << pn;
4687 /* are keeps missing? */
4689 for (i = 0; i < n_outs; ++i) {
4692 const arch_register_req_t *req;
4693 const arch_register_class_t *cls;
4695 if (found_projs & (1 << i)) {
4699 req = get_ia32_out_req(node, i);
4704 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4708 block = get_nodes_block(node);
4709 in[0] = new_r_Proj(current_ir_graph, block, node,
4710 arch_register_class_mode(cls), i);
4711 if (last_keep != NULL) {
4712 be_Keep_add_node(last_keep, cls, in[0]);
4714 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4715 if (sched_is_scheduled(node)) {
4716 sched_add_after(node, last_keep);
4723 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4726 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4728 ir_graph *irg = be_get_birg_irg(cg->birg);
4729 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4732 /* do the transformation */
4733 void ia32_transform_graph(ia32_code_gen_t *cg)
4737 register_transformers();
4739 initial_fpcw = NULL;
4741 BE_TIMER_PUSH(t_heights);
4742 heights = heights_new(cg->irg);
4743 BE_TIMER_POP(t_heights);
4744 ia32_calculate_non_address_mode_nodes(cg->birg);
4746 /* the transform phase is not safe for CSE (yet) because several nodes get
4747 * attributes set after their creation */
4748 cse_last = get_opt_cse();
4751 be_transform_graph(cg->birg, ia32_pretransform_node);
4753 set_opt_cse(cse_last);
4755 ia32_free_non_address_mode_nodes();
4756 heights_free(heights);
4760 void ia32_init_transform(void)
4762 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");