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);
597 ia32_mode_needs_gp_reg(src_mode) &&
598 ia32_mode_needs_gp_reg(dest_mode) &&
599 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
602 /* Skip all Down-Conv's on a given node and return the resulting node. */
603 ir_node *ia32_skip_downconv(ir_node *node)
605 while (is_downconv(node))
606 node = get_Conv_op(node);
611 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
613 ir_mode *mode = get_irn_mode(node);
618 if (mode_is_signed(mode)) {
623 block = get_nodes_block(node);
624 dbgi = get_irn_dbg_info(node);
626 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
630 * matches operands of a node into ia32 addressing/operand modes. This covers
631 * usage of source address mode, immediates, operations with non 32-bit modes,
633 * The resulting data is filled into the @p am struct. block is the block
634 * of the node whose arguments are matched. op1, op2 are the first and second
635 * input that are matched (op1 may be NULL). other_op is another unrelated
636 * input that is not matched! but which is needed sometimes to check if AM
637 * for op1/op2 is legal.
638 * @p flags describes the supported modes of the operation in detail.
640 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
641 ir_node *op1, ir_node *op2, ir_node *other_op,
644 ia32_address_t *addr = &am->addr;
645 ir_mode *mode = get_irn_mode(op2);
646 int mode_bits = get_mode_size_bits(mode);
647 ir_node *noreg_gp, *new_op1, *new_op2;
649 unsigned commutative;
650 int use_am_and_immediates;
653 memset(am, 0, sizeof(am[0]));
655 commutative = (flags & match_commutative) != 0;
656 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
657 use_am = (flags & match_am) != 0;
658 use_immediate = (flags & match_immediate) != 0;
659 assert(!use_am_and_immediates || use_immediate);
662 assert(!commutative || op1 != NULL);
663 assert(use_am || !(flags & match_8bit_am));
664 assert(use_am || !(flags & match_16bit_am));
666 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
667 (mode_bits == 16 && !(flags & match_16bit_am))) {
671 /* we can simply skip downconvs for mode neutral nodes: the upper bits
672 * can be random for these operations */
673 if (flags & match_mode_neutral) {
674 op2 = ia32_skip_downconv(op2);
676 op1 = ia32_skip_downconv(op1);
680 /* match immediates. firm nodes are normalized: constants are always on the
683 if (!(flags & match_try_am) && use_immediate) {
684 new_op2 = try_create_Immediate(op2, 0);
687 noreg_gp = ia32_new_NoReg_gp(env_cg);
688 if (new_op2 == NULL &&
689 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
690 build_address(am, op2, 0);
691 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
692 if (mode_is_float(mode)) {
693 new_op2 = ia32_new_NoReg_vfp(env_cg);
697 am->op_type = ia32_AddrModeS;
698 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
700 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
702 build_address(am, op1, 0);
704 if (mode_is_float(mode)) {
705 noreg = ia32_new_NoReg_vfp(env_cg);
710 if (new_op2 != NULL) {
713 new_op1 = be_transform_node(op2);
715 am->ins_permuted = 1;
717 am->op_type = ia32_AddrModeS;
719 am->op_type = ia32_Normal;
721 if (flags & match_try_am) {
727 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
729 new_op2 = be_transform_node(op2);
731 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
733 if (addr->base == NULL)
734 addr->base = noreg_gp;
735 if (addr->index == NULL)
736 addr->index = noreg_gp;
737 if (addr->mem == NULL)
738 addr->mem = new_NoMem();
740 am->new_op1 = new_op1;
741 am->new_op2 = new_op2;
742 am->commutative = commutative;
745 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
750 if (am->mem_proj == NULL)
753 /* we have to create a mode_T so the old MemProj can attach to us */
754 mode = get_irn_mode(node);
755 load = get_Proj_pred(am->mem_proj);
757 be_set_transformed_node(load, node);
759 if (mode != mode_T) {
760 set_irn_mode(node, mode_T);
761 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
768 * Construct a standard binary operation, set AM and immediate if required.
770 * @param node The original node for which the binop is created
771 * @param op1 The first operand
772 * @param op2 The second operand
773 * @param func The node constructor function
774 * @return The constructed ia32 node.
776 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
777 construct_binop_func *func, match_flags_t flags)
780 ir_node *block, *new_block, *new_node;
781 ia32_address_mode_t am;
782 ia32_address_t *addr = &am.addr;
784 block = get_nodes_block(node);
785 match_arguments(&am, block, op1, op2, NULL, flags);
787 dbgi = get_irn_dbg_info(node);
788 new_block = be_transform_node(block);
789 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
790 am.new_op1, am.new_op2);
791 set_am_attributes(new_node, &am);
792 /* we can't use source address mode anymore when using immediates */
793 if (!(flags & match_am_and_immediates) &&
794 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
795 set_ia32_am_support(new_node, ia32_am_none);
796 SET_IA32_ORIG_NODE(new_node, node);
798 new_node = fix_mem_proj(new_node, &am);
805 n_ia32_l_binop_right,
806 n_ia32_l_binop_eflags
808 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
809 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
810 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
811 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
812 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
813 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
816 * Construct a binary operation which also consumes the eflags.
818 * @param node The node to transform
819 * @param func The node constructor function
820 * @param flags The match flags
821 * @return The constructor ia32 node
823 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
826 ir_node *src_block = get_nodes_block(node);
827 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
828 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
829 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
831 ir_node *block, *new_node, *new_eflags;
832 ia32_address_mode_t am;
833 ia32_address_t *addr = &am.addr;
835 match_arguments(&am, src_block, op1, op2, eflags, flags);
837 dbgi = get_irn_dbg_info(node);
838 block = be_transform_node(src_block);
839 new_eflags = be_transform_node(eflags);
840 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
841 am.new_op1, am.new_op2, new_eflags);
842 set_am_attributes(new_node, &am);
843 /* we can't use source address mode anymore when using immediates */
844 if (!(flags & match_am_and_immediates) &&
845 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
846 set_ia32_am_support(new_node, ia32_am_none);
847 SET_IA32_ORIG_NODE(new_node, node);
849 new_node = fix_mem_proj(new_node, &am);
854 static ir_node *get_fpcw(void)
857 if (initial_fpcw != NULL)
860 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
861 &ia32_fp_cw_regs[REG_FPCW]);
862 initial_fpcw = be_transform_node(fpcw);
868 * Construct a standard binary operation, set AM and immediate if required.
870 * @param op1 The first operand
871 * @param op2 The second operand
872 * @param func The node constructor function
873 * @return The constructed ia32 node.
875 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
876 construct_binop_float_func *func)
878 ir_mode *mode = get_irn_mode(node);
880 ir_node *block, *new_block, *new_node;
881 ia32_address_mode_t am;
882 ia32_address_t *addr = &am.addr;
883 ia32_x87_attr_t *attr;
884 /* All operations are considered commutative, because there are reverse
886 match_flags_t flags = match_commutative;
888 /* cannot use address mode with long double on x87 */
889 if (get_mode_size_bits(mode) <= 64)
892 block = get_nodes_block(node);
893 match_arguments(&am, block, op1, op2, NULL, flags);
895 dbgi = get_irn_dbg_info(node);
896 new_block = be_transform_node(block);
897 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
898 am.new_op1, am.new_op2, get_fpcw());
899 set_am_attributes(new_node, &am);
901 attr = get_ia32_x87_attr(new_node);
902 attr->attr.data.ins_permuted = am.ins_permuted;
904 SET_IA32_ORIG_NODE(new_node, node);
906 new_node = fix_mem_proj(new_node, &am);
912 * Construct a shift/rotate binary operation, sets AM and immediate if required.
914 * @param op1 The first operand
915 * @param op2 The second operand
916 * @param func The node constructor function
917 * @return The constructed ia32 node.
919 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
920 construct_shift_func *func,
924 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
926 assert(! mode_is_float(get_irn_mode(node)));
927 assert(flags & match_immediate);
928 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
930 if (flags & match_mode_neutral) {
931 op1 = ia32_skip_downconv(op1);
932 new_op1 = be_transform_node(op1);
933 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
934 new_op1 = create_upconv(op1, node);
936 new_op1 = be_transform_node(op1);
939 /* the shift amount can be any mode that is bigger than 5 bits, since all
940 * other bits are ignored anyway */
941 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
942 ir_node *const op = get_Conv_op(op2);
943 if (mode_is_float(get_irn_mode(op)))
946 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
948 new_op2 = create_immediate_or_transform(op2, 0);
950 dbgi = get_irn_dbg_info(node);
951 block = get_nodes_block(node);
952 new_block = be_transform_node(block);
953 new_node = func(dbgi, new_block, new_op1, new_op2);
954 SET_IA32_ORIG_NODE(new_node, node);
956 /* lowered shift instruction may have a dependency operand, handle it here */
957 if (get_irn_arity(node) == 3) {
958 /* we have a dependency */
959 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
960 add_irn_dep(new_node, new_dep);
968 * Construct a standard unary operation, set AM and immediate if required.
970 * @param op The operand
971 * @param func The node constructor function
972 * @return The constructed ia32 node.
974 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
978 ir_node *block, *new_block, *new_op, *new_node;
980 assert(flags == 0 || flags == match_mode_neutral);
981 if (flags & match_mode_neutral) {
982 op = ia32_skip_downconv(op);
985 new_op = be_transform_node(op);
986 dbgi = get_irn_dbg_info(node);
987 block = get_nodes_block(node);
988 new_block = be_transform_node(block);
989 new_node = func(dbgi, new_block, new_op);
991 SET_IA32_ORIG_NODE(new_node, node);
996 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
997 ia32_address_t *addr)
999 ir_node *base, *index, *res;
1003 base = ia32_new_NoReg_gp(env_cg);
1005 base = be_transform_node(base);
1008 index = addr->index;
1009 if (index == NULL) {
1010 index = ia32_new_NoReg_gp(env_cg);
1012 index = be_transform_node(index);
1015 res = new_bd_ia32_Lea(dbgi, block, base, index);
1016 set_address(res, addr);
1022 * Returns non-zero if a given address mode has a symbolic or
1023 * numerical offset != 0.
1025 static int am_has_immediates(const ia32_address_t *addr)
1027 return addr->offset != 0 || addr->symconst_ent != NULL
1028 || addr->frame_entity || addr->use_frame;
1032 * Creates an ia32 Add.
1034 * @return the created ia32 Add node
1036 static ir_node *gen_Add(ir_node *node)
1038 ir_mode *mode = get_irn_mode(node);
1039 ir_node *op1 = get_Add_left(node);
1040 ir_node *op2 = get_Add_right(node);
1042 ir_node *block, *new_block, *new_node, *add_immediate_op;
1043 ia32_address_t addr;
1044 ia32_address_mode_t am;
1046 if (mode_is_float(mode)) {
1047 if (ia32_cg_config.use_sse2)
1048 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1049 match_commutative | match_am);
1051 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1054 ia32_mark_non_am(node);
1056 op2 = ia32_skip_downconv(op2);
1057 op1 = ia32_skip_downconv(op1);
1061 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1062 * 1. Add with immediate -> Lea
1063 * 2. Add with possible source address mode -> Add
1064 * 3. Otherwise -> Lea
1066 memset(&addr, 0, sizeof(addr));
1067 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1068 add_immediate_op = NULL;
1070 dbgi = get_irn_dbg_info(node);
1071 block = get_nodes_block(node);
1072 new_block = be_transform_node(block);
1075 if (addr.base == NULL && addr.index == NULL) {
1076 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1077 addr.symconst_sign, addr.offset);
1078 be_dep_on_frame(new_node);
1079 SET_IA32_ORIG_NODE(new_node, node);
1082 /* add with immediate? */
1083 if (addr.index == NULL) {
1084 add_immediate_op = addr.base;
1085 } else if (addr.base == NULL && addr.scale == 0) {
1086 add_immediate_op = addr.index;
1089 if (add_immediate_op != NULL) {
1090 if (!am_has_immediates(&addr)) {
1091 #ifdef DEBUG_libfirm
1092 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1095 return be_transform_node(add_immediate_op);
1098 new_node = create_lea_from_address(dbgi, new_block, &addr);
1099 SET_IA32_ORIG_NODE(new_node, node);
1103 /* test if we can use source address mode */
1104 match_arguments(&am, block, op1, op2, NULL, match_commutative
1105 | match_mode_neutral | match_am | match_immediate | match_try_am);
1107 /* construct an Add with source address mode */
1108 if (am.op_type == ia32_AddrModeS) {
1109 ia32_address_t *am_addr = &am.addr;
1110 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1111 am_addr->index, am_addr->mem, am.new_op1,
1113 set_am_attributes(new_node, &am);
1114 SET_IA32_ORIG_NODE(new_node, node);
1116 new_node = fix_mem_proj(new_node, &am);
1121 /* otherwise construct a lea */
1122 new_node = create_lea_from_address(dbgi, new_block, &addr);
1123 SET_IA32_ORIG_NODE(new_node, node);
1128 * Creates an ia32 Mul.
1130 * @return the created ia32 Mul node
1132 static ir_node *gen_Mul(ir_node *node)
1134 ir_node *op1 = get_Mul_left(node);
1135 ir_node *op2 = get_Mul_right(node);
1136 ir_mode *mode = get_irn_mode(node);
1138 if (mode_is_float(mode)) {
1139 if (ia32_cg_config.use_sse2)
1140 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1141 match_commutative | match_am);
1143 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1145 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1146 match_commutative | match_am | match_mode_neutral |
1147 match_immediate | match_am_and_immediates);
1151 * Creates an ia32 Mulh.
1152 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1153 * this result while Mul returns the lower 32 bit.
1155 * @return the created ia32 Mulh node
1157 static ir_node *gen_Mulh(ir_node *node)
1159 ir_node *block = get_nodes_block(node);
1160 ir_node *new_block = be_transform_node(block);
1161 dbg_info *dbgi = get_irn_dbg_info(node);
1162 ir_node *op1 = get_Mulh_left(node);
1163 ir_node *op2 = get_Mulh_right(node);
1164 ir_mode *mode = get_irn_mode(node);
1166 ir_node *proj_res_high;
1168 if (mode_is_signed(mode)) {
1169 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1170 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1171 mode_Iu, pn_ia32_IMul1OP_res_high);
1173 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1174 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1175 mode_Iu, pn_ia32_Mul_res_high);
1177 return proj_res_high;
1181 * Creates an ia32 And.
1183 * @return The created ia32 And node
1185 static ir_node *gen_And(ir_node *node)
1187 ir_node *op1 = get_And_left(node);
1188 ir_node *op2 = get_And_right(node);
1189 assert(! mode_is_float(get_irn_mode(node)));
1191 /* is it a zero extension? */
1192 if (is_Const(op2)) {
1193 tarval *tv = get_Const_tarval(op2);
1194 long v = get_tarval_long(tv);
1196 if (v == 0xFF || v == 0xFFFF) {
1197 dbg_info *dbgi = get_irn_dbg_info(node);
1198 ir_node *block = get_nodes_block(node);
1205 assert(v == 0xFFFF);
1208 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1213 return gen_binop(node, op1, op2, new_bd_ia32_And,
1214 match_commutative | match_mode_neutral | match_am | match_immediate);
1220 * Creates an ia32 Or.
1222 * @return The created ia32 Or node
1224 static ir_node *gen_Or(ir_node *node)
1226 ir_node *op1 = get_Or_left(node);
1227 ir_node *op2 = get_Or_right(node);
1229 assert (! mode_is_float(get_irn_mode(node)));
1230 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1231 | match_mode_neutral | match_am | match_immediate);
1237 * Creates an ia32 Eor.
1239 * @return The created ia32 Eor node
1241 static ir_node *gen_Eor(ir_node *node)
1243 ir_node *op1 = get_Eor_left(node);
1244 ir_node *op2 = get_Eor_right(node);
1246 assert(! mode_is_float(get_irn_mode(node)));
1247 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1248 | match_mode_neutral | match_am | match_immediate);
1253 * Creates an ia32 Sub.
1255 * @return The created ia32 Sub node
1257 static ir_node *gen_Sub(ir_node *node)
1259 ir_node *op1 = get_Sub_left(node);
1260 ir_node *op2 = get_Sub_right(node);
1261 ir_mode *mode = get_irn_mode(node);
1263 if (mode_is_float(mode)) {
1264 if (ia32_cg_config.use_sse2)
1265 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1267 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1270 if (is_Const(op2)) {
1271 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1275 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1276 | match_am | match_immediate);
1279 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1280 ir_node *const src_val,
1281 ir_node *const src_mem,
1282 ir_node *const am_mem)
1284 if (is_NoMem(am_mem)) {
1285 return be_transform_node(src_mem);
1286 } else if (is_Proj(src_val) &&
1288 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1289 /* avoid memory loop */
1291 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1292 ir_node *const ptr_pred = get_Proj_pred(src_val);
1293 int const arity = get_Sync_n_preds(src_mem);
1298 NEW_ARR_A(ir_node*, ins, arity + 1);
1300 /* NOTE: This sometimes produces dead-code because the old sync in
1301 * src_mem might not be used anymore, we should detect this case
1302 * and kill the sync... */
1303 for (i = arity - 1; i >= 0; --i) {
1304 ir_node *const pred = get_Sync_pred(src_mem, i);
1306 /* avoid memory loop */
1307 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1310 ins[n++] = be_transform_node(pred);
1315 return new_r_Sync(irg, block, n, ins);
1319 ins[0] = be_transform_node(src_mem);
1321 return new_r_Sync(irg, block, 2, ins);
1325 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1326 ir_node *val, const ir_node *orig)
1331 if (ia32_cg_config.use_short_sex_eax) {
1332 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1333 be_dep_on_frame(pval);
1334 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1336 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1337 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1339 SET_IA32_ORIG_NODE(res, orig);
1344 * Generates an ia32 DivMod with additional infrastructure for the
1345 * register allocator if needed.
1347 static ir_node *create_Div(ir_node *node)
1349 dbg_info *dbgi = get_irn_dbg_info(node);
1350 ir_node *block = get_nodes_block(node);
1351 ir_node *new_block = be_transform_node(block);
1358 ir_node *sign_extension;
1359 ia32_address_mode_t am;
1360 ia32_address_t *addr = &am.addr;
1362 /* the upper bits have random contents for smaller modes */
1363 switch (get_irn_opcode(node)) {
1365 op1 = get_Div_left(node);
1366 op2 = get_Div_right(node);
1367 mem = get_Div_mem(node);
1368 mode = get_Div_resmode(node);
1371 op1 = get_Mod_left(node);
1372 op2 = get_Mod_right(node);
1373 mem = get_Mod_mem(node);
1374 mode = get_Mod_resmode(node);
1377 op1 = get_DivMod_left(node);
1378 op2 = get_DivMod_right(node);
1379 mem = get_DivMod_mem(node);
1380 mode = get_DivMod_resmode(node);
1383 panic("invalid divmod node %+F", node);
1386 match_arguments(&am, block, op1, op2, NULL, match_am);
1388 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1389 is the memory of the consumed address. We can have only the second op as address
1390 in Div nodes, so check only op2. */
1391 new_mem = transform_AM_mem(current_ir_graph, block, op2, mem, addr->mem);
1393 if (mode_is_signed(mode)) {
1394 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1395 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1396 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1398 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0);
1399 be_dep_on_frame(sign_extension);
1401 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1402 addr->index, new_mem, am.new_op2,
1403 am.new_op1, sign_extension);
1406 set_irn_pinned(new_node, get_irn_pinned(node));
1408 set_am_attributes(new_node, &am);
1409 SET_IA32_ORIG_NODE(new_node, node);
1411 new_node = fix_mem_proj(new_node, &am);
1417 static ir_node *gen_Mod(ir_node *node)
1419 return create_Div(node);
1422 static ir_node *gen_Div(ir_node *node)
1424 return create_Div(node);
1427 static ir_node *gen_DivMod(ir_node *node)
1429 return create_Div(node);
1435 * Creates an ia32 floating Div.
1437 * @return The created ia32 xDiv node
1439 static ir_node *gen_Quot(ir_node *node)
1441 ir_node *op1 = get_Quot_left(node);
1442 ir_node *op2 = get_Quot_right(node);
1444 if (ia32_cg_config.use_sse2) {
1445 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1447 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1453 * Creates an ia32 Shl.
1455 * @return The created ia32 Shl node
1457 static ir_node *gen_Shl(ir_node *node)
1459 ir_node *left = get_Shl_left(node);
1460 ir_node *right = get_Shl_right(node);
1462 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1463 match_mode_neutral | match_immediate);
1467 * Creates an ia32 Shr.
1469 * @return The created ia32 Shr node
1471 static ir_node *gen_Shr(ir_node *node)
1473 ir_node *left = get_Shr_left(node);
1474 ir_node *right = get_Shr_right(node);
1476 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1482 * Creates an ia32 Sar.
1484 * @return The created ia32 Shrs node
1486 static ir_node *gen_Shrs(ir_node *node)
1488 ir_node *left = get_Shrs_left(node);
1489 ir_node *right = get_Shrs_right(node);
1490 ir_mode *mode = get_irn_mode(node);
1492 if (is_Const(right) && mode == mode_Is) {
1493 tarval *tv = get_Const_tarval(right);
1494 long val = get_tarval_long(tv);
1496 /* this is a sign extension */
1497 dbg_info *dbgi = get_irn_dbg_info(node);
1498 ir_node *block = be_transform_node(get_nodes_block(node));
1499 ir_node *new_op = be_transform_node(left);
1501 return create_sex_32_64(dbgi, block, new_op, node);
1505 /* 8 or 16 bit sign extension? */
1506 if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1507 ir_node *shl_left = get_Shl_left(left);
1508 ir_node *shl_right = get_Shl_right(left);
1509 if (is_Const(shl_right)) {
1510 tarval *tv1 = get_Const_tarval(right);
1511 tarval *tv2 = get_Const_tarval(shl_right);
1512 if (tv1 == tv2 && tarval_is_long(tv1)) {
1513 long val = get_tarval_long(tv1);
1514 if (val == 16 || val == 24) {
1515 dbg_info *dbgi = get_irn_dbg_info(node);
1516 ir_node *block = get_nodes_block(node);
1526 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1535 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1541 * Creates an ia32 Rol.
1543 * @param op1 The first operator
1544 * @param op2 The second operator
1545 * @return The created ia32 RotL node
1547 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1549 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1555 * Creates an ia32 Ror.
1556 * NOTE: There is no RotR with immediate because this would always be a RotL
1557 * "imm-mode_size_bits" which can be pre-calculated.
1559 * @param op1 The first operator
1560 * @param op2 The second operator
1561 * @return The created ia32 RotR node
1563 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1565 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1571 * Creates an ia32 RotR or RotL (depending on the found pattern).
1573 * @return The created ia32 RotL or RotR node
1575 static ir_node *gen_Rotl(ir_node *node)
1577 ir_node *rotate = NULL;
1578 ir_node *op1 = get_Rotl_left(node);
1579 ir_node *op2 = get_Rotl_right(node);
1581 /* Firm has only RotL, so we are looking for a right (op2)
1582 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1583 that means we can create a RotR instead of an Add and a RotL */
1587 ir_node *left = get_Add_left(add);
1588 ir_node *right = get_Add_right(add);
1589 if (is_Const(right)) {
1590 tarval *tv = get_Const_tarval(right);
1591 ir_mode *mode = get_irn_mode(node);
1592 long bits = get_mode_size_bits(mode);
1594 if (is_Minus(left) &&
1595 tarval_is_long(tv) &&
1596 get_tarval_long(tv) == bits &&
1599 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1600 rotate = gen_Ror(node, op1, get_Minus_op(left));
1605 if (rotate == NULL) {
1606 rotate = gen_Rol(node, op1, op2);
1615 * Transforms a Minus node.
1617 * @return The created ia32 Minus node
1619 static ir_node *gen_Minus(ir_node *node)
1621 ir_node *op = get_Minus_op(node);
1622 ir_node *block = be_transform_node(get_nodes_block(node));
1623 dbg_info *dbgi = get_irn_dbg_info(node);
1624 ir_mode *mode = get_irn_mode(node);
1629 if (mode_is_float(mode)) {
1630 ir_node *new_op = be_transform_node(op);
1631 if (ia32_cg_config.use_sse2) {
1632 /* TODO: non-optimal... if we have many xXors, then we should
1633 * rather create a load for the const and use that instead of
1634 * several AM nodes... */
1635 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1636 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1637 ir_node *nomem = new_NoMem();
1639 new_node = new_bd_ia32_xXor(dbgi, block, noreg_gp, noreg_gp,
1640 nomem, new_op, noreg_xmm);
1642 size = get_mode_size_bits(mode);
1643 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1645 set_ia32_am_sc(new_node, ent);
1646 set_ia32_op_type(new_node, ia32_AddrModeS);
1647 set_ia32_ls_mode(new_node, mode);
1649 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1652 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1655 SET_IA32_ORIG_NODE(new_node, node);
1661 * Transforms a Not node.
1663 * @return The created ia32 Not node
1665 static ir_node *gen_Not(ir_node *node)
1667 ir_node *op = get_Not_op(node);
1669 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1670 assert (! mode_is_float(get_irn_mode(node)));
1672 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1678 * Transforms an Abs node.
1680 * @return The created ia32 Abs node
1682 static ir_node *gen_Abs(ir_node *node)
1684 ir_node *block = get_nodes_block(node);
1685 ir_node *new_block = be_transform_node(block);
1686 ir_node *op = get_Abs_op(node);
1687 dbg_info *dbgi = get_irn_dbg_info(node);
1688 ir_mode *mode = get_irn_mode(node);
1689 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1690 ir_node *nomem = new_NoMem();
1696 if (mode_is_float(mode)) {
1697 new_op = be_transform_node(op);
1699 if (ia32_cg_config.use_sse2) {
1700 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1701 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_gp, noreg_gp,
1702 nomem, new_op, noreg_fp);
1704 size = get_mode_size_bits(mode);
1705 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1707 set_ia32_am_sc(new_node, ent);
1709 SET_IA32_ORIG_NODE(new_node, node);
1711 set_ia32_op_type(new_node, ia32_AddrModeS);
1712 set_ia32_ls_mode(new_node, mode);
1714 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1715 SET_IA32_ORIG_NODE(new_node, node);
1718 ir_node *xor, *sign_extension;
1720 if (get_mode_size_bits(mode) == 32) {
1721 new_op = be_transform_node(op);
1723 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1726 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1728 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_gp, noreg_gp,
1729 nomem, new_op, sign_extension);
1730 SET_IA32_ORIG_NODE(xor, node);
1732 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_gp, noreg_gp,
1733 nomem, xor, sign_extension);
1734 SET_IA32_ORIG_NODE(new_node, node);
1741 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1743 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1745 dbg_info *dbgi = get_irn_dbg_info(cmp);
1746 ir_node *block = get_nodes_block(cmp);
1747 ir_node *new_block = be_transform_node(block);
1748 ir_node *op1 = be_transform_node(x);
1749 ir_node *op2 = be_transform_node(n);
1751 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1755 * Transform a node returning a "flag" result.
1757 * @param node the node to transform
1758 * @param pnc_out the compare mode to use
1760 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1769 /* we have a Cmp as input */
1770 if (is_Proj(node)) {
1771 ir_node *pred = get_Proj_pred(node);
1773 pn_Cmp pnc = get_Proj_proj(node);
1774 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1775 ir_node *l = get_Cmp_left(pred);
1776 ir_node *r = get_Cmp_right(pred);
1778 ir_node *la = get_And_left(l);
1779 ir_node *ra = get_And_right(l);
1781 ir_node *c = get_Shl_left(la);
1782 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1783 /* (1 << n) & ra) */
1784 ir_node *n = get_Shl_right(la);
1785 flags = gen_bt(pred, ra, n);
1786 /* we must generate a Jc/Jnc jump */
1787 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1790 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1795 ir_node *c = get_Shl_left(ra);
1796 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1797 /* la & (1 << n)) */
1798 ir_node *n = get_Shl_right(ra);
1799 flags = gen_bt(pred, la, n);
1800 /* we must generate a Jc/Jnc jump */
1801 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1804 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1810 flags = be_transform_node(pred);
1816 /* a mode_b value, we have to compare it against 0 */
1817 dbgi = get_irn_dbg_info(node);
1818 new_block = be_transform_node(get_nodes_block(node));
1819 new_op = be_transform_node(node);
1820 noreg = ia32_new_NoReg_gp(env_cg);
1821 nomem = new_NoMem();
1822 flags = new_bd_ia32_Test(dbgi, new_block, noreg, noreg, nomem, new_op,
1823 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1824 *pnc_out = pn_Cmp_Lg;
1829 * Transforms a Load.
1831 * @return the created ia32 Load node
1833 static ir_node *gen_Load(ir_node *node)
1835 ir_node *old_block = get_nodes_block(node);
1836 ir_node *block = be_transform_node(old_block);
1837 ir_node *ptr = get_Load_ptr(node);
1838 ir_node *mem = get_Load_mem(node);
1839 ir_node *new_mem = be_transform_node(mem);
1842 dbg_info *dbgi = get_irn_dbg_info(node);
1843 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1844 ir_mode *mode = get_Load_mode(node);
1847 ia32_address_t addr;
1849 /* construct load address */
1850 memset(&addr, 0, sizeof(addr));
1851 ia32_create_address_mode(&addr, ptr, 0);
1858 base = be_transform_node(base);
1861 if (index == NULL) {
1864 index = be_transform_node(index);
1867 if (mode_is_float(mode)) {
1868 if (ia32_cg_config.use_sse2) {
1869 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1871 res_mode = mode_xmm;
1873 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1875 res_mode = mode_vfp;
1878 assert(mode != mode_b);
1880 /* create a conv node with address mode for smaller modes */
1881 if (get_mode_size_bits(mode) < 32) {
1882 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1883 new_mem, noreg, mode);
1885 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1890 set_irn_pinned(new_node, get_irn_pinned(node));
1891 set_ia32_op_type(new_node, ia32_AddrModeS);
1892 set_ia32_ls_mode(new_node, mode);
1893 set_address(new_node, &addr);
1895 if (get_irn_pinned(node) == op_pin_state_floats) {
1896 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1897 && pn_ia32_vfld_res == pn_ia32_Load_res
1898 && pn_ia32_Load_res == pn_ia32_res);
1899 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1902 SET_IA32_ORIG_NODE(new_node, node);
1904 be_dep_on_frame(new_node);
1908 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1909 ir_node *ptr, ir_node *other)
1916 /* we only use address mode if we're the only user of the load */
1917 if (get_irn_n_edges(node) > 1)
1920 load = get_Proj_pred(node);
1923 if (get_nodes_block(load) != block)
1926 /* store should have the same pointer as the load */
1927 if (get_Load_ptr(load) != ptr)
1930 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1931 if (other != NULL &&
1932 get_nodes_block(other) == block &&
1933 heights_reachable_in_block(heights, other, load)) {
1937 if (prevents_AM(block, load, mem))
1939 /* Store should be attached to the load via mem */
1940 assert(heights_reachable_in_block(heights, mem, load));
1945 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1946 ir_node *mem, ir_node *ptr, ir_mode *mode,
1947 construct_binop_dest_func *func,
1948 construct_binop_dest_func *func8bit,
1949 match_flags_t flags)
1951 ir_node *src_block = get_nodes_block(node);
1953 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1960 ia32_address_mode_t am;
1961 ia32_address_t *addr = &am.addr;
1962 memset(&am, 0, sizeof(am));
1964 assert(flags & match_immediate); /* there is no destam node without... */
1965 commutative = (flags & match_commutative) != 0;
1967 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1968 build_address(&am, op1, ia32_create_am_double_use);
1969 new_op = create_immediate_or_transform(op2, 0);
1970 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1971 build_address(&am, op2, ia32_create_am_double_use);
1972 new_op = create_immediate_or_transform(op1, 0);
1977 if (addr->base == NULL)
1978 addr->base = noreg_gp;
1979 if (addr->index == NULL)
1980 addr->index = noreg_gp;
1981 if (addr->mem == NULL)
1982 addr->mem = new_NoMem();
1984 dbgi = get_irn_dbg_info(node);
1985 block = be_transform_node(src_block);
1986 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
1988 if (get_mode_size_bits(mode) == 8) {
1989 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
1991 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
1993 set_address(new_node, addr);
1994 set_ia32_op_type(new_node, ia32_AddrModeD);
1995 set_ia32_ls_mode(new_node, mode);
1996 SET_IA32_ORIG_NODE(new_node, node);
1998 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
1999 mem_proj = be_transform_node(am.mem_proj);
2000 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2005 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2006 ir_node *ptr, ir_mode *mode,
2007 construct_unop_dest_func *func)
2009 ir_node *src_block = get_nodes_block(node);
2015 ia32_address_mode_t am;
2016 ia32_address_t *addr = &am.addr;
2018 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2021 memset(&am, 0, sizeof(am));
2022 build_address(&am, op, ia32_create_am_double_use);
2024 dbgi = get_irn_dbg_info(node);
2025 block = be_transform_node(src_block);
2026 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2027 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2028 set_address(new_node, addr);
2029 set_ia32_op_type(new_node, ia32_AddrModeD);
2030 set_ia32_ls_mode(new_node, mode);
2031 SET_IA32_ORIG_NODE(new_node, node);
2033 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2034 mem_proj = be_transform_node(am.mem_proj);
2035 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2040 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2042 ir_mode *mode = get_irn_mode(node);
2043 ir_node *mux_true = get_Mux_true(node);
2044 ir_node *mux_false = get_Mux_false(node);
2054 ia32_address_t addr;
2056 if (get_mode_size_bits(mode) != 8)
2059 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2061 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2067 build_address_ptr(&addr, ptr, mem);
2069 dbgi = get_irn_dbg_info(node);
2070 block = get_nodes_block(node);
2071 new_block = be_transform_node(block);
2072 cond = get_Mux_sel(node);
2073 flags = get_flags_node(cond, &pnc);
2074 new_mem = be_transform_node(mem);
2075 new_node = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2076 addr.index, addr.mem, flags, pnc, negated);
2077 set_address(new_node, &addr);
2078 set_ia32_op_type(new_node, ia32_AddrModeD);
2079 set_ia32_ls_mode(new_node, mode);
2080 SET_IA32_ORIG_NODE(new_node, node);
2085 static ir_node *try_create_dest_am(ir_node *node)
2087 ir_node *val = get_Store_value(node);
2088 ir_node *mem = get_Store_mem(node);
2089 ir_node *ptr = get_Store_ptr(node);
2090 ir_mode *mode = get_irn_mode(val);
2091 unsigned bits = get_mode_size_bits(mode);
2096 /* handle only GP modes for now... */
2097 if (!ia32_mode_needs_gp_reg(mode))
2101 /* store must be the only user of the val node */
2102 if (get_irn_n_edges(val) > 1)
2104 /* skip pointless convs */
2106 ir_node *conv_op = get_Conv_op(val);
2107 ir_mode *pred_mode = get_irn_mode(conv_op);
2108 if (!ia32_mode_needs_gp_reg(pred_mode))
2110 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2118 /* value must be in the same block */
2119 if (get_nodes_block(node) != get_nodes_block(val))
2122 switch (get_irn_opcode(val)) {
2124 op1 = get_Add_left(val);
2125 op2 = get_Add_right(val);
2126 if (ia32_cg_config.use_incdec) {
2127 if (is_Const_1(op2)) {
2128 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2130 } else if (is_Const_Minus_1(op2)) {
2131 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2135 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2136 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2137 match_commutative | match_immediate);
2140 op1 = get_Sub_left(val);
2141 op2 = get_Sub_right(val);
2142 if (is_Const(op2)) {
2143 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2145 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2146 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2150 op1 = get_And_left(val);
2151 op2 = get_And_right(val);
2152 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2153 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2154 match_commutative | match_immediate);
2157 op1 = get_Or_left(val);
2158 op2 = get_Or_right(val);
2159 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2160 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2161 match_commutative | match_immediate);
2164 op1 = get_Eor_left(val);
2165 op2 = get_Eor_right(val);
2166 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2167 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2168 match_commutative | match_immediate);
2171 op1 = get_Shl_left(val);
2172 op2 = get_Shl_right(val);
2173 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2174 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2178 op1 = get_Shr_left(val);
2179 op2 = get_Shr_right(val);
2180 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2181 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2185 op1 = get_Shrs_left(val);
2186 op2 = get_Shrs_right(val);
2187 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2188 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2192 op1 = get_Rotl_left(val);
2193 op2 = get_Rotl_right(val);
2194 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2195 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2198 /* TODO: match ROR patterns... */
2200 new_node = try_create_SetMem(val, ptr, mem);
2203 op1 = get_Minus_op(val);
2204 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2207 /* should be lowered already */
2208 assert(mode != mode_b);
2209 op1 = get_Not_op(val);
2210 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2216 if (new_node != NULL) {
2217 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2218 get_irn_pinned(node) == op_pin_state_pinned) {
2219 set_irn_pinned(new_node, op_pin_state_pinned);
2226 static bool possible_int_mode_for_fp(ir_mode *mode)
2230 if (!mode_is_signed(mode))
2232 size = get_mode_size_bits(mode);
2233 if (size != 16 && size != 32)
2238 static int is_float_to_int_conv(const ir_node *node)
2240 ir_mode *mode = get_irn_mode(node);
2244 if (!possible_int_mode_for_fp(mode))
2249 conv_op = get_Conv_op(node);
2250 conv_mode = get_irn_mode(conv_op);
2252 if (!mode_is_float(conv_mode))
2259 * Transform a Store(floatConst) into a sequence of
2262 * @return the created ia32 Store node
2264 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2266 ir_mode *mode = get_irn_mode(cns);
2267 unsigned size = get_mode_size_bytes(mode);
2268 tarval *tv = get_Const_tarval(cns);
2269 ir_node *block = get_nodes_block(node);
2270 ir_node *new_block = be_transform_node(block);
2271 ir_node *ptr = get_Store_ptr(node);
2272 ir_node *mem = get_Store_mem(node);
2273 dbg_info *dbgi = get_irn_dbg_info(node);
2277 ia32_address_t addr;
2279 assert(size % 4 == 0);
2282 build_address_ptr(&addr, ptr, mem);
2286 get_tarval_sub_bits(tv, ofs) |
2287 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2288 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2289 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2290 ir_node *imm = create_Immediate(NULL, 0, val);
2292 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2293 addr.index, addr.mem, imm);
2295 set_irn_pinned(new_node, get_irn_pinned(node));
2296 set_ia32_op_type(new_node, ia32_AddrModeD);
2297 set_ia32_ls_mode(new_node, mode_Iu);
2298 set_address(new_node, &addr);
2299 SET_IA32_ORIG_NODE(new_node, node);
2302 ins[i++] = new_node;
2307 } while (size != 0);
2310 return new_rd_Sync(dbgi, current_ir_graph, new_block, i, ins);
2317 * Generate a vfist or vfisttp instruction.
2319 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2320 ir_node *mem, ir_node *val, ir_node **fist)
2324 if (ia32_cg_config.use_fisttp) {
2325 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2326 if other users exists */
2327 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2328 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2329 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2330 be_new_Keep(reg_class, irg, block, 1, &value);
2332 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2335 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2338 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2344 * Transforms a general (no special case) Store.
2346 * @return the created ia32 Store node
2348 static ir_node *gen_general_Store(ir_node *node)
2350 ir_node *val = get_Store_value(node);
2351 ir_mode *mode = get_irn_mode(val);
2352 ir_node *block = get_nodes_block(node);
2353 ir_node *new_block = be_transform_node(block);
2354 ir_node *ptr = get_Store_ptr(node);
2355 ir_node *mem = get_Store_mem(node);
2356 dbg_info *dbgi = get_irn_dbg_info(node);
2357 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2358 ir_node *new_val, *new_node, *store;
2359 ia32_address_t addr;
2361 /* check for destination address mode */
2362 new_node = try_create_dest_am(node);
2363 if (new_node != NULL)
2366 /* construct store address */
2367 memset(&addr, 0, sizeof(addr));
2368 ia32_create_address_mode(&addr, ptr, 0);
2370 if (addr.base == NULL) {
2373 addr.base = be_transform_node(addr.base);
2376 if (addr.index == NULL) {
2379 addr.index = be_transform_node(addr.index);
2381 addr.mem = be_transform_node(mem);
2383 if (mode_is_float(mode)) {
2384 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2386 while (is_Conv(val) && mode == get_irn_mode(val)) {
2387 ir_node *op = get_Conv_op(val);
2388 if (!mode_is_float(get_irn_mode(op)))
2392 new_val = be_transform_node(val);
2393 if (ia32_cg_config.use_sse2) {
2394 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2395 addr.index, addr.mem, new_val);
2397 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2398 addr.index, addr.mem, new_val, mode);
2401 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2402 val = get_Conv_op(val);
2404 /* TODO: is this optimisation still necessary at all (middleend)? */
2405 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2406 while (is_Conv(val)) {
2407 ir_node *op = get_Conv_op(val);
2408 if (!mode_is_float(get_irn_mode(op)))
2410 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2414 new_val = be_transform_node(val);
2415 new_node = gen_vfist(dbgi, current_ir_graph, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2417 new_val = create_immediate_or_transform(val, 0);
2418 assert(mode != mode_b);
2420 if (get_mode_size_bits(mode) == 8) {
2421 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2422 addr.index, addr.mem, new_val);
2424 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2425 addr.index, addr.mem, new_val);
2430 set_irn_pinned(store, get_irn_pinned(node));
2431 set_ia32_op_type(store, ia32_AddrModeD);
2432 set_ia32_ls_mode(store, mode);
2434 set_address(store, &addr);
2435 SET_IA32_ORIG_NODE(store, node);
2441 * Transforms a Store.
2443 * @return the created ia32 Store node
2445 static ir_node *gen_Store(ir_node *node)
2447 ir_node *val = get_Store_value(node);
2448 ir_mode *mode = get_irn_mode(val);
2450 if (mode_is_float(mode) && is_Const(val)) {
2451 /* We can transform every floating const store
2452 into a sequence of integer stores.
2453 If the constant is already in a register,
2454 it would be better to use it, but we don't
2455 have this information here. */
2456 return gen_float_const_Store(node, val);
2458 return gen_general_Store(node);
2462 * Transforms a Switch.
2464 * @return the created ia32 SwitchJmp node
2466 static ir_node *create_Switch(ir_node *node)
2468 dbg_info *dbgi = get_irn_dbg_info(node);
2469 ir_node *block = be_transform_node(get_nodes_block(node));
2470 ir_node *sel = get_Cond_selector(node);
2471 ir_node *new_sel = be_transform_node(sel);
2472 int switch_min = INT_MAX;
2473 int switch_max = INT_MIN;
2474 long default_pn = get_Cond_defaultProj(node);
2476 const ir_edge_t *edge;
2478 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2480 /* determine the smallest switch case value */
2481 foreach_out_edge(node, edge) {
2482 ir_node *proj = get_edge_src_irn(edge);
2483 long pn = get_Proj_proj(proj);
2484 if (pn == default_pn)
2487 if (pn < switch_min)
2489 if (pn > switch_max)
2493 if ((unsigned) (switch_max - switch_min) > 256000) {
2494 panic("Size of switch %+F bigger than 256000", node);
2497 if (switch_min != 0) {
2498 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2500 /* if smallest switch case is not 0 we need an additional sub */
2501 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg);
2502 add_ia32_am_offs_int(new_sel, -switch_min);
2503 set_ia32_op_type(new_sel, ia32_AddrModeS);
2505 SET_IA32_ORIG_NODE(new_sel, node);
2508 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2509 SET_IA32_ORIG_NODE(new_node, node);
2515 * Transform a Cond node.
2517 static ir_node *gen_Cond(ir_node *node)
2519 ir_node *block = get_nodes_block(node);
2520 ir_node *new_block = be_transform_node(block);
2521 dbg_info *dbgi = get_irn_dbg_info(node);
2522 ir_node *sel = get_Cond_selector(node);
2523 ir_mode *sel_mode = get_irn_mode(sel);
2524 ir_node *flags = NULL;
2528 if (sel_mode != mode_b) {
2529 return create_Switch(node);
2532 /* we get flags from a Cmp */
2533 flags = get_flags_node(sel, &pnc);
2535 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2536 SET_IA32_ORIG_NODE(new_node, node);
2541 static ir_node *gen_be_Copy(ir_node *node)
2543 ir_node *new_node = be_duplicate_node(node);
2544 ir_mode *mode = get_irn_mode(new_node);
2546 if (ia32_mode_needs_gp_reg(mode)) {
2547 set_irn_mode(new_node, mode_Iu);
2553 static ir_node *create_Fucom(ir_node *node)
2555 dbg_info *dbgi = get_irn_dbg_info(node);
2556 ir_node *block = get_nodes_block(node);
2557 ir_node *new_block = be_transform_node(block);
2558 ir_node *left = get_Cmp_left(node);
2559 ir_node *new_left = be_transform_node(left);
2560 ir_node *right = get_Cmp_right(node);
2564 if (ia32_cg_config.use_fucomi) {
2565 new_right = be_transform_node(right);
2566 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2568 set_ia32_commutative(new_node);
2569 SET_IA32_ORIG_NODE(new_node, node);
2571 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2572 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2574 new_right = be_transform_node(right);
2575 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2578 set_ia32_commutative(new_node);
2580 SET_IA32_ORIG_NODE(new_node, node);
2582 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2583 SET_IA32_ORIG_NODE(new_node, node);
2589 static ir_node *create_Ucomi(ir_node *node)
2591 dbg_info *dbgi = get_irn_dbg_info(node);
2592 ir_node *src_block = get_nodes_block(node);
2593 ir_node *new_block = be_transform_node(src_block);
2594 ir_node *left = get_Cmp_left(node);
2595 ir_node *right = get_Cmp_right(node);
2597 ia32_address_mode_t am;
2598 ia32_address_t *addr = &am.addr;
2600 match_arguments(&am, src_block, left, right, NULL,
2601 match_commutative | match_am);
2603 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2604 addr->mem, am.new_op1, am.new_op2,
2606 set_am_attributes(new_node, &am);
2608 SET_IA32_ORIG_NODE(new_node, node);
2610 new_node = fix_mem_proj(new_node, &am);
2616 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2617 * to fold an and into a test node
2619 static bool can_fold_test_and(ir_node *node)
2621 const ir_edge_t *edge;
2623 /** we can only have eq and lg projs */
2624 foreach_out_edge(node, edge) {
2625 ir_node *proj = get_edge_src_irn(edge);
2626 pn_Cmp pnc = get_Proj_proj(proj);
2627 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2635 * returns true if it is assured, that the upper bits of a node are "clean"
2636 * which means for a 16 or 8 bit value, that the upper bits in the register
2637 * are 0 for unsigned and a copy of the last significant bit for signed
2640 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2642 assert(ia32_mode_needs_gp_reg(mode));
2643 if (get_mode_size_bits(mode) >= 32)
2646 if (is_Proj(transformed_node))
2647 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2649 switch (get_ia32_irn_opcode(transformed_node)) {
2650 case iro_ia32_Conv_I2I:
2651 case iro_ia32_Conv_I2I8Bit: {
2652 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2653 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2655 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2662 if (mode_is_signed(mode)) {
2663 return false; /* TODO handle signed modes */
2665 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2666 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2667 const ia32_immediate_attr_t *attr
2668 = get_ia32_immediate_attr_const(right);
2669 if (attr->symconst == 0 &&
2670 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2674 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2678 /* TODO too conservative if shift amount is constant */
2679 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2682 if (!mode_is_signed(mode)) {
2684 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2685 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2687 /* TODO if one is known to be zero extended, then || is sufficient */
2692 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2693 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2695 case iro_ia32_Const:
2696 case iro_ia32_Immediate: {
2697 const ia32_immediate_attr_t *attr =
2698 get_ia32_immediate_attr_const(transformed_node);
2699 if (mode_is_signed(mode)) {
2700 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2701 return shifted == 0 || shifted == -1;
2703 unsigned long shifted = (unsigned long)attr->offset;
2704 shifted >>= get_mode_size_bits(mode);
2705 return shifted == 0;
2715 * Generate code for a Cmp.
2717 static ir_node *gen_Cmp(ir_node *node)
2719 dbg_info *dbgi = get_irn_dbg_info(node);
2720 ir_node *block = get_nodes_block(node);
2721 ir_node *new_block = be_transform_node(block);
2722 ir_node *left = get_Cmp_left(node);
2723 ir_node *right = get_Cmp_right(node);
2724 ir_mode *cmp_mode = get_irn_mode(left);
2726 ia32_address_mode_t am;
2727 ia32_address_t *addr = &am.addr;
2730 if (mode_is_float(cmp_mode)) {
2731 if (ia32_cg_config.use_sse2) {
2732 return create_Ucomi(node);
2734 return create_Fucom(node);
2738 assert(ia32_mode_needs_gp_reg(cmp_mode));
2740 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2741 cmp_unsigned = !mode_is_signed(cmp_mode);
2742 if (is_Const_0(right) &&
2744 get_irn_n_edges(left) == 1 &&
2745 can_fold_test_and(node)) {
2746 /* Test(and_left, and_right) */
2747 ir_node *and_left = get_And_left(left);
2748 ir_node *and_right = get_And_right(left);
2750 /* matze: code here used mode instead of cmd_mode, I think it is always
2751 * the same as cmp_mode, but I leave this here to see if this is really
2754 assert(get_irn_mode(and_left) == cmp_mode);
2756 match_arguments(&am, block, and_left, and_right, NULL,
2758 match_am | match_8bit_am | match_16bit_am |
2759 match_am_and_immediates | match_immediate);
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 |
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 ia32_address_mode_t am;
2817 ia32_address_t *addr;
2819 assert(ia32_cg_config.use_cmov);
2820 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2824 match_arguments(&am, block, val_false, val_true, flags,
2825 match_commutative | match_am | match_16bit_am | match_mode_neutral);
2827 new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2828 addr->mem, am.new_op1, am.new_op2, new_flags,
2829 am.ins_permuted, pnc);
2830 set_am_attributes(new_node, &am);
2832 SET_IA32_ORIG_NODE(new_node, node);
2834 new_node = fix_mem_proj(new_node, &am);
2840 * Creates a ia32 Setcc instruction.
2842 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2843 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2846 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2847 ir_node *nomem = new_NoMem();
2848 ir_mode *mode = get_irn_mode(orig_node);
2851 new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2852 SET_IA32_ORIG_NODE(new_node, orig_node);
2854 /* we might need to conv the result up */
2855 if (get_mode_size_bits(mode) > 8) {
2856 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg, noreg,
2857 nomem, new_node, mode_Bu);
2858 SET_IA32_ORIG_NODE(new_node, orig_node);
2865 * Create instruction for an unsigned Difference or Zero.
2867 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2869 ir_graph *irg = current_ir_graph;
2870 ir_mode *mode = get_irn_mode(psi);
2871 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2874 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2875 match_mode_neutral | match_am | match_immediate | match_two_users);
2877 block = get_nodes_block(new_node);
2879 if (is_Proj(new_node)) {
2880 sub = get_Proj_pred(new_node);
2881 assert(is_ia32_Sub(sub));
2884 set_irn_mode(sub, mode_T);
2885 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2887 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2889 dbgi = get_irn_dbg_info(psi);
2890 noreg = ia32_new_NoReg_gp(env_cg);
2891 tmpreg = new_bd_ia32_ProduceVal(dbgi, block);
2892 nomem = new_NoMem();
2893 sbb = new_bd_ia32_Sbb(dbgi, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2895 new_node = new_bd_ia32_And(dbgi, block, noreg, noreg, nomem, new_node, sbb);
2896 set_ia32_commutative(new_node);
2901 * Transforms a Mux node into CMov.
2903 * @return The transformed node.
2905 static ir_node *gen_Mux(ir_node *node)
2907 dbg_info *dbgi = get_irn_dbg_info(node);
2908 ir_node *block = get_nodes_block(node);
2909 ir_node *new_block = be_transform_node(block);
2910 ir_node *mux_true = get_Mux_true(node);
2911 ir_node *mux_false = get_Mux_false(node);
2912 ir_node *cond = get_Mux_sel(node);
2913 ir_mode *mode = get_irn_mode(node);
2916 assert(get_irn_mode(cond) == mode_b);
2918 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2919 if (mode_is_float(mode)) {
2920 ir_node *cmp = get_Proj_pred(cond);
2921 ir_node *cmp_left = get_Cmp_left(cmp);
2922 ir_node *cmp_right = get_Cmp_right(cmp);
2923 pn_Cmp pnc = get_Proj_proj(cond);
2925 if (ia32_cg_config.use_sse2) {
2926 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2927 if (cmp_left == mux_true && cmp_right == mux_false) {
2928 /* Mux(a <= b, a, b) => MIN */
2929 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2930 match_commutative | match_am | match_two_users);
2931 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2932 /* Mux(a <= b, b, a) => MAX */
2933 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2934 match_commutative | match_am | match_two_users);
2936 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2937 if (cmp_left == mux_true && cmp_right == mux_false) {
2938 /* Mux(a >= b, a, b) => MAX */
2939 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2940 match_commutative | match_am | match_two_users);
2941 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2942 /* Mux(a >= b, b, a) => MIN */
2943 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2944 match_commutative | match_am | match_two_users);
2948 panic("cannot transform floating point Mux");
2954 assert(ia32_mode_needs_gp_reg(mode));
2956 if (is_Proj(cond)) {
2957 ir_node *cmp = get_Proj_pred(cond);
2959 ir_node *cmp_left = get_Cmp_left(cmp);
2960 ir_node *cmp_right = get_Cmp_right(cmp);
2961 pn_Cmp pnc = get_Proj_proj(cond);
2963 /* check for unsigned Doz first */
2964 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2965 is_Const_0(mux_false) && is_Sub(mux_true) &&
2966 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2967 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2968 return create_Doz(node, cmp_left, cmp_right);
2969 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2970 is_Const_0(mux_true) && is_Sub(mux_false) &&
2971 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2972 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2973 return create_Doz(node, cmp_left, cmp_right);
2978 flags = get_flags_node(cond, &pnc);
2980 if (is_Const(mux_true) && is_Const(mux_false)) {
2981 /* both are const, good */
2982 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2983 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2984 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2985 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2987 /* Not that simple. */
2992 new_node = create_CMov(node, cond, flags, pnc);
3000 * Create a conversion from x87 state register to general purpose.
3002 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3004 ir_node *block = be_transform_node(get_nodes_block(node));
3005 ir_node *op = get_Conv_op(node);
3006 ir_node *new_op = be_transform_node(op);
3007 ia32_code_gen_t *cg = env_cg;
3008 ir_graph *irg = current_ir_graph;
3009 dbg_info *dbgi = get_irn_dbg_info(node);
3010 ir_node *noreg = ia32_new_NoReg_gp(cg);
3011 ir_mode *mode = get_irn_mode(node);
3012 ir_node *fist, *load, *mem;
3014 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3015 set_irn_pinned(fist, op_pin_state_floats);
3016 set_ia32_use_frame(fist);
3017 set_ia32_op_type(fist, ia32_AddrModeD);
3019 assert(get_mode_size_bits(mode) <= 32);
3020 /* exception we can only store signed 32 bit integers, so for unsigned
3021 we store a 64bit (signed) integer and load the lower bits */
3022 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3023 set_ia32_ls_mode(fist, mode_Ls);
3025 set_ia32_ls_mode(fist, mode_Is);
3027 SET_IA32_ORIG_NODE(fist, node);
3030 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg, mem);
3032 set_irn_pinned(load, op_pin_state_floats);
3033 set_ia32_use_frame(load);
3034 set_ia32_op_type(load, ia32_AddrModeS);
3035 set_ia32_ls_mode(load, mode_Is);
3036 if (get_ia32_ls_mode(fist) == mode_Ls) {
3037 ia32_attr_t *attr = get_ia32_attr(load);
3038 attr->data.need_64bit_stackent = 1;
3040 ia32_attr_t *attr = get_ia32_attr(load);
3041 attr->data.need_32bit_stackent = 1;
3043 SET_IA32_ORIG_NODE(load, node);
3045 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3049 * Creates a x87 strict Conv by placing a Store and a Load
3051 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3053 ir_node *block = get_nodes_block(node);
3054 ir_graph *irg = current_ir_graph;
3055 dbg_info *dbgi = get_irn_dbg_info(node);
3056 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3057 ir_node *nomem = new_NoMem();
3058 ir_node *frame = get_irg_frame(irg);
3059 ir_node *store, *load;
3062 store = new_bd_ia32_vfst(dbgi, block, frame, noreg, nomem, node, tgt_mode);
3063 set_ia32_use_frame(store);
3064 set_ia32_op_type(store, ia32_AddrModeD);
3065 SET_IA32_ORIG_NODE(store, node);
3067 load = new_bd_ia32_vfld(dbgi, block, frame, noreg, store, tgt_mode);
3068 set_ia32_use_frame(load);
3069 set_ia32_op_type(load, ia32_AddrModeS);
3070 SET_IA32_ORIG_NODE(load, node);
3072 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3076 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3077 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3079 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3081 func = get_mode_size_bits(mode) == 8 ?
3082 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3083 return func(dbgi, block, base, index, mem, val, mode);
3087 * Create a conversion from general purpose to x87 register
3089 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3091 ir_node *src_block = get_nodes_block(node);
3092 ir_node *block = be_transform_node(src_block);
3093 ir_graph *irg = current_ir_graph;
3094 dbg_info *dbgi = get_irn_dbg_info(node);
3095 ir_node *op = get_Conv_op(node);
3096 ir_node *new_op = NULL;
3100 ir_mode *store_mode;
3105 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3106 if (possible_int_mode_for_fp(src_mode)) {
3107 ia32_address_mode_t am;
3109 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3110 if (am.op_type == ia32_AddrModeS) {
3111 ia32_address_t *addr = &am.addr;
3113 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index,
3115 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3118 set_am_attributes(fild, &am);
3119 SET_IA32_ORIG_NODE(fild, node);
3121 fix_mem_proj(fild, &am);
3126 if (new_op == NULL) {
3127 new_op = be_transform_node(op);
3130 noreg = ia32_new_NoReg_gp(env_cg);
3131 nomem = new_NoMem();
3132 mode = get_irn_mode(op);
3134 /* first convert to 32 bit signed if necessary */
3135 if (get_mode_size_bits(src_mode) < 32) {
3136 if (!upper_bits_clean(new_op, src_mode)) {
3137 new_op = create_Conv_I2I(dbgi, block, noreg, noreg, nomem, new_op, src_mode);
3138 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 ir_node *new_block = be_transform_node(block);
3197 ir_mode *smaller_mode;
3198 ia32_address_mode_t am;
3199 ia32_address_t *addr = &am.addr;
3202 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3203 smaller_mode = src_mode;
3205 smaller_mode = tgt_mode;
3208 #ifdef DEBUG_libfirm
3210 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3215 match_arguments(&am, block, NULL, op, NULL,
3216 match_am | match_8bit_am | match_16bit_am);
3218 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3219 /* unnecessary conv. in theory it shouldn't have been AM */
3220 assert(is_ia32_NoReg_GP(addr->base));
3221 assert(is_ia32_NoReg_GP(addr->index));
3222 assert(is_NoMem(addr->mem));
3223 assert(am.addr.offset == 0);
3224 assert(am.addr.symconst_ent == NULL);
3228 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3229 addr->mem, am.new_op2, smaller_mode);
3230 set_am_attributes(new_node, &am);
3231 /* match_arguments assume that out-mode = in-mode, this isn't true here
3233 set_ia32_ls_mode(new_node, smaller_mode);
3234 SET_IA32_ORIG_NODE(new_node, node);
3235 new_node = fix_mem_proj(new_node, &am);
3240 * Transforms a Conv node.
3242 * @return The created ia32 Conv node
3244 static ir_node *gen_Conv(ir_node *node)
3246 ir_node *block = get_nodes_block(node);
3247 ir_node *new_block = be_transform_node(block);
3248 ir_node *op = get_Conv_op(node);
3249 ir_node *new_op = NULL;
3250 dbg_info *dbgi = get_irn_dbg_info(node);
3251 ir_mode *src_mode = get_irn_mode(op);
3252 ir_mode *tgt_mode = get_irn_mode(node);
3253 int src_bits = get_mode_size_bits(src_mode);
3254 int tgt_bits = get_mode_size_bits(tgt_mode);
3255 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3256 ir_node *nomem = new_NoMem();
3257 ir_node *res = NULL;
3259 assert(!mode_is_int(src_mode) || src_bits <= 32);
3260 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3262 if (src_mode == mode_b) {
3263 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3264 /* nothing to do, we already model bools as 0/1 ints */
3265 return be_transform_node(op);
3268 if (src_mode == tgt_mode) {
3269 if (get_Conv_strict(node)) {
3270 if (ia32_cg_config.use_sse2) {
3271 /* when we are in SSE mode, we can kill all strict no-op conversion */
3272 return be_transform_node(op);
3275 /* this should be optimized already, but who knows... */
3276 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3277 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3278 return be_transform_node(op);
3282 if (mode_is_float(src_mode)) {
3283 new_op = be_transform_node(op);
3284 /* we convert from float ... */
3285 if (mode_is_float(tgt_mode)) {
3286 if (src_mode == mode_E && tgt_mode == mode_D
3287 && !get_Conv_strict(node)) {
3288 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3293 if (ia32_cg_config.use_sse2) {
3294 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3295 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg, noreg,
3297 set_ia32_ls_mode(res, tgt_mode);
3299 if (get_Conv_strict(node)) {
3300 res = gen_x87_strict_conv(tgt_mode, new_op);
3301 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3304 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3309 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3310 if (ia32_cg_config.use_sse2) {
3311 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg, noreg,
3313 set_ia32_ls_mode(res, src_mode);
3315 return gen_x87_fp_to_gp(node);
3319 /* we convert from int ... */
3320 if (mode_is_float(tgt_mode)) {
3322 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3323 if (ia32_cg_config.use_sse2) {
3324 new_op = be_transform_node(op);
3325 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg, noreg,
3327 set_ia32_ls_mode(res, tgt_mode);
3329 res = gen_x87_gp_to_fp(node, src_mode);
3330 if (get_Conv_strict(node)) {
3331 /* The strict-Conv is only necessary, if the int mode has more bits
3332 * than the float mantissa */
3333 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3334 size_t float_mantissa;
3335 /* FIXME There is no way to get the mantissa size of a mode */
3336 switch (get_mode_size_bits(tgt_mode)) {
3337 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3338 case 64: float_mantissa = 52 + 1; break;
3340 case 96: float_mantissa = 64; break;
3341 default: float_mantissa = 0; break;
3343 if (float_mantissa < int_mantissa) {
3344 res = gen_x87_strict_conv(tgt_mode, res);
3345 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3350 } else if (tgt_mode == mode_b) {
3351 /* mode_b lowering already took care that we only have 0/1 values */
3352 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3353 src_mode, tgt_mode));
3354 return be_transform_node(op);
3357 if (src_bits == tgt_bits) {
3358 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3359 src_mode, tgt_mode));
3360 return be_transform_node(op);
3363 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3371 static ir_node *create_immediate_or_transform(ir_node *node,
3372 char immediate_constraint_type)
3374 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3375 if (new_node == NULL) {
3376 new_node = be_transform_node(node);
3382 * Transforms a FrameAddr into an ia32 Add.
3384 static ir_node *gen_be_FrameAddr(ir_node *node)
3386 ir_node *block = be_transform_node(get_nodes_block(node));
3387 ir_node *op = be_get_FrameAddr_frame(node);
3388 ir_node *new_op = be_transform_node(op);
3389 dbg_info *dbgi = get_irn_dbg_info(node);
3390 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3393 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg);
3394 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3395 set_ia32_use_frame(new_node);
3397 SET_IA32_ORIG_NODE(new_node, node);
3403 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3405 static ir_node *gen_be_Return(ir_node *node)
3407 ir_graph *irg = current_ir_graph;
3408 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3409 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3410 ir_entity *ent = get_irg_entity(irg);
3411 ir_type *tp = get_entity_type(ent);
3416 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3417 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3420 int pn_ret_val, pn_ret_mem, arity, i;
3422 assert(ret_val != NULL);
3423 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3424 return be_duplicate_node(node);
3427 res_type = get_method_res_type(tp, 0);
3429 if (! is_Primitive_type(res_type)) {
3430 return be_duplicate_node(node);
3433 mode = get_type_mode(res_type);
3434 if (! mode_is_float(mode)) {
3435 return be_duplicate_node(node);
3438 assert(get_method_n_ress(tp) == 1);
3440 pn_ret_val = get_Proj_proj(ret_val);
3441 pn_ret_mem = get_Proj_proj(ret_mem);
3443 /* get the Barrier */
3444 barrier = get_Proj_pred(ret_val);
3446 /* get result input of the Barrier */
3447 ret_val = get_irn_n(barrier, pn_ret_val);
3448 new_ret_val = be_transform_node(ret_val);
3450 /* get memory input of the Barrier */
3451 ret_mem = get_irn_n(barrier, pn_ret_mem);
3452 new_ret_mem = be_transform_node(ret_mem);
3454 frame = get_irg_frame(irg);
3456 dbgi = get_irn_dbg_info(barrier);
3457 block = be_transform_node(get_nodes_block(barrier));
3459 noreg = ia32_new_NoReg_gp(env_cg);
3461 /* store xmm0 onto stack */
3462 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg,
3463 new_ret_mem, new_ret_val);
3464 set_ia32_ls_mode(sse_store, mode);
3465 set_ia32_op_type(sse_store, ia32_AddrModeD);
3466 set_ia32_use_frame(sse_store);
3468 /* load into x87 register */
3469 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg, sse_store, mode);
3470 set_ia32_op_type(fld, ia32_AddrModeS);
3471 set_ia32_use_frame(fld);
3473 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3474 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3476 /* create a new barrier */
3477 arity = get_irn_arity(barrier);
3478 in = ALLOCAN(ir_node*, arity);
3479 for (i = 0; i < arity; ++i) {
3482 if (i == pn_ret_val) {
3484 } else if (i == pn_ret_mem) {
3487 ir_node *in = get_irn_n(barrier, i);
3488 new_in = be_transform_node(in);
3493 new_barrier = new_ir_node(dbgi, irg, block,
3494 get_irn_op(barrier), get_irn_mode(barrier),
3496 copy_node_attr(barrier, new_barrier);
3497 be_duplicate_deps(barrier, new_barrier);
3498 be_set_transformed_node(barrier, new_barrier);
3500 /* transform normally */
3501 return be_duplicate_node(node);
3505 * Transform a be_AddSP into an ia32_SubSP.
3507 static ir_node *gen_be_AddSP(ir_node *node)
3509 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3510 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3512 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3513 match_am | match_immediate);
3517 * Transform a be_SubSP into an ia32_AddSP
3519 static ir_node *gen_be_SubSP(ir_node *node)
3521 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3522 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3524 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3525 match_am | match_immediate);
3529 * Change some phi modes
3531 static ir_node *gen_Phi(ir_node *node)
3533 ir_node *block = be_transform_node(get_nodes_block(node));
3534 ir_graph *irg = current_ir_graph;
3535 dbg_info *dbgi = get_irn_dbg_info(node);
3536 ir_mode *mode = get_irn_mode(node);
3539 if (ia32_mode_needs_gp_reg(mode)) {
3540 /* we shouldn't have any 64bit stuff around anymore */
3541 assert(get_mode_size_bits(mode) <= 32);
3542 /* all integer operations are on 32bit registers now */
3544 } else if (mode_is_float(mode)) {
3545 if (ia32_cg_config.use_sse2) {
3552 /* phi nodes allow loops, so we use the old arguments for now
3553 * and fix this later */
3554 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3555 get_irn_in(node) + 1);
3556 copy_node_attr(node, phi);
3557 be_duplicate_deps(node, phi);
3559 be_enqueue_preds(node);
3567 static ir_node *gen_IJmp(ir_node *node)
3569 ir_node *block = get_nodes_block(node);
3570 ir_node *new_block = be_transform_node(block);
3571 dbg_info *dbgi = get_irn_dbg_info(node);
3572 ir_node *op = get_IJmp_target(node);
3574 ia32_address_mode_t am;
3575 ia32_address_t *addr = &am.addr;
3577 assert(get_irn_mode(op) == mode_P);
3579 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3581 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3582 addr->mem, am.new_op2);
3583 set_am_attributes(new_node, &am);
3584 SET_IA32_ORIG_NODE(new_node, node);
3586 new_node = fix_mem_proj(new_node, &am);
3592 * Transform a Bound node.
3594 static ir_node *gen_Bound(ir_node *node)
3597 ir_node *lower = get_Bound_lower(node);
3598 dbg_info *dbgi = get_irn_dbg_info(node);
3600 if (is_Const_0(lower)) {
3601 /* typical case for Java */
3602 ir_node *sub, *res, *flags, *block;
3603 ir_graph *irg = current_ir_graph;
3605 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3606 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3608 block = get_nodes_block(res);
3609 if (! is_Proj(res)) {
3611 set_irn_mode(sub, mode_T);
3612 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3614 sub = get_Proj_pred(res);
3616 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3617 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3618 SET_IA32_ORIG_NODE(new_node, node);
3620 panic("generic Bound not supported in ia32 Backend");
3626 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3628 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3629 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3631 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3632 match_immediate | match_mode_neutral);
3635 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3637 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3638 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3639 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3643 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3645 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3646 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3647 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3651 static ir_node *gen_ia32_l_Add(ir_node *node)
3653 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3654 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3655 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3656 match_commutative | match_am | match_immediate |
3657 match_mode_neutral);
3659 if (is_Proj(lowered)) {
3660 lowered = get_Proj_pred(lowered);
3662 assert(is_ia32_Add(lowered));
3663 set_irn_mode(lowered, mode_T);
3669 static ir_node *gen_ia32_l_Adc(ir_node *node)
3671 return gen_binop_flags(node, new_bd_ia32_Adc,
3672 match_commutative | match_am | match_immediate |
3673 match_mode_neutral);
3677 * Transforms a l_MulS into a "real" MulS node.
3679 * @return the created ia32 Mul node
3681 static ir_node *gen_ia32_l_Mul(ir_node *node)
3683 ir_node *left = get_binop_left(node);
3684 ir_node *right = get_binop_right(node);
3686 return gen_binop(node, left, right, new_bd_ia32_Mul,
3687 match_commutative | match_am | match_mode_neutral);
3691 * Transforms a l_IMulS into a "real" IMul1OPS node.
3693 * @return the created ia32 IMul1OP node
3695 static ir_node *gen_ia32_l_IMul(ir_node *node)
3697 ir_node *left = get_binop_left(node);
3698 ir_node *right = get_binop_right(node);
3700 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3701 match_commutative | match_am | match_mode_neutral);
3704 static ir_node *gen_ia32_l_Sub(ir_node *node)
3706 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3707 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3708 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3709 match_am | match_immediate | match_mode_neutral);
3711 if (is_Proj(lowered)) {
3712 lowered = get_Proj_pred(lowered);
3714 assert(is_ia32_Sub(lowered));
3715 set_irn_mode(lowered, mode_T);
3721 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3723 return gen_binop_flags(node, new_bd_ia32_Sbb,
3724 match_am | match_immediate | match_mode_neutral);
3728 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3729 * op1 - target to be shifted
3730 * op2 - contains bits to be shifted into target
3732 * Only op3 can be an immediate.
3734 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3735 ir_node *low, ir_node *count)
3737 ir_node *block = get_nodes_block(node);
3738 ir_node *new_block = be_transform_node(block);
3739 dbg_info *dbgi = get_irn_dbg_info(node);
3740 ir_node *new_high = be_transform_node(high);
3741 ir_node *new_low = be_transform_node(low);
3745 /* the shift amount can be any mode that is bigger than 5 bits, since all
3746 * other bits are ignored anyway */
3747 while (is_Conv(count) &&
3748 get_irn_n_edges(count) == 1 &&
3749 mode_is_int(get_irn_mode(count))) {
3750 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3751 count = get_Conv_op(count);
3753 new_count = create_immediate_or_transform(count, 0);
3755 if (is_ia32_l_ShlD(node)) {
3756 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3759 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3762 SET_IA32_ORIG_NODE(new_node, node);
3767 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3769 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3770 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3771 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3772 return gen_lowered_64bit_shifts(node, high, low, count);
3775 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3777 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3778 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3779 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3780 return gen_lowered_64bit_shifts(node, high, low, count);
3783 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3785 ir_node *src_block = get_nodes_block(node);
3786 ir_node *block = be_transform_node(src_block);
3787 ir_graph *irg = current_ir_graph;
3788 dbg_info *dbgi = get_irn_dbg_info(node);
3789 ir_node *frame = get_irg_frame(irg);
3790 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3791 ir_node *nomem = new_NoMem();
3792 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3793 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3794 ir_node *new_val_low = be_transform_node(val_low);
3795 ir_node *new_val_high = be_transform_node(val_high);
3800 ir_node *store_high;
3802 if (!mode_is_signed(get_irn_mode(val_high))) {
3803 panic("unsigned long long -> float not supported yet (%+F)", node);
3807 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3809 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3811 SET_IA32_ORIG_NODE(store_low, node);
3812 SET_IA32_ORIG_NODE(store_high, node);
3814 set_ia32_use_frame(store_low);
3815 set_ia32_use_frame(store_high);
3816 set_ia32_op_type(store_low, ia32_AddrModeD);
3817 set_ia32_op_type(store_high, ia32_AddrModeD);
3818 set_ia32_ls_mode(store_low, mode_Iu);
3819 set_ia32_ls_mode(store_high, mode_Is);
3820 add_ia32_am_offs_int(store_high, 4);
3824 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3827 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg, sync);
3829 set_ia32_use_frame(fild);
3830 set_ia32_op_type(fild, ia32_AddrModeS);
3831 set_ia32_ls_mode(fild, mode_Ls);
3833 SET_IA32_ORIG_NODE(fild, node);
3835 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3838 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3840 ir_node *src_block = get_nodes_block(node);
3841 ir_node *block = be_transform_node(src_block);
3842 ir_graph *irg = current_ir_graph;
3843 dbg_info *dbgi = get_irn_dbg_info(node);
3844 ir_node *frame = get_irg_frame(irg);
3845 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3846 ir_node *nomem = new_NoMem();
3847 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3848 ir_node *new_val = be_transform_node(val);
3849 ir_node *fist, *mem;
3851 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3852 SET_IA32_ORIG_NODE(fist, node);
3853 set_ia32_use_frame(fist);
3854 set_ia32_op_type(fist, ia32_AddrModeD);
3855 set_ia32_ls_mode(fist, mode_Ls);
3861 * the BAD transformer.
3863 static ir_node *bad_transform(ir_node *node)
3865 panic("No transform function for %+F available.", node);
3869 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3871 ir_graph *irg = current_ir_graph;
3872 ir_node *block = be_transform_node(get_nodes_block(node));
3873 ir_node *pred = get_Proj_pred(node);
3874 ir_node *new_pred = be_transform_node(pred);
3875 ir_node *frame = get_irg_frame(irg);
3876 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3877 dbg_info *dbgi = get_irn_dbg_info(node);
3878 long pn = get_Proj_proj(node);
3883 load = new_bd_ia32_Load(dbgi, block, frame, noreg, new_pred);
3884 SET_IA32_ORIG_NODE(load, node);
3885 set_ia32_use_frame(load);
3886 set_ia32_op_type(load, ia32_AddrModeS);
3887 set_ia32_ls_mode(load, mode_Iu);
3888 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3889 * 32 bit from it with this particular load */
3890 attr = get_ia32_attr(load);
3891 attr->data.need_64bit_stackent = 1;
3893 if (pn == pn_ia32_l_FloattoLL_res_high) {
3894 add_ia32_am_offs_int(load, 4);
3896 assert(pn == pn_ia32_l_FloattoLL_res_low);
3899 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3905 * Transform the Projs of an AddSP.
3907 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3909 ir_node *block = be_transform_node(get_nodes_block(node));
3910 ir_node *pred = get_Proj_pred(node);
3911 ir_node *new_pred = be_transform_node(pred);
3912 ir_graph *irg = current_ir_graph;
3913 dbg_info *dbgi = get_irn_dbg_info(node);
3914 long proj = get_Proj_proj(node);
3916 if (proj == pn_be_AddSP_sp) {
3917 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3918 pn_ia32_SubSP_stack);
3919 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3921 } else if (proj == pn_be_AddSP_res) {
3922 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3923 pn_ia32_SubSP_addr);
3924 } else if (proj == pn_be_AddSP_M) {
3925 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3928 panic("No idea how to transform proj->AddSP");
3932 * Transform the Projs of a SubSP.
3934 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3936 ir_node *block = be_transform_node(get_nodes_block(node));
3937 ir_node *pred = get_Proj_pred(node);
3938 ir_node *new_pred = be_transform_node(pred);
3939 ir_graph *irg = current_ir_graph;
3940 dbg_info *dbgi = get_irn_dbg_info(node);
3941 long proj = get_Proj_proj(node);
3943 if (proj == pn_be_SubSP_sp) {
3944 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3945 pn_ia32_AddSP_stack);
3946 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3948 } else if (proj == pn_be_SubSP_M) {
3949 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3952 panic("No idea how to transform proj->SubSP");
3956 * Transform and renumber the Projs from a Load.
3958 static ir_node *gen_Proj_Load(ir_node *node)
3961 ir_node *block = be_transform_node(get_nodes_block(node));
3962 ir_node *pred = get_Proj_pred(node);
3963 ir_graph *irg = current_ir_graph;
3964 dbg_info *dbgi = get_irn_dbg_info(node);
3965 long proj = get_Proj_proj(node);
3967 /* loads might be part of source address mode matches, so we don't
3968 * transform the ProjMs yet (with the exception of loads whose result is
3971 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
3974 /* this is needed, because sometimes we have loops that are only
3975 reachable through the ProjM */
3976 be_enqueue_preds(node);
3977 /* do it in 2 steps, to silence firm verifier */
3978 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
3979 set_Proj_proj(res, pn_ia32_mem);
3983 /* renumber the proj */
3984 new_pred = be_transform_node(pred);
3985 if (is_ia32_Load(new_pred)) {
3988 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
3990 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
3991 case pn_Load_X_regular:
3992 return new_rd_Jmp(dbgi, irg, block);
3993 case pn_Load_X_except:
3994 /* This Load might raise an exception. Mark it. */
3995 set_ia32_exc_label(new_pred, 1);
3996 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4000 } else if (is_ia32_Conv_I2I(new_pred) ||
4001 is_ia32_Conv_I2I8Bit(new_pred)) {
4002 set_irn_mode(new_pred, mode_T);
4003 if (proj == pn_Load_res) {
4004 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4005 } else if (proj == pn_Load_M) {
4006 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4008 } else if (is_ia32_xLoad(new_pred)) {
4011 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4013 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4014 case pn_Load_X_regular:
4015 return new_rd_Jmp(dbgi, irg, block);
4016 case pn_Load_X_except:
4017 /* This Load might raise an exception. Mark it. */
4018 set_ia32_exc_label(new_pred, 1);
4019 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4023 } else if (is_ia32_vfld(new_pred)) {
4026 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4028 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4029 case pn_Load_X_regular:
4030 return new_rd_Jmp(dbgi, irg, block);
4031 case pn_Load_X_except:
4032 /* This Load might raise an exception. Mark it. */
4033 set_ia32_exc_label(new_pred, 1);
4034 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4039 /* can happen for ProJMs when source address mode happened for the
4042 /* however it should not be the result proj, as that would mean the
4043 load had multiple users and should not have been used for
4045 if (proj != pn_Load_M) {
4046 panic("internal error: transformed node not a Load");
4048 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4051 panic("No idea how to transform proj");
4055 * Transform and renumber the Projs from a DivMod like instruction.
4057 static ir_node *gen_Proj_DivMod(ir_node *node)
4059 ir_node *block = be_transform_node(get_nodes_block(node));
4060 ir_node *pred = get_Proj_pred(node);
4061 ir_node *new_pred = be_transform_node(pred);
4062 ir_graph *irg = current_ir_graph;
4063 dbg_info *dbgi = get_irn_dbg_info(node);
4064 long proj = get_Proj_proj(node);
4066 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4068 switch (get_irn_opcode(pred)) {
4072 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4074 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4075 case pn_Div_X_regular:
4076 return new_rd_Jmp(dbgi, irg, block);
4077 case pn_Div_X_except:
4078 set_ia32_exc_label(new_pred, 1);
4079 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4087 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4089 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4090 case pn_Mod_X_except:
4091 set_ia32_exc_label(new_pred, 1);
4092 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4100 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4101 case pn_DivMod_res_div:
4102 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4103 case pn_DivMod_res_mod:
4104 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4105 case pn_DivMod_X_regular:
4106 return new_rd_Jmp(dbgi, irg, block);
4107 case pn_DivMod_X_except:
4108 set_ia32_exc_label(new_pred, 1);
4109 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4118 panic("No idea how to transform proj->DivMod");
4122 * Transform and renumber the Projs from a CopyB.
4124 static ir_node *gen_Proj_CopyB(ir_node *node)
4126 ir_node *block = be_transform_node(get_nodes_block(node));
4127 ir_node *pred = get_Proj_pred(node);
4128 ir_node *new_pred = be_transform_node(pred);
4129 ir_graph *irg = current_ir_graph;
4130 dbg_info *dbgi = get_irn_dbg_info(node);
4131 long proj = get_Proj_proj(node);
4134 case pn_CopyB_M_regular:
4135 if (is_ia32_CopyB_i(new_pred)) {
4136 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4137 } else if (is_ia32_CopyB(new_pred)) {
4138 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4145 panic("No idea how to transform proj->CopyB");
4149 * Transform and renumber the Projs from a Quot.
4151 static ir_node *gen_Proj_Quot(ir_node *node)
4153 ir_node *block = be_transform_node(get_nodes_block(node));
4154 ir_node *pred = get_Proj_pred(node);
4155 ir_node *new_pred = be_transform_node(pred);
4156 ir_graph *irg = current_ir_graph;
4157 dbg_info *dbgi = get_irn_dbg_info(node);
4158 long proj = get_Proj_proj(node);
4162 if (is_ia32_xDiv(new_pred)) {
4163 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4164 } else if (is_ia32_vfdiv(new_pred)) {
4165 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4169 if (is_ia32_xDiv(new_pred)) {
4170 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4171 } else if (is_ia32_vfdiv(new_pred)) {
4172 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4175 case pn_Quot_X_regular:
4176 case pn_Quot_X_except:
4181 panic("No idea how to transform proj->Quot");
4184 static ir_node *gen_be_Call(ir_node *node)
4186 dbg_info *const dbgi = get_irn_dbg_info(node);
4187 ir_graph *const irg = current_ir_graph;
4188 ir_node *const src_block = get_nodes_block(node);
4189 ir_node *const block = be_transform_node(src_block);
4190 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4191 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4192 ir_node *const sp = be_transform_node(src_sp);
4193 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4194 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4195 ia32_address_mode_t am;
4196 ia32_address_t *const addr = &am.addr;
4201 ir_node * eax = noreg;
4202 ir_node * ecx = noreg;
4203 ir_node * edx = noreg;
4204 unsigned const pop = be_Call_get_pop(node);
4205 ir_type *const call_tp = be_Call_get_type(node);
4207 /* Run the x87 simulator if the call returns a float value */
4208 if (get_method_n_ress(call_tp) > 0) {
4209 ir_type *const res_type = get_method_res_type(call_tp, 0);
4210 ir_mode *const res_mode = get_type_mode(res_type);
4212 if (res_mode != NULL && mode_is_float(res_mode)) {
4213 env_cg->do_x87_sim = 1;
4217 /* We do not want be_Call direct calls */
4218 assert(be_Call_get_entity(node) == NULL);
4220 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4221 match_am | match_immediate);
4223 i = get_irn_arity(node) - 1;
4224 fpcw = be_transform_node(get_irn_n(node, i--));
4225 for (; i >= be_pos_Call_first_arg; --i) {
4226 arch_register_req_t const *const req = arch_get_register_req(node, i);
4227 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4229 assert(req->type == arch_register_req_type_limited);
4230 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4232 switch (*req->limited) {
4233 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4234 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4235 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4236 default: panic("Invalid GP register for register parameter");
4240 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4241 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4242 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4243 set_am_attributes(call, &am);
4244 call = fix_mem_proj(call, &am);
4246 if (get_irn_pinned(node) == op_pin_state_pinned)
4247 set_irn_pinned(call, op_pin_state_pinned);
4249 SET_IA32_ORIG_NODE(call, node);
4253 static ir_node *gen_be_IncSP(ir_node *node)
4255 ir_node *res = be_duplicate_node(node);
4256 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4262 * Transform the Projs from a be_Call.
4264 static ir_node *gen_Proj_be_Call(ir_node *node)
4266 ir_node *block = be_transform_node(get_nodes_block(node));
4267 ir_node *call = get_Proj_pred(node);
4268 ir_node *new_call = be_transform_node(call);
4269 ir_graph *irg = current_ir_graph;
4270 dbg_info *dbgi = get_irn_dbg_info(node);
4271 ir_type *method_type = be_Call_get_type(call);
4272 int n_res = get_method_n_ress(method_type);
4273 long proj = get_Proj_proj(node);
4274 ir_mode *mode = get_irn_mode(node);
4278 /* The following is kinda tricky: If we're using SSE, then we have to
4279 * move the result value of the call in floating point registers to an
4280 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4281 * after the call, we have to make sure to correctly make the
4282 * MemProj and the result Proj use these 2 nodes
4284 if (proj == pn_be_Call_M_regular) {
4285 // get new node for result, are we doing the sse load/store hack?
4286 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4287 ir_node *call_res_new;
4288 ir_node *call_res_pred = NULL;
4290 if (call_res != NULL) {
4291 call_res_new = be_transform_node(call_res);
4292 call_res_pred = get_Proj_pred(call_res_new);
4295 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4296 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4299 assert(is_ia32_xLoad(call_res_pred));
4300 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4304 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4305 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4307 ir_node *frame = get_irg_frame(irg);
4308 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4310 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4313 /* in case there is no memory output: create one to serialize the copy
4315 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4316 pn_be_Call_M_regular);
4317 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4318 pn_be_Call_first_res);
4320 /* store st(0) onto stack */
4321 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg, call_mem,
4323 set_ia32_op_type(fstp, ia32_AddrModeD);
4324 set_ia32_use_frame(fstp);
4326 /* load into SSE register */
4327 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg, fstp, mode);
4328 set_ia32_op_type(sse_load, ia32_AddrModeS);
4329 set_ia32_use_frame(sse_load);
4331 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4337 /* transform call modes */
4338 if (mode_is_data(mode)) {
4339 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4343 /* Map from be_Call to ia32_Call proj number */
4344 if (proj == pn_be_Call_sp) {
4345 proj = pn_ia32_Call_stack;
4346 } else if (proj == pn_be_Call_M_regular) {
4347 proj = pn_ia32_Call_M;
4349 arch_register_req_t const *const req = arch_get_register_req_out(node);
4350 int const n_outs = arch_irn_get_n_outs(new_call);
4353 assert(proj >= pn_be_Call_first_res);
4354 assert(req->type & arch_register_req_type_limited);
4356 for (i = 0; i < n_outs; ++i) {
4357 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4359 if (!(new_req->type & arch_register_req_type_limited) ||
4360 new_req->cls != req->cls ||
4361 *new_req->limited != *req->limited)
4370 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4372 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4374 case pn_ia32_Call_stack:
4375 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4378 case pn_ia32_Call_fpcw:
4379 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4387 * Transform the Projs from a Cmp.
4389 static ir_node *gen_Proj_Cmp(ir_node *node)
4391 /* this probably means not all mode_b nodes were lowered... */
4392 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4397 * Transform the Projs from a Bound.
4399 static ir_node *gen_Proj_Bound(ir_node *node)
4401 ir_node *new_node, *block;
4402 ir_node *pred = get_Proj_pred(node);
4404 switch (get_Proj_proj(node)) {
4406 return be_transform_node(get_Bound_mem(pred));
4407 case pn_Bound_X_regular:
4408 new_node = be_transform_node(pred);
4409 block = get_nodes_block(new_node);
4410 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4411 case pn_Bound_X_except:
4412 new_node = be_transform_node(pred);
4413 block = get_nodes_block(new_node);
4414 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4416 return be_transform_node(get_Bound_index(pred));
4418 panic("unsupported Proj from Bound");
4422 static ir_node *gen_Proj_ASM(ir_node *node)
4428 if (get_irn_mode(node) != mode_M)
4429 return be_duplicate_node(node);
4431 pred = get_Proj_pred(node);
4432 new_pred = be_transform_node(pred);
4433 block = get_nodes_block(new_pred);
4434 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4435 arch_irn_get_n_outs(new_pred) + 1);
4439 * Transform and potentially renumber Proj nodes.
4441 static ir_node *gen_Proj(ir_node *node)
4443 ir_node *pred = get_Proj_pred(node);
4446 switch (get_irn_opcode(pred)) {
4448 proj = get_Proj_proj(node);
4449 if (proj == pn_Store_M) {
4450 return be_transform_node(pred);
4452 panic("No idea how to transform proj->Store");
4455 return gen_Proj_Load(node);
4457 return gen_Proj_ASM(node);
4461 return gen_Proj_DivMod(node);
4463 return gen_Proj_CopyB(node);
4465 return gen_Proj_Quot(node);
4467 return gen_Proj_be_SubSP(node);
4469 return gen_Proj_be_AddSP(node);
4471 return gen_Proj_be_Call(node);
4473 return gen_Proj_Cmp(node);
4475 return gen_Proj_Bound(node);
4477 proj = get_Proj_proj(node);
4479 case pn_Start_X_initial_exec: {
4480 ir_node *block = get_nodes_block(pred);
4481 ir_node *new_block = be_transform_node(block);
4482 dbg_info *dbgi = get_irn_dbg_info(node);
4483 /* we exchange the ProjX with a jump */
4484 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4489 case pn_Start_P_tls:
4490 return gen_Proj_tls(node);
4495 if (is_ia32_l_FloattoLL(pred)) {
4496 return gen_Proj_l_FloattoLL(node);
4498 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4502 ir_mode *mode = get_irn_mode(node);
4503 if (ia32_mode_needs_gp_reg(mode)) {
4504 ir_node *new_pred = be_transform_node(pred);
4505 ir_node *block = be_transform_node(get_nodes_block(node));
4506 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4507 mode_Iu, get_Proj_proj(node));
4508 #ifdef DEBUG_libfirm
4509 new_proj->node_nr = node->node_nr;
4515 return be_duplicate_node(node);
4519 * Enters all transform functions into the generic pointer
4521 static void register_transformers(void)
4525 /* first clear the generic function pointer for all ops */
4526 clear_irp_opcodes_generic_func();
4528 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4529 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4567 /* transform ops from intrinsic lowering */
4579 GEN(ia32_l_LLtoFloat);
4580 GEN(ia32_l_FloattoLL);
4586 /* we should never see these nodes */
4601 /* handle generic backend nodes */
4610 op_Mulh = get_op_Mulh();
4619 * Pre-transform all unknown and noreg nodes.
4621 static void ia32_pretransform_node(void)
4623 ia32_code_gen_t *cg = env_cg;
4625 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4626 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4627 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4628 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4629 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4630 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4635 * Walker, checks if all ia32 nodes producing more than one result have their
4636 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4638 static void add_missing_keep_walker(ir_node *node, void *data)
4641 unsigned found_projs = 0;
4642 const ir_edge_t *edge;
4643 ir_mode *mode = get_irn_mode(node);
4648 if (!is_ia32_irn(node))
4651 n_outs = arch_irn_get_n_outs(node);
4654 if (is_ia32_SwitchJmp(node))
4657 assert(n_outs < (int) sizeof(unsigned) * 8);
4658 foreach_out_edge(node, edge) {
4659 ir_node *proj = get_edge_src_irn(edge);
4662 /* The node could be kept */
4666 if (get_irn_mode(proj) == mode_M)
4669 pn = get_Proj_proj(proj);
4670 assert(pn < n_outs);
4671 found_projs |= 1 << pn;
4675 /* are keeps missing? */
4677 for (i = 0; i < n_outs; ++i) {
4680 const arch_register_req_t *req;
4681 const arch_register_class_t *cls;
4683 if (found_projs & (1 << i)) {
4687 req = get_ia32_out_req(node, i);
4692 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4696 block = get_nodes_block(node);
4697 in[0] = new_r_Proj(current_ir_graph, block, node,
4698 arch_register_class_mode(cls), i);
4699 if (last_keep != NULL) {
4700 be_Keep_add_node(last_keep, cls, in[0]);
4702 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4703 if (sched_is_scheduled(node)) {
4704 sched_add_after(node, last_keep);
4711 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4714 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4716 ir_graph *irg = be_get_birg_irg(cg->birg);
4717 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4720 /* do the transformation */
4721 void ia32_transform_graph(ia32_code_gen_t *cg)
4725 register_transformers();
4727 initial_fpcw = NULL;
4729 BE_TIMER_PUSH(t_heights);
4730 heights = heights_new(cg->irg);
4731 BE_TIMER_POP(t_heights);
4732 ia32_calculate_non_address_mode_nodes(cg->birg);
4734 /* the transform phase is not safe for CSE (yet) because several nodes get
4735 * attributes set after their creation */
4736 cse_last = get_opt_cse();
4739 be_transform_graph(cg->birg, ia32_pretransform_node);
4741 set_opt_cse(cse_last);
4743 ia32_free_non_address_mode_nodes();
4744 heights_free(heights);
4748 void ia32_init_transform(void)
4750 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");