2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
34 #include "irgraph_t.h"
39 #include "iredges_t.h"
52 #include "../benode_t.h"
53 #include "../besched.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
60 #include "bearch_ia32_t.h"
61 #include "ia32_common_transform.h"
62 #include "ia32_nodes_attr.h"
63 #include "ia32_transform.h"
64 #include "ia32_new_nodes.h"
65 #include "ia32_map_regs.h"
66 #include "ia32_dbg_stat.h"
67 #include "ia32_optimize.h"
68 #include "ia32_util.h"
69 #include "ia32_address_mode.h"
70 #include "ia32_architecture.h"
72 #include "gen_ia32_regalloc_if.h"
74 #define SFP_SIGN "0x80000000"
75 #define DFP_SIGN "0x8000000000000000"
76 #define SFP_ABS "0x7FFFFFFF"
77 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
78 #define DFP_INTMAX "9223372036854775807"
80 #define TP_SFP_SIGN "ia32_sfp_sign"
81 #define TP_DFP_SIGN "ia32_dfp_sign"
82 #define TP_SFP_ABS "ia32_sfp_abs"
83 #define TP_DFP_ABS "ia32_dfp_abs"
84 #define TP_INT_MAX "ia32_int_max"
86 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
87 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
88 #define ENT_SFP_ABS "IA32_SFP_ABS"
89 #define ENT_DFP_ABS "IA32_DFP_ABS"
90 #define ENT_INT_MAX "IA32_INT_MAX"
92 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
93 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
95 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
97 static ir_node *initial_fpcw = NULL;
99 extern ir_op *get_op_Mulh(void);
101 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
102 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
105 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
106 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
109 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
110 ir_node *op1, ir_node *op2);
112 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
113 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
115 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
116 ir_node *base, ir_node *index, ir_node *mem);
118 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
119 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
122 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
124 static ir_node *create_immediate_or_transform(ir_node *node,
125 char immediate_constraint_type);
127 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
128 dbg_info *dbgi, ir_node *block,
129 ir_node *op, ir_node *orig_node);
131 /** Return non-zero is a node represents the 0 constant. */
132 static bool is_Const_0(ir_node *node)
134 return is_Const(node) && is_Const_null(node);
137 /** Return non-zero is a node represents the 1 constant. */
138 static bool is_Const_1(ir_node *node)
140 return is_Const(node) && is_Const_one(node);
143 /** Return non-zero is a node represents the -1 constant. */
144 static bool is_Const_Minus_1(ir_node *node)
146 return is_Const(node) && is_Const_all_one(node);
150 * returns true if constant can be created with a simple float command
152 static bool is_simple_x87_Const(ir_node *node)
154 tarval *tv = get_Const_tarval(node);
155 if (tarval_is_null(tv) || tarval_is_one(tv))
158 /* TODO: match all the other float constants */
163 * returns true if constant can be created with a simple float command
165 static bool is_simple_sse_Const(ir_node *node)
167 tarval *tv = get_Const_tarval(node);
168 ir_mode *mode = get_tarval_mode(tv);
173 if (tarval_is_null(tv) || tarval_is_one(tv))
176 if (mode == mode_D) {
177 unsigned val = get_tarval_sub_bits(tv, 0) |
178 (get_tarval_sub_bits(tv, 1) << 8) |
179 (get_tarval_sub_bits(tv, 2) << 16) |
180 (get_tarval_sub_bits(tv, 3) << 24);
182 /* lower 32bit are zero, really a 32bit constant */
186 /* TODO: match all the other float constants */
191 * Transforms a Const.
193 static ir_node *gen_Const(ir_node *node)
195 ir_node *old_block = get_nodes_block(node);
196 ir_node *block = be_transform_node(old_block);
197 dbg_info *dbgi = get_irn_dbg_info(node);
198 ir_mode *mode = get_irn_mode(node);
200 assert(is_Const(node));
202 if (mode_is_float(mode)) {
204 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
205 ir_node *nomem = new_NoMem();
209 if (ia32_cg_config.use_sse2) {
210 tarval *tv = get_Const_tarval(node);
211 if (tarval_is_null(tv)) {
212 load = new_bd_ia32_xZero(dbgi, block);
213 set_ia32_ls_mode(load, mode);
215 } else if (tarval_is_one(tv)) {
216 int cnst = mode == mode_F ? 26 : 55;
217 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
218 ir_node *imm2 = create_Immediate(NULL, 0, 2);
219 ir_node *pslld, *psrld;
221 load = new_bd_ia32_xAllOnes(dbgi, block);
222 set_ia32_ls_mode(load, mode);
223 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
224 set_ia32_ls_mode(pslld, mode);
225 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
226 set_ia32_ls_mode(psrld, mode);
228 } else if (mode == mode_F) {
229 /* we can place any 32bit constant by using a movd gp, sse */
230 unsigned val = get_tarval_sub_bits(tv, 0) |
231 (get_tarval_sub_bits(tv, 1) << 8) |
232 (get_tarval_sub_bits(tv, 2) << 16) |
233 (get_tarval_sub_bits(tv, 3) << 24);
234 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
235 load = new_bd_ia32_xMovd(dbgi, block, cnst);
236 set_ia32_ls_mode(load, mode);
239 if (mode == mode_D) {
240 unsigned val = get_tarval_sub_bits(tv, 0) |
241 (get_tarval_sub_bits(tv, 1) << 8) |
242 (get_tarval_sub_bits(tv, 2) << 16) |
243 (get_tarval_sub_bits(tv, 3) << 24);
245 ir_node *imm32 = create_Immediate(NULL, 0, 32);
246 ir_node *cnst, *psllq;
248 /* fine, lower 32bit are zero, produce 32bit value */
249 val = get_tarval_sub_bits(tv, 4) |
250 (get_tarval_sub_bits(tv, 5) << 8) |
251 (get_tarval_sub_bits(tv, 6) << 16) |
252 (get_tarval_sub_bits(tv, 7) << 24);
253 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
254 load = new_bd_ia32_xMovd(dbgi, block, cnst);
255 set_ia32_ls_mode(load, mode);
256 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
257 set_ia32_ls_mode(psllq, mode);
262 floatent = create_float_const_entity(node);
264 load = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem,
266 set_ia32_op_type(load, ia32_AddrModeS);
267 set_ia32_am_sc(load, floatent);
268 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
269 res = new_r_Proj(current_ir_graph, block, load, mode_xmm, pn_ia32_xLoad_res);
272 if (is_Const_null(node)) {
273 load = new_bd_ia32_vfldz(dbgi, block);
275 set_ia32_ls_mode(load, mode);
276 } else if (is_Const_one(node)) {
277 load = new_bd_ia32_vfld1(dbgi, block);
279 set_ia32_ls_mode(load, mode);
281 floatent = create_float_const_entity(node);
283 load = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode);
284 set_ia32_op_type(load, ia32_AddrModeS);
285 set_ia32_am_sc(load, floatent);
286 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
287 res = new_r_Proj(current_ir_graph, block, load, mode_vfp, pn_ia32_vfld_res);
288 /* take the mode from the entity */
289 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
293 SET_IA32_ORIG_NODE(load, node);
295 be_dep_on_frame(load);
297 } else { /* non-float mode */
299 tarval *tv = get_Const_tarval(node);
302 tv = tarval_convert_to(tv, mode_Iu);
304 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
306 panic("couldn't convert constant tarval (%+F)", node);
308 val = get_tarval_long(tv);
310 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
311 SET_IA32_ORIG_NODE(cnst, node);
313 be_dep_on_frame(cnst);
319 * Transforms a SymConst.
321 static ir_node *gen_SymConst(ir_node *node)
323 ir_node *old_block = get_nodes_block(node);
324 ir_node *block = be_transform_node(old_block);
325 dbg_info *dbgi = get_irn_dbg_info(node);
326 ir_mode *mode = get_irn_mode(node);
329 if (mode_is_float(mode)) {
330 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
331 ir_node *nomem = new_NoMem();
333 if (ia32_cg_config.use_sse2)
334 cnst = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem, mode_E);
336 cnst = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode_E);
337 set_ia32_am_sc(cnst, get_SymConst_entity(node));
338 set_ia32_use_frame(cnst);
342 if (get_SymConst_kind(node) != symconst_addr_ent) {
343 panic("backend only support symconst_addr_ent (at %+F)", node);
345 entity = get_SymConst_entity(node);
346 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0);
349 SET_IA32_ORIG_NODE(cnst, node);
351 be_dep_on_frame(cnst);
355 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
356 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
358 static const struct {
360 const char *ent_name;
361 const char *cnst_str;
364 } names [ia32_known_const_max] = {
365 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
366 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
367 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
368 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
369 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
371 static ir_entity *ent_cache[ia32_known_const_max];
373 const char *tp_name, *ent_name, *cnst_str;
381 ent_name = names[kct].ent_name;
382 if (! ent_cache[kct]) {
383 tp_name = names[kct].tp_name;
384 cnst_str = names[kct].cnst_str;
386 switch (names[kct].mode) {
387 case 0: mode = mode_Iu; break;
388 case 1: mode = mode_Lu; break;
389 default: mode = mode_F; break;
391 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
392 tp = new_type_primitive(new_id_from_str(tp_name), mode);
393 /* set the specified alignment */
394 set_type_alignment_bytes(tp, names[kct].align);
396 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
398 set_entity_ld_ident(ent, get_entity_ident(ent));
399 set_entity_visibility(ent, visibility_local);
400 set_entity_variability(ent, variability_constant);
401 set_entity_allocation(ent, allocation_static);
403 /* we create a new entity here: It's initialization must resist on the
405 rem = current_ir_graph;
406 current_ir_graph = get_const_code_irg();
407 cnst = new_Const(mode, tv);
408 current_ir_graph = rem;
410 set_atomic_ent_value(ent, cnst);
412 /* cache the entry */
413 ent_cache[kct] = ent;
416 return ent_cache[kct];
420 * return true if the node is a Proj(Load) and could be used in source address
421 * mode for another node. Will return only true if the @p other node is not
422 * dependent on the memory of the Load (for binary operations use the other
423 * input here, for unary operations use NULL).
425 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
426 ir_node *other, ir_node *other2, match_flags_t flags)
431 /* float constants are always available */
432 if (is_Const(node)) {
433 ir_mode *mode = get_irn_mode(node);
434 if (mode_is_float(mode)) {
435 if (ia32_cg_config.use_sse2) {
436 if (is_simple_sse_Const(node))
439 if (is_simple_x87_Const(node))
442 if (get_irn_n_edges(node) > 1)
450 load = get_Proj_pred(node);
451 pn = get_Proj_proj(node);
452 if (!is_Load(load) || pn != pn_Load_res)
454 if (get_nodes_block(load) != block)
456 /* we only use address mode if we're the only user of the load */
457 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
459 /* in some edge cases with address mode we might reach the load normally
460 * and through some AM sequence, if it is already materialized then we
461 * can't create an AM node from it */
462 if (be_is_transformed(node))
465 /* don't do AM if other node inputs depend on the load (via mem-proj) */
466 if (other != NULL && prevents_AM(block, load, other))
469 if (other2 != NULL && prevents_AM(block, load, other2))
475 typedef struct ia32_address_mode_t ia32_address_mode_t;
476 struct ia32_address_mode_t {
481 ia32_op_type_t op_type;
485 unsigned commutative : 1;
486 unsigned ins_permuted : 1;
489 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
493 /* construct load address */
494 memset(addr, 0, sizeof(addr[0]));
495 ia32_create_address_mode(addr, ptr, 0);
497 noreg_gp = ia32_new_NoReg_gp(env_cg);
498 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
499 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
500 addr->mem = be_transform_node(mem);
503 static void build_address(ia32_address_mode_t *am, ir_node *node,
504 ia32_create_am_flags_t flags)
506 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
507 ia32_address_t *addr = &am->addr;
513 if (is_Const(node)) {
514 ir_entity *entity = create_float_const_entity(node);
515 addr->base = noreg_gp;
516 addr->index = noreg_gp;
517 addr->mem = new_NoMem();
518 addr->symconst_ent = entity;
520 am->ls_mode = get_type_mode(get_entity_type(entity));
521 am->pinned = op_pin_state_floats;
525 load = get_Proj_pred(node);
526 ptr = get_Load_ptr(load);
527 mem = get_Load_mem(load);
528 new_mem = be_transform_node(mem);
529 am->pinned = get_irn_pinned(load);
530 am->ls_mode = get_Load_mode(load);
531 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
534 /* construct load address */
535 ia32_create_address_mode(addr, ptr, flags);
537 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
538 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
542 static void set_address(ir_node *node, const ia32_address_t *addr)
544 set_ia32_am_scale(node, addr->scale);
545 set_ia32_am_sc(node, addr->symconst_ent);
546 set_ia32_am_offs_int(node, addr->offset);
547 if (addr->symconst_sign)
548 set_ia32_am_sc_sign(node);
550 set_ia32_use_frame(node);
551 set_ia32_frame_ent(node, addr->frame_entity);
555 * Apply attributes of a given address mode to a node.
557 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
559 set_address(node, &am->addr);
561 set_ia32_op_type(node, am->op_type);
562 set_ia32_ls_mode(node, am->ls_mode);
563 if (am->pinned == op_pin_state_pinned) {
564 /* beware: some nodes are already pinned and did not allow to change the state */
565 if (get_irn_pinned(node) != op_pin_state_pinned)
566 set_irn_pinned(node, op_pin_state_pinned);
569 set_ia32_commutative(node);
573 * Check, if a given node is a Down-Conv, ie. a integer Conv
574 * from a mode with a mode with more bits to a mode with lesser bits.
575 * Moreover, we return only true if the node has not more than 1 user.
577 * @param node the node
578 * @return non-zero if node is a Down-Conv
580 static int is_downconv(const ir_node *node)
588 /* we only want to skip the conv when we're the only user
589 * (not optimal but for now...)
591 if (get_irn_n_edges(node) > 1)
594 src_mode = get_irn_mode(get_Conv_op(node));
595 dest_mode = get_irn_mode(node);
596 return ia32_mode_needs_gp_reg(src_mode)
597 && ia32_mode_needs_gp_reg(dest_mode)
598 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
601 /* Skip all Down-Conv's on a given node and return the resulting node. */
602 ir_node *ia32_skip_downconv(ir_node *node)
604 while (is_downconv(node))
605 node = get_Conv_op(node);
610 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
612 ir_mode *mode = get_irn_mode(node);
617 if (mode_is_signed(mode)) {
622 block = get_nodes_block(node);
623 dbgi = get_irn_dbg_info(node);
625 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
629 * matches operands of a node into ia32 addressing/operand modes. This covers
630 * usage of source address mode, immediates, operations with non 32-bit modes,
632 * The resulting data is filled into the @p am struct. block is the block
633 * of the node whose arguments are matched. op1, op2 are the first and second
634 * input that are matched (op1 may be NULL). other_op is another unrelated
635 * input that is not matched! but which is needed sometimes to check if AM
636 * for op1/op2 is legal.
637 * @p flags describes the supported modes of the operation in detail.
639 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
640 ir_node *op1, ir_node *op2, ir_node *other_op,
643 ia32_address_t *addr = &am->addr;
644 ir_mode *mode = get_irn_mode(op2);
645 int mode_bits = get_mode_size_bits(mode);
646 ir_node *noreg_gp, *new_op1, *new_op2;
648 unsigned commutative;
649 int use_am_and_immediates;
652 memset(am, 0, sizeof(am[0]));
654 commutative = (flags & match_commutative) != 0;
655 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
656 use_am = (flags & match_am) != 0;
657 use_immediate = (flags & match_immediate) != 0;
658 assert(!use_am_and_immediates || use_immediate);
661 assert(!commutative || op1 != NULL);
662 assert(use_am || !(flags & match_8bit_am));
663 assert(use_am || !(flags & match_16bit_am));
665 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
666 (mode_bits == 16 && !(flags & match_16bit_am))) {
670 /* we can simply skip downconvs for mode neutral nodes: the upper bits
671 * can be random for these operations */
672 if (flags & match_mode_neutral) {
673 op2 = ia32_skip_downconv(op2);
675 op1 = ia32_skip_downconv(op1);
679 /* match immediates. firm nodes are normalized: constants are always on the
682 if (!(flags & match_try_am) && use_immediate) {
683 new_op2 = try_create_Immediate(op2, 0);
686 noreg_gp = ia32_new_NoReg_gp(env_cg);
687 if (new_op2 == NULL &&
688 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
689 build_address(am, op2, 0);
690 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
691 if (mode_is_float(mode)) {
692 new_op2 = ia32_new_NoReg_vfp(env_cg);
696 am->op_type = ia32_AddrModeS;
697 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
699 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
701 build_address(am, op1, 0);
703 if (mode_is_float(mode)) {
704 noreg = ia32_new_NoReg_vfp(env_cg);
709 if (new_op2 != NULL) {
712 new_op1 = be_transform_node(op2);
714 am->ins_permuted = 1;
716 am->op_type = ia32_AddrModeS;
718 am->op_type = ia32_Normal;
720 if (flags & match_try_am) {
726 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
728 new_op2 = be_transform_node(op2);
730 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
732 if (addr->base == NULL)
733 addr->base = noreg_gp;
734 if (addr->index == NULL)
735 addr->index = noreg_gp;
736 if (addr->mem == NULL)
737 addr->mem = new_NoMem();
739 am->new_op1 = new_op1;
740 am->new_op2 = new_op2;
741 am->commutative = commutative;
744 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
749 if (am->mem_proj == NULL)
752 /* we have to create a mode_T so the old MemProj can attach to us */
753 mode = get_irn_mode(node);
754 load = get_Proj_pred(am->mem_proj);
756 be_set_transformed_node(load, node);
758 if (mode != mode_T) {
759 set_irn_mode(node, mode_T);
760 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
767 * Construct a standard binary operation, set AM and immediate if required.
769 * @param node The original node for which the binop is created
770 * @param op1 The first operand
771 * @param op2 The second operand
772 * @param func The node constructor function
773 * @return The constructed ia32 node.
775 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
776 construct_binop_func *func, match_flags_t flags)
779 ir_node *block, *new_block, *new_node;
780 ia32_address_mode_t am;
781 ia32_address_t *addr = &am.addr;
783 block = get_nodes_block(node);
784 match_arguments(&am, block, op1, op2, NULL, flags);
786 dbgi = get_irn_dbg_info(node);
787 new_block = be_transform_node(block);
788 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
789 am.new_op1, am.new_op2);
790 set_am_attributes(new_node, &am);
791 /* we can't use source address mode anymore when using immediates */
792 if (!(flags & match_am_and_immediates) &&
793 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
794 set_ia32_am_support(new_node, ia32_am_none);
795 SET_IA32_ORIG_NODE(new_node, node);
797 new_node = fix_mem_proj(new_node, &am);
804 n_ia32_l_binop_right,
805 n_ia32_l_binop_eflags
807 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
808 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
809 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
810 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
811 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
812 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
815 * Construct a binary operation which also consumes the eflags.
817 * @param node The node to transform
818 * @param func The node constructor function
819 * @param flags The match flags
820 * @return The constructor ia32 node
822 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
825 ir_node *src_block = get_nodes_block(node);
826 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
827 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
828 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
830 ir_node *block, *new_node, *new_eflags;
831 ia32_address_mode_t am;
832 ia32_address_t *addr = &am.addr;
834 match_arguments(&am, src_block, op1, op2, eflags, flags);
836 dbgi = get_irn_dbg_info(node);
837 block = be_transform_node(src_block);
838 new_eflags = be_transform_node(eflags);
839 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
840 am.new_op1, am.new_op2, new_eflags);
841 set_am_attributes(new_node, &am);
842 /* we can't use source address mode anymore when using immediates */
843 if (!(flags & match_am_and_immediates) &&
844 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
845 set_ia32_am_support(new_node, ia32_am_none);
846 SET_IA32_ORIG_NODE(new_node, node);
848 new_node = fix_mem_proj(new_node, &am);
853 static ir_node *get_fpcw(void)
856 if (initial_fpcw != NULL)
859 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
860 &ia32_fp_cw_regs[REG_FPCW]);
861 initial_fpcw = be_transform_node(fpcw);
867 * Construct a standard binary operation, set AM and immediate if required.
869 * @param op1 The first operand
870 * @param op2 The second operand
871 * @param func The node constructor function
872 * @return The constructed ia32 node.
874 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
875 construct_binop_float_func *func)
877 ir_mode *mode = get_irn_mode(node);
879 ir_node *block, *new_block, *new_node;
880 ia32_address_mode_t am;
881 ia32_address_t *addr = &am.addr;
882 ia32_x87_attr_t *attr;
883 /* All operations are considered commutative, because there are reverse
885 match_flags_t flags = match_commutative;
887 /* cannot use address mode with long double on x87 */
888 if (get_mode_size_bits(mode) <= 64)
891 block = get_nodes_block(node);
892 match_arguments(&am, block, op1, op2, NULL, flags);
894 dbgi = get_irn_dbg_info(node);
895 new_block = be_transform_node(block);
896 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
897 am.new_op1, am.new_op2, get_fpcw());
898 set_am_attributes(new_node, &am);
900 attr = get_ia32_x87_attr(new_node);
901 attr->attr.data.ins_permuted = am.ins_permuted;
903 SET_IA32_ORIG_NODE(new_node, node);
905 new_node = fix_mem_proj(new_node, &am);
911 * Construct a shift/rotate binary operation, sets AM and immediate if required.
913 * @param op1 The first operand
914 * @param op2 The second operand
915 * @param func The node constructor function
916 * @return The constructed ia32 node.
918 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
919 construct_shift_func *func,
923 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
925 assert(! mode_is_float(get_irn_mode(node)));
926 assert(flags & match_immediate);
927 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
929 if (flags & match_mode_neutral) {
930 op1 = ia32_skip_downconv(op1);
931 new_op1 = be_transform_node(op1);
932 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
933 new_op1 = create_upconv(op1, node);
935 new_op1 = be_transform_node(op1);
938 /* the shift amount can be any mode that is bigger than 5 bits, since all
939 * other bits are ignored anyway */
940 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
941 ir_node *const op = get_Conv_op(op2);
942 if (mode_is_float(get_irn_mode(op)))
945 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
947 new_op2 = create_immediate_or_transform(op2, 0);
949 dbgi = get_irn_dbg_info(node);
950 block = get_nodes_block(node);
951 new_block = be_transform_node(block);
952 new_node = func(dbgi, new_block, new_op1, new_op2);
953 SET_IA32_ORIG_NODE(new_node, node);
955 /* lowered shift instruction may have a dependency operand, handle it here */
956 if (get_irn_arity(node) == 3) {
957 /* we have a dependency */
958 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
959 add_irn_dep(new_node, new_dep);
967 * Construct a standard unary operation, set AM and immediate if required.
969 * @param op The operand
970 * @param func The node constructor function
971 * @return The constructed ia32 node.
973 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
977 ir_node *block, *new_block, *new_op, *new_node;
979 assert(flags == 0 || flags == match_mode_neutral);
980 if (flags & match_mode_neutral) {
981 op = ia32_skip_downconv(op);
984 new_op = be_transform_node(op);
985 dbgi = get_irn_dbg_info(node);
986 block = get_nodes_block(node);
987 new_block = be_transform_node(block);
988 new_node = func(dbgi, new_block, new_op);
990 SET_IA32_ORIG_NODE(new_node, node);
995 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
996 ia32_address_t *addr)
998 ir_node *base, *index, *res;
1002 base = ia32_new_NoReg_gp(env_cg);
1004 base = be_transform_node(base);
1007 index = addr->index;
1008 if (index == NULL) {
1009 index = ia32_new_NoReg_gp(env_cg);
1011 index = be_transform_node(index);
1014 res = new_bd_ia32_Lea(dbgi, block, base, index);
1015 set_address(res, addr);
1021 * Returns non-zero if a given address mode has a symbolic or
1022 * numerical offset != 0.
1024 static int am_has_immediates(const ia32_address_t *addr)
1026 return addr->offset != 0 || addr->symconst_ent != NULL
1027 || addr->frame_entity || addr->use_frame;
1031 * Creates an ia32 Add.
1033 * @return the created ia32 Add node
1035 static ir_node *gen_Add(ir_node *node)
1037 ir_mode *mode = get_irn_mode(node);
1038 ir_node *op1 = get_Add_left(node);
1039 ir_node *op2 = get_Add_right(node);
1041 ir_node *block, *new_block, *new_node, *add_immediate_op;
1042 ia32_address_t addr;
1043 ia32_address_mode_t am;
1045 if (mode_is_float(mode)) {
1046 if (ia32_cg_config.use_sse2)
1047 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1048 match_commutative | match_am);
1050 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1053 ia32_mark_non_am(node);
1055 op2 = ia32_skip_downconv(op2);
1056 op1 = ia32_skip_downconv(op1);
1060 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1061 * 1. Add with immediate -> Lea
1062 * 2. Add with possible source address mode -> Add
1063 * 3. Otherwise -> Lea
1065 memset(&addr, 0, sizeof(addr));
1066 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1067 add_immediate_op = NULL;
1069 dbgi = get_irn_dbg_info(node);
1070 block = get_nodes_block(node);
1071 new_block = be_transform_node(block);
1074 if (addr.base == NULL && addr.index == NULL) {
1075 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1076 addr.symconst_sign, addr.offset);
1077 be_dep_on_frame(new_node);
1078 SET_IA32_ORIG_NODE(new_node, node);
1081 /* add with immediate? */
1082 if (addr.index == NULL) {
1083 add_immediate_op = addr.base;
1084 } else if (addr.base == NULL && addr.scale == 0) {
1085 add_immediate_op = addr.index;
1088 if (add_immediate_op != NULL) {
1089 if (!am_has_immediates(&addr)) {
1090 #ifdef DEBUG_libfirm
1091 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1094 return be_transform_node(add_immediate_op);
1097 new_node = create_lea_from_address(dbgi, new_block, &addr);
1098 SET_IA32_ORIG_NODE(new_node, node);
1102 /* test if we can use source address mode */
1103 match_arguments(&am, block, op1, op2, NULL, match_commutative
1104 | match_mode_neutral | match_am | match_immediate | match_try_am);
1106 /* construct an Add with source address mode */
1107 if (am.op_type == ia32_AddrModeS) {
1108 ia32_address_t *am_addr = &am.addr;
1109 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1110 am_addr->index, am_addr->mem, am.new_op1,
1112 set_am_attributes(new_node, &am);
1113 SET_IA32_ORIG_NODE(new_node, node);
1115 new_node = fix_mem_proj(new_node, &am);
1120 /* otherwise construct a lea */
1121 new_node = create_lea_from_address(dbgi, new_block, &addr);
1122 SET_IA32_ORIG_NODE(new_node, node);
1127 * Creates an ia32 Mul.
1129 * @return the created ia32 Mul node
1131 static ir_node *gen_Mul(ir_node *node)
1133 ir_node *op1 = get_Mul_left(node);
1134 ir_node *op2 = get_Mul_right(node);
1135 ir_mode *mode = get_irn_mode(node);
1137 if (mode_is_float(mode)) {
1138 if (ia32_cg_config.use_sse2)
1139 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1140 match_commutative | match_am);
1142 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1144 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1145 match_commutative | match_am | match_mode_neutral |
1146 match_immediate | match_am_and_immediates);
1150 * Creates an ia32 Mulh.
1151 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1152 * this result while Mul returns the lower 32 bit.
1154 * @return the created ia32 Mulh node
1156 static ir_node *gen_Mulh(ir_node *node)
1158 ir_node *block = get_nodes_block(node);
1159 ir_node *new_block = be_transform_node(block);
1160 dbg_info *dbgi = get_irn_dbg_info(node);
1161 ir_node *op1 = get_Mulh_left(node);
1162 ir_node *op2 = get_Mulh_right(node);
1163 ir_mode *mode = get_irn_mode(node);
1165 ir_node *proj_res_high;
1167 if (mode_is_signed(mode)) {
1168 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1169 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1170 mode_Iu, pn_ia32_IMul1OP_res_high);
1172 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1173 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1174 mode_Iu, pn_ia32_Mul_res_high);
1176 return proj_res_high;
1180 * Creates an ia32 And.
1182 * @return The created ia32 And node
1184 static ir_node *gen_And(ir_node *node)
1186 ir_node *op1 = get_And_left(node);
1187 ir_node *op2 = get_And_right(node);
1188 assert(! mode_is_float(get_irn_mode(node)));
1190 /* is it a zero extension? */
1191 if (is_Const(op2)) {
1192 tarval *tv = get_Const_tarval(op2);
1193 long v = get_tarval_long(tv);
1195 if (v == 0xFF || v == 0xFFFF) {
1196 dbg_info *dbgi = get_irn_dbg_info(node);
1197 ir_node *block = get_nodes_block(node);
1204 assert(v == 0xFFFF);
1207 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1212 return gen_binop(node, op1, op2, new_bd_ia32_And,
1213 match_commutative | match_mode_neutral | match_am | match_immediate);
1219 * Creates an ia32 Or.
1221 * @return The created ia32 Or node
1223 static ir_node *gen_Or(ir_node *node)
1225 ir_node *op1 = get_Or_left(node);
1226 ir_node *op2 = get_Or_right(node);
1228 assert (! mode_is_float(get_irn_mode(node)));
1229 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1230 | match_mode_neutral | match_am | match_immediate);
1236 * Creates an ia32 Eor.
1238 * @return The created ia32 Eor node
1240 static ir_node *gen_Eor(ir_node *node)
1242 ir_node *op1 = get_Eor_left(node);
1243 ir_node *op2 = get_Eor_right(node);
1245 assert(! mode_is_float(get_irn_mode(node)));
1246 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1247 | match_mode_neutral | match_am | match_immediate);
1252 * Creates an ia32 Sub.
1254 * @return The created ia32 Sub node
1256 static ir_node *gen_Sub(ir_node *node)
1258 ir_node *op1 = get_Sub_left(node);
1259 ir_node *op2 = get_Sub_right(node);
1260 ir_mode *mode = get_irn_mode(node);
1262 if (mode_is_float(mode)) {
1263 if (ia32_cg_config.use_sse2)
1264 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1266 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1269 if (is_Const(op2)) {
1270 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1274 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1275 | match_am | match_immediate);
1278 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1279 ir_node *const src_val,
1280 ir_node *const src_mem,
1281 ir_node *const am_mem)
1283 if (is_NoMem(am_mem)) {
1284 return be_transform_node(src_mem);
1285 } else if (is_Proj(src_val) &&
1287 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1288 /* avoid memory loop */
1290 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1291 ir_node *const ptr_pred = get_Proj_pred(src_val);
1292 int const arity = get_Sync_n_preds(src_mem);
1297 NEW_ARR_A(ir_node*, ins, arity + 1);
1299 /* NOTE: This sometimes produces dead-code because the old sync in
1300 * src_mem might not be used anymore, we should detect this case
1301 * and kill the sync... */
1302 for (i = arity - 1; i >= 0; --i) {
1303 ir_node *const pred = get_Sync_pred(src_mem, i);
1305 /* avoid memory loop */
1306 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1309 ins[n++] = be_transform_node(pred);
1314 return new_r_Sync(irg, block, n, ins);
1318 ins[0] = be_transform_node(src_mem);
1320 return new_r_Sync(irg, block, 2, ins);
1324 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1325 ir_node *val, const ir_node *orig)
1330 if (ia32_cg_config.use_short_sex_eax) {
1331 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1332 be_dep_on_frame(pval);
1333 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1335 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1336 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1338 SET_IA32_ORIG_NODE(res, orig);
1343 * Generates an ia32 DivMod with additional infrastructure for the
1344 * register allocator if needed.
1346 static ir_node *create_Div(ir_node *node)
1348 dbg_info *dbgi = get_irn_dbg_info(node);
1349 ir_node *block = get_nodes_block(node);
1350 ir_node *new_block = be_transform_node(block);
1357 ir_node *sign_extension;
1358 ia32_address_mode_t am;
1359 ia32_address_t *addr = &am.addr;
1361 /* the upper bits have random contents for smaller modes */
1362 switch (get_irn_opcode(node)) {
1364 op1 = get_Div_left(node);
1365 op2 = get_Div_right(node);
1366 mem = get_Div_mem(node);
1367 mode = get_Div_resmode(node);
1370 op1 = get_Mod_left(node);
1371 op2 = get_Mod_right(node);
1372 mem = get_Mod_mem(node);
1373 mode = get_Mod_resmode(node);
1376 op1 = get_DivMod_left(node);
1377 op2 = get_DivMod_right(node);
1378 mem = get_DivMod_mem(node);
1379 mode = get_DivMod_resmode(node);
1382 panic("invalid divmod node %+F", node);
1385 match_arguments(&am, block, op1, op2, NULL, match_am);
1387 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1388 is the memory of the consumed address. We can have only the second op as address
1389 in Div nodes, so check only op2. */
1390 new_mem = transform_AM_mem(current_ir_graph, block, op2, mem, addr->mem);
1392 if (mode_is_signed(mode)) {
1393 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1394 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1395 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1397 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0);
1398 be_dep_on_frame(sign_extension);
1400 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1401 addr->index, new_mem, am.new_op2,
1402 am.new_op1, sign_extension);
1405 set_irn_pinned(new_node, get_irn_pinned(node));
1407 set_am_attributes(new_node, &am);
1408 SET_IA32_ORIG_NODE(new_node, node);
1410 new_node = fix_mem_proj(new_node, &am);
1416 static ir_node *gen_Mod(ir_node *node)
1418 return create_Div(node);
1421 static ir_node *gen_Div(ir_node *node)
1423 return create_Div(node);
1426 static ir_node *gen_DivMod(ir_node *node)
1428 return create_Div(node);
1434 * Creates an ia32 floating Div.
1436 * @return The created ia32 xDiv node
1438 static ir_node *gen_Quot(ir_node *node)
1440 ir_node *op1 = get_Quot_left(node);
1441 ir_node *op2 = get_Quot_right(node);
1443 if (ia32_cg_config.use_sse2) {
1444 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1446 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1452 * Creates an ia32 Shl.
1454 * @return The created ia32 Shl node
1456 static ir_node *gen_Shl(ir_node *node)
1458 ir_node *left = get_Shl_left(node);
1459 ir_node *right = get_Shl_right(node);
1461 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1462 match_mode_neutral | match_immediate);
1466 * Creates an ia32 Shr.
1468 * @return The created ia32 Shr node
1470 static ir_node *gen_Shr(ir_node *node)
1472 ir_node *left = get_Shr_left(node);
1473 ir_node *right = get_Shr_right(node);
1475 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1481 * Creates an ia32 Sar.
1483 * @return The created ia32 Shrs node
1485 static ir_node *gen_Shrs(ir_node *node)
1487 ir_node *left = get_Shrs_left(node);
1488 ir_node *right = get_Shrs_right(node);
1489 ir_mode *mode = get_irn_mode(node);
1491 if (is_Const(right) && mode == mode_Is) {
1492 tarval *tv = get_Const_tarval(right);
1493 long val = get_tarval_long(tv);
1495 /* this is a sign extension */
1496 dbg_info *dbgi = get_irn_dbg_info(node);
1497 ir_node *block = be_transform_node(get_nodes_block(node));
1498 ir_node *new_op = be_transform_node(left);
1500 return create_sex_32_64(dbgi, block, new_op, node);
1504 /* 8 or 16 bit sign extension? */
1505 if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1506 ir_node *shl_left = get_Shl_left(left);
1507 ir_node *shl_right = get_Shl_right(left);
1508 if (is_Const(shl_right)) {
1509 tarval *tv1 = get_Const_tarval(right);
1510 tarval *tv2 = get_Const_tarval(shl_right);
1511 if (tv1 == tv2 && tarval_is_long(tv1)) {
1512 long val = get_tarval_long(tv1);
1513 if (val == 16 || val == 24) {
1514 dbg_info *dbgi = get_irn_dbg_info(node);
1515 ir_node *block = get_nodes_block(node);
1525 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1534 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1540 * Creates an ia32 Rol.
1542 * @param op1 The first operator
1543 * @param op2 The second operator
1544 * @return The created ia32 RotL node
1546 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1548 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1554 * Creates an ia32 Ror.
1555 * NOTE: There is no RotR with immediate because this would always be a RotL
1556 * "imm-mode_size_bits" which can be pre-calculated.
1558 * @param op1 The first operator
1559 * @param op2 The second operator
1560 * @return The created ia32 RotR node
1562 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1564 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1570 * Creates an ia32 RotR or RotL (depending on the found pattern).
1572 * @return The created ia32 RotL or RotR node
1574 static ir_node *gen_Rotl(ir_node *node)
1576 ir_node *rotate = NULL;
1577 ir_node *op1 = get_Rotl_left(node);
1578 ir_node *op2 = get_Rotl_right(node);
1580 /* Firm has only RotL, so we are looking for a right (op2)
1581 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1582 that means we can create a RotR instead of an Add and a RotL */
1586 ir_node *left = get_Add_left(add);
1587 ir_node *right = get_Add_right(add);
1588 if (is_Const(right)) {
1589 tarval *tv = get_Const_tarval(right);
1590 ir_mode *mode = get_irn_mode(node);
1591 long bits = get_mode_size_bits(mode);
1593 if (is_Minus(left) &&
1594 tarval_is_long(tv) &&
1595 get_tarval_long(tv) == bits &&
1598 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1599 rotate = gen_Ror(node, op1, get_Minus_op(left));
1604 if (rotate == NULL) {
1605 rotate = gen_Rol(node, op1, op2);
1614 * Transforms a Minus node.
1616 * @return The created ia32 Minus node
1618 static ir_node *gen_Minus(ir_node *node)
1620 ir_node *op = get_Minus_op(node);
1621 ir_node *block = be_transform_node(get_nodes_block(node));
1622 dbg_info *dbgi = get_irn_dbg_info(node);
1623 ir_mode *mode = get_irn_mode(node);
1628 if (mode_is_float(mode)) {
1629 ir_node *new_op = be_transform_node(op);
1630 if (ia32_cg_config.use_sse2) {
1631 /* TODO: non-optimal... if we have many xXors, then we should
1632 * rather create a load for the const and use that instead of
1633 * several AM nodes... */
1634 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1635 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1636 ir_node *nomem = new_NoMem();
1638 new_node = new_bd_ia32_xXor(dbgi, block, noreg_gp, noreg_gp,
1639 nomem, new_op, noreg_xmm);
1641 size = get_mode_size_bits(mode);
1642 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1644 set_ia32_am_sc(new_node, ent);
1645 set_ia32_op_type(new_node, ia32_AddrModeS);
1646 set_ia32_ls_mode(new_node, mode);
1648 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1651 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1654 SET_IA32_ORIG_NODE(new_node, node);
1660 * Transforms a Not node.
1662 * @return The created ia32 Not node
1664 static ir_node *gen_Not(ir_node *node)
1666 ir_node *op = get_Not_op(node);
1668 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1669 assert (! mode_is_float(get_irn_mode(node)));
1671 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1677 * Transforms an Abs node.
1679 * @return The created ia32 Abs node
1681 static ir_node *gen_Abs(ir_node *node)
1683 ir_node *block = get_nodes_block(node);
1684 ir_node *new_block = be_transform_node(block);
1685 ir_node *op = get_Abs_op(node);
1686 dbg_info *dbgi = get_irn_dbg_info(node);
1687 ir_mode *mode = get_irn_mode(node);
1688 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1689 ir_node *nomem = new_NoMem();
1695 if (mode_is_float(mode)) {
1696 new_op = be_transform_node(op);
1698 if (ia32_cg_config.use_sse2) {
1699 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1700 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_gp, noreg_gp,
1701 nomem, new_op, noreg_fp);
1703 size = get_mode_size_bits(mode);
1704 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1706 set_ia32_am_sc(new_node, ent);
1708 SET_IA32_ORIG_NODE(new_node, node);
1710 set_ia32_op_type(new_node, ia32_AddrModeS);
1711 set_ia32_ls_mode(new_node, mode);
1713 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1714 SET_IA32_ORIG_NODE(new_node, node);
1717 ir_node *xor, *sign_extension;
1719 if (get_mode_size_bits(mode) == 32) {
1720 new_op = be_transform_node(op);
1722 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1725 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1727 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_gp, noreg_gp,
1728 nomem, new_op, sign_extension);
1729 SET_IA32_ORIG_NODE(xor, node);
1731 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_gp, noreg_gp,
1732 nomem, xor, sign_extension);
1733 SET_IA32_ORIG_NODE(new_node, node);
1740 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1742 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1744 dbg_info *dbgi = get_irn_dbg_info(cmp);
1745 ir_node *block = get_nodes_block(cmp);
1746 ir_node *new_block = be_transform_node(block);
1747 ir_node *op1 = be_transform_node(x);
1748 ir_node *op2 = be_transform_node(n);
1750 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1754 * Transform a node returning a "flag" result.
1756 * @param node the node to transform
1757 * @param pnc_out the compare mode to use
1759 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1768 /* we have a Cmp as input */
1769 if (is_Proj(node)) {
1770 ir_node *pred = get_Proj_pred(node);
1772 pn_Cmp pnc = get_Proj_proj(node);
1773 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1774 ir_node *l = get_Cmp_left(pred);
1775 ir_node *r = get_Cmp_right(pred);
1777 ir_node *la = get_And_left(l);
1778 ir_node *ra = get_And_right(l);
1780 ir_node *c = get_Shl_left(la);
1781 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1782 /* (1 << n) & ra) */
1783 ir_node *n = get_Shl_right(la);
1784 flags = gen_bt(pred, ra, n);
1785 /* we must generate a Jc/Jnc jump */
1786 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1789 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1794 ir_node *c = get_Shl_left(ra);
1795 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1796 /* la & (1 << n)) */
1797 ir_node *n = get_Shl_right(ra);
1798 flags = gen_bt(pred, la, n);
1799 /* we must generate a Jc/Jnc jump */
1800 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1803 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1809 flags = be_transform_node(pred);
1815 /* a mode_b value, we have to compare it against 0 */
1816 dbgi = get_irn_dbg_info(node);
1817 new_block = be_transform_node(get_nodes_block(node));
1818 new_op = be_transform_node(node);
1819 noreg = ia32_new_NoReg_gp(env_cg);
1820 nomem = new_NoMem();
1821 flags = new_bd_ia32_Test(dbgi, new_block, noreg, noreg, nomem, new_op,
1822 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1823 *pnc_out = pn_Cmp_Lg;
1828 * Transforms a Load.
1830 * @return the created ia32 Load node
1832 static ir_node *gen_Load(ir_node *node)
1834 ir_node *old_block = get_nodes_block(node);
1835 ir_node *block = be_transform_node(old_block);
1836 ir_node *ptr = get_Load_ptr(node);
1837 ir_node *mem = get_Load_mem(node);
1838 ir_node *new_mem = be_transform_node(mem);
1841 dbg_info *dbgi = get_irn_dbg_info(node);
1842 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1843 ir_mode *mode = get_Load_mode(node);
1846 ia32_address_t addr;
1848 /* construct load address */
1849 memset(&addr, 0, sizeof(addr));
1850 ia32_create_address_mode(&addr, ptr, 0);
1857 base = be_transform_node(base);
1860 if (index == NULL) {
1863 index = be_transform_node(index);
1866 if (mode_is_float(mode)) {
1867 if (ia32_cg_config.use_sse2) {
1868 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1870 res_mode = mode_xmm;
1872 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1874 res_mode = mode_vfp;
1877 assert(mode != mode_b);
1879 /* create a conv node with address mode for smaller modes */
1880 if (get_mode_size_bits(mode) < 32) {
1881 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1882 new_mem, noreg, mode);
1884 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1889 set_irn_pinned(new_node, get_irn_pinned(node));
1890 set_ia32_op_type(new_node, ia32_AddrModeS);
1891 set_ia32_ls_mode(new_node, mode);
1892 set_address(new_node, &addr);
1894 if (get_irn_pinned(node) == op_pin_state_floats) {
1895 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1896 && pn_ia32_vfld_res == pn_ia32_Load_res
1897 && pn_ia32_Load_res == pn_ia32_res);
1898 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1901 SET_IA32_ORIG_NODE(new_node, node);
1903 be_dep_on_frame(new_node);
1907 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1908 ir_node *ptr, ir_node *other)
1915 /* we only use address mode if we're the only user of the load */
1916 if (get_irn_n_edges(node) > 1)
1919 load = get_Proj_pred(node);
1922 if (get_nodes_block(load) != block)
1925 /* store should have the same pointer as the load */
1926 if (get_Load_ptr(load) != ptr)
1929 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1930 if (other != NULL &&
1931 get_nodes_block(other) == block &&
1932 heights_reachable_in_block(heights, other, load)) {
1936 if (prevents_AM(block, load, mem))
1938 /* Store should be attached to the load via mem */
1939 assert(heights_reachable_in_block(heights, mem, load));
1944 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1945 ir_node *mem, ir_node *ptr, ir_mode *mode,
1946 construct_binop_dest_func *func,
1947 construct_binop_dest_func *func8bit,
1948 match_flags_t flags)
1950 ir_node *src_block = get_nodes_block(node);
1952 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1959 ia32_address_mode_t am;
1960 ia32_address_t *addr = &am.addr;
1961 memset(&am, 0, sizeof(am));
1963 assert(flags & match_immediate); /* there is no destam node without... */
1964 commutative = (flags & match_commutative) != 0;
1966 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1967 build_address(&am, op1, ia32_create_am_double_use);
1968 new_op = create_immediate_or_transform(op2, 0);
1969 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1970 build_address(&am, op2, ia32_create_am_double_use);
1971 new_op = create_immediate_or_transform(op1, 0);
1976 if (addr->base == NULL)
1977 addr->base = noreg_gp;
1978 if (addr->index == NULL)
1979 addr->index = noreg_gp;
1980 if (addr->mem == NULL)
1981 addr->mem = new_NoMem();
1983 dbgi = get_irn_dbg_info(node);
1984 block = be_transform_node(src_block);
1985 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
1987 if (get_mode_size_bits(mode) == 8) {
1988 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
1990 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
1992 set_address(new_node, addr);
1993 set_ia32_op_type(new_node, ia32_AddrModeD);
1994 set_ia32_ls_mode(new_node, mode);
1995 SET_IA32_ORIG_NODE(new_node, node);
1997 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
1998 mem_proj = be_transform_node(am.mem_proj);
1999 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2004 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2005 ir_node *ptr, ir_mode *mode,
2006 construct_unop_dest_func *func)
2008 ir_node *src_block = get_nodes_block(node);
2014 ia32_address_mode_t am;
2015 ia32_address_t *addr = &am.addr;
2017 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2020 memset(&am, 0, sizeof(am));
2021 build_address(&am, op, ia32_create_am_double_use);
2023 dbgi = get_irn_dbg_info(node);
2024 block = be_transform_node(src_block);
2025 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2026 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2027 set_address(new_node, addr);
2028 set_ia32_op_type(new_node, ia32_AddrModeD);
2029 set_ia32_ls_mode(new_node, mode);
2030 SET_IA32_ORIG_NODE(new_node, node);
2032 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2033 mem_proj = be_transform_node(am.mem_proj);
2034 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2039 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2041 ir_mode *mode = get_irn_mode(node);
2042 ir_node *mux_true = get_Mux_true(node);
2043 ir_node *mux_false = get_Mux_false(node);
2053 ia32_address_t addr;
2055 if (get_mode_size_bits(mode) != 8)
2058 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2060 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2066 build_address_ptr(&addr, ptr, mem);
2068 dbgi = get_irn_dbg_info(node);
2069 block = get_nodes_block(node);
2070 new_block = be_transform_node(block);
2071 cond = get_Mux_sel(node);
2072 flags = get_flags_node(cond, &pnc);
2073 new_mem = be_transform_node(mem);
2074 new_node = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2075 addr.index, addr.mem, flags, pnc, negated);
2076 set_address(new_node, &addr);
2077 set_ia32_op_type(new_node, ia32_AddrModeD);
2078 set_ia32_ls_mode(new_node, mode);
2079 SET_IA32_ORIG_NODE(new_node, node);
2084 static ir_node *try_create_dest_am(ir_node *node)
2086 ir_node *val = get_Store_value(node);
2087 ir_node *mem = get_Store_mem(node);
2088 ir_node *ptr = get_Store_ptr(node);
2089 ir_mode *mode = get_irn_mode(val);
2090 unsigned bits = get_mode_size_bits(mode);
2095 /* handle only GP modes for now... */
2096 if (!ia32_mode_needs_gp_reg(mode))
2100 /* store must be the only user of the val node */
2101 if (get_irn_n_edges(val) > 1)
2103 /* skip pointless convs */
2105 ir_node *conv_op = get_Conv_op(val);
2106 ir_mode *pred_mode = get_irn_mode(conv_op);
2107 if (!ia32_mode_needs_gp_reg(pred_mode))
2109 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2117 /* value must be in the same block */
2118 if (get_nodes_block(node) != get_nodes_block(val))
2121 switch (get_irn_opcode(val)) {
2123 op1 = get_Add_left(val);
2124 op2 = get_Add_right(val);
2125 if (ia32_cg_config.use_incdec) {
2126 if (is_Const_1(op2)) {
2127 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2129 } else if (is_Const_Minus_1(op2)) {
2130 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2134 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2135 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2136 match_commutative | match_immediate);
2139 op1 = get_Sub_left(val);
2140 op2 = get_Sub_right(val);
2141 if (is_Const(op2)) {
2142 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2144 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2145 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2149 op1 = get_And_left(val);
2150 op2 = get_And_right(val);
2151 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2152 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2153 match_commutative | match_immediate);
2156 op1 = get_Or_left(val);
2157 op2 = get_Or_right(val);
2158 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2159 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2160 match_commutative | match_immediate);
2163 op1 = get_Eor_left(val);
2164 op2 = get_Eor_right(val);
2165 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2166 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2167 match_commutative | match_immediate);
2170 op1 = get_Shl_left(val);
2171 op2 = get_Shl_right(val);
2172 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2173 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2177 op1 = get_Shr_left(val);
2178 op2 = get_Shr_right(val);
2179 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2180 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2184 op1 = get_Shrs_left(val);
2185 op2 = get_Shrs_right(val);
2186 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2187 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2191 op1 = get_Rotl_left(val);
2192 op2 = get_Rotl_right(val);
2193 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2194 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2197 /* TODO: match ROR patterns... */
2199 new_node = try_create_SetMem(val, ptr, mem);
2202 op1 = get_Minus_op(val);
2203 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2206 /* should be lowered already */
2207 assert(mode != mode_b);
2208 op1 = get_Not_op(val);
2209 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2215 if (new_node != NULL) {
2216 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2217 get_irn_pinned(node) == op_pin_state_pinned) {
2218 set_irn_pinned(new_node, op_pin_state_pinned);
2225 static bool possible_int_mode_for_fp(ir_mode *mode)
2229 if (!mode_is_signed(mode))
2231 size = get_mode_size_bits(mode);
2232 if (size != 16 && size != 32)
2237 static int is_float_to_int_conv(const ir_node *node)
2239 ir_mode *mode = get_irn_mode(node);
2243 if (!possible_int_mode_for_fp(mode))
2248 conv_op = get_Conv_op(node);
2249 conv_mode = get_irn_mode(conv_op);
2251 if (!mode_is_float(conv_mode))
2258 * Transform a Store(floatConst) into a sequence of
2261 * @return the created ia32 Store node
2263 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2265 ir_mode *mode = get_irn_mode(cns);
2266 unsigned size = get_mode_size_bytes(mode);
2267 tarval *tv = get_Const_tarval(cns);
2268 ir_node *block = get_nodes_block(node);
2269 ir_node *new_block = be_transform_node(block);
2270 ir_node *ptr = get_Store_ptr(node);
2271 ir_node *mem = get_Store_mem(node);
2272 dbg_info *dbgi = get_irn_dbg_info(node);
2276 ia32_address_t addr;
2278 assert(size % 4 == 0);
2281 build_address_ptr(&addr, ptr, mem);
2285 get_tarval_sub_bits(tv, ofs) |
2286 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2287 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2288 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2289 ir_node *imm = create_Immediate(NULL, 0, val);
2291 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2292 addr.index, addr.mem, imm);
2294 set_irn_pinned(new_node, get_irn_pinned(node));
2295 set_ia32_op_type(new_node, ia32_AddrModeD);
2296 set_ia32_ls_mode(new_node, mode_Iu);
2297 set_address(new_node, &addr);
2298 SET_IA32_ORIG_NODE(new_node, node);
2301 ins[i++] = new_node;
2306 } while (size != 0);
2309 return new_rd_Sync(dbgi, current_ir_graph, new_block, i, ins);
2316 * Generate a vfist or vfisttp instruction.
2318 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2319 ir_node *mem, ir_node *val, ir_node **fist)
2323 if (ia32_cg_config.use_fisttp) {
2324 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2325 if other users exists */
2326 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2327 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2328 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2329 be_new_Keep(reg_class, irg, block, 1, &value);
2331 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2334 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2337 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2343 * Transforms a general (no special case) Store.
2345 * @return the created ia32 Store node
2347 static ir_node *gen_general_Store(ir_node *node)
2349 ir_node *val = get_Store_value(node);
2350 ir_mode *mode = get_irn_mode(val);
2351 ir_node *block = get_nodes_block(node);
2352 ir_node *new_block = be_transform_node(block);
2353 ir_node *ptr = get_Store_ptr(node);
2354 ir_node *mem = get_Store_mem(node);
2355 dbg_info *dbgi = get_irn_dbg_info(node);
2356 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2357 ir_node *new_val, *new_node, *store;
2358 ia32_address_t addr;
2360 /* check for destination address mode */
2361 new_node = try_create_dest_am(node);
2362 if (new_node != NULL)
2365 /* construct store address */
2366 memset(&addr, 0, sizeof(addr));
2367 ia32_create_address_mode(&addr, ptr, 0);
2369 if (addr.base == NULL) {
2372 addr.base = be_transform_node(addr.base);
2375 if (addr.index == NULL) {
2378 addr.index = be_transform_node(addr.index);
2380 addr.mem = be_transform_node(mem);
2382 if (mode_is_float(mode)) {
2383 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2385 while (is_Conv(val) && mode == get_irn_mode(val)) {
2386 ir_node *op = get_Conv_op(val);
2387 if (!mode_is_float(get_irn_mode(op)))
2391 new_val = be_transform_node(val);
2392 if (ia32_cg_config.use_sse2) {
2393 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2394 addr.index, addr.mem, new_val);
2396 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2397 addr.index, addr.mem, new_val, mode);
2400 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2401 val = get_Conv_op(val);
2403 /* TODO: is this optimisation still necessary at all (middleend)? */
2404 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2405 while (is_Conv(val)) {
2406 ir_node *op = get_Conv_op(val);
2407 if (!mode_is_float(get_irn_mode(op)))
2409 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2413 new_val = be_transform_node(val);
2414 new_node = gen_vfist(dbgi, current_ir_graph, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2416 new_val = create_immediate_or_transform(val, 0);
2417 assert(mode != mode_b);
2419 if (get_mode_size_bits(mode) == 8) {
2420 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2421 addr.index, addr.mem, new_val);
2423 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2424 addr.index, addr.mem, new_val);
2429 set_irn_pinned(store, get_irn_pinned(node));
2430 set_ia32_op_type(store, ia32_AddrModeD);
2431 set_ia32_ls_mode(store, mode);
2433 set_address(store, &addr);
2434 SET_IA32_ORIG_NODE(store, node);
2440 * Transforms a Store.
2442 * @return the created ia32 Store node
2444 static ir_node *gen_Store(ir_node *node)
2446 ir_node *val = get_Store_value(node);
2447 ir_mode *mode = get_irn_mode(val);
2449 if (mode_is_float(mode) && is_Const(val)) {
2450 /* We can transform every floating const store
2451 into a sequence of integer stores.
2452 If the constant is already in a register,
2453 it would be better to use it, but we don't
2454 have this information here. */
2455 return gen_float_const_Store(node, val);
2457 return gen_general_Store(node);
2461 * Transforms a Switch.
2463 * @return the created ia32 SwitchJmp node
2465 static ir_node *create_Switch(ir_node *node)
2467 dbg_info *dbgi = get_irn_dbg_info(node);
2468 ir_node *block = be_transform_node(get_nodes_block(node));
2469 ir_node *sel = get_Cond_selector(node);
2470 ir_node *new_sel = be_transform_node(sel);
2471 int switch_min = INT_MAX;
2472 int switch_max = INT_MIN;
2473 long default_pn = get_Cond_defaultProj(node);
2475 const ir_edge_t *edge;
2477 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2479 /* determine the smallest switch case value */
2480 foreach_out_edge(node, edge) {
2481 ir_node *proj = get_edge_src_irn(edge);
2482 long pn = get_Proj_proj(proj);
2483 if (pn == default_pn)
2486 if (pn < switch_min)
2488 if (pn > switch_max)
2492 if ((unsigned) (switch_max - switch_min) > 256000) {
2493 panic("Size of switch %+F bigger than 256000", node);
2496 if (switch_min != 0) {
2497 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2499 /* if smallest switch case is not 0 we need an additional sub */
2500 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg);
2501 add_ia32_am_offs_int(new_sel, -switch_min);
2502 set_ia32_op_type(new_sel, ia32_AddrModeS);
2504 SET_IA32_ORIG_NODE(new_sel, node);
2507 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2508 SET_IA32_ORIG_NODE(new_node, node);
2514 * Transform a Cond node.
2516 static ir_node *gen_Cond(ir_node *node)
2518 ir_node *block = get_nodes_block(node);
2519 ir_node *new_block = be_transform_node(block);
2520 dbg_info *dbgi = get_irn_dbg_info(node);
2521 ir_node *sel = get_Cond_selector(node);
2522 ir_mode *sel_mode = get_irn_mode(sel);
2523 ir_node *flags = NULL;
2527 if (sel_mode != mode_b) {
2528 return create_Switch(node);
2531 /* we get flags from a Cmp */
2532 flags = get_flags_node(sel, &pnc);
2534 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2535 SET_IA32_ORIG_NODE(new_node, node);
2540 static ir_node *gen_be_Copy(ir_node *node)
2542 ir_node *new_node = be_duplicate_node(node);
2543 ir_mode *mode = get_irn_mode(new_node);
2545 if (ia32_mode_needs_gp_reg(mode)) {
2546 set_irn_mode(new_node, mode_Iu);
2552 static ir_node *create_Fucom(ir_node *node)
2554 dbg_info *dbgi = get_irn_dbg_info(node);
2555 ir_node *block = get_nodes_block(node);
2556 ir_node *new_block = be_transform_node(block);
2557 ir_node *left = get_Cmp_left(node);
2558 ir_node *new_left = be_transform_node(left);
2559 ir_node *right = get_Cmp_right(node);
2563 if (ia32_cg_config.use_fucomi) {
2564 new_right = be_transform_node(right);
2565 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2567 set_ia32_commutative(new_node);
2568 SET_IA32_ORIG_NODE(new_node, node);
2570 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2571 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2573 new_right = be_transform_node(right);
2574 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2577 set_ia32_commutative(new_node);
2579 SET_IA32_ORIG_NODE(new_node, node);
2581 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2582 SET_IA32_ORIG_NODE(new_node, node);
2588 static ir_node *create_Ucomi(ir_node *node)
2590 dbg_info *dbgi = get_irn_dbg_info(node);
2591 ir_node *src_block = get_nodes_block(node);
2592 ir_node *new_block = be_transform_node(src_block);
2593 ir_node *left = get_Cmp_left(node);
2594 ir_node *right = get_Cmp_right(node);
2596 ia32_address_mode_t am;
2597 ia32_address_t *addr = &am.addr;
2599 match_arguments(&am, src_block, left, right, NULL,
2600 match_commutative | match_am);
2602 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2603 addr->mem, am.new_op1, am.new_op2,
2605 set_am_attributes(new_node, &am);
2607 SET_IA32_ORIG_NODE(new_node, node);
2609 new_node = fix_mem_proj(new_node, &am);
2615 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2616 * to fold an and into a test node
2618 static bool can_fold_test_and(ir_node *node)
2620 const ir_edge_t *edge;
2622 /** we can only have eq and lg projs */
2623 foreach_out_edge(node, edge) {
2624 ir_node *proj = get_edge_src_irn(edge);
2625 pn_Cmp pnc = get_Proj_proj(proj);
2626 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2634 * returns true if it is assured, that the upper bits of a node are "clean"
2635 * which means for a 16 or 8 bit value, that the upper bits in the register
2636 * are 0 for unsigned and a copy of the last significant bit for signed
2639 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2641 assert(ia32_mode_needs_gp_reg(mode));
2642 if (get_mode_size_bits(mode) >= 32)
2645 if (is_Proj(transformed_node))
2646 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2648 switch (get_ia32_irn_opcode(transformed_node)) {
2649 case iro_ia32_Conv_I2I:
2650 case iro_ia32_Conv_I2I8Bit: {
2651 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2652 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2654 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2661 if (mode_is_signed(mode)) {
2662 return false; /* TODO handle signed modes */
2664 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2665 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2666 const ia32_immediate_attr_t *attr
2667 = get_ia32_immediate_attr_const(right);
2668 if (attr->symconst == 0 &&
2669 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2673 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2677 /* TODO too conservative if shift amount is constant */
2678 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2681 if (!mode_is_signed(mode)) {
2683 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2684 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2686 /* TODO if one is known to be zero extended, then || is sufficient */
2691 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2692 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2694 case iro_ia32_Const:
2695 case iro_ia32_Immediate: {
2696 const ia32_immediate_attr_t *attr =
2697 get_ia32_immediate_attr_const(transformed_node);
2698 if (mode_is_signed(mode)) {
2699 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2700 return shifted == 0 || shifted == -1;
2702 unsigned long shifted = (unsigned long)attr->offset;
2703 shifted >>= get_mode_size_bits(mode);
2704 return shifted == 0;
2714 * Generate code for a Cmp.
2716 static ir_node *gen_Cmp(ir_node *node)
2718 dbg_info *dbgi = get_irn_dbg_info(node);
2719 ir_node *block = get_nodes_block(node);
2720 ir_node *new_block = be_transform_node(block);
2721 ir_node *left = get_Cmp_left(node);
2722 ir_node *right = get_Cmp_right(node);
2723 ir_mode *cmp_mode = get_irn_mode(left);
2725 ia32_address_mode_t am;
2726 ia32_address_t *addr = &am.addr;
2729 if (mode_is_float(cmp_mode)) {
2730 if (ia32_cg_config.use_sse2) {
2731 return create_Ucomi(node);
2733 return create_Fucom(node);
2737 assert(ia32_mode_needs_gp_reg(cmp_mode));
2739 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2740 cmp_unsigned = !mode_is_signed(cmp_mode);
2741 if (is_Const_0(right) &&
2743 get_irn_n_edges(left) == 1 &&
2744 can_fold_test_and(node)) {
2745 /* Test(and_left, and_right) */
2746 ir_node *and_left = get_And_left(left);
2747 ir_node *and_right = get_And_right(left);
2749 /* matze: code here used mode instead of cmd_mode, I think it is always
2750 * the same as cmp_mode, but I leave this here to see if this is really
2753 assert(get_irn_mode(and_left) == cmp_mode);
2755 match_arguments(&am, block, and_left, and_right, NULL,
2757 match_am | match_8bit_am | match_16bit_am |
2758 match_am_and_immediates | match_immediate);
2760 /* use 32bit compare mode if possible since the opcode is smaller */
2761 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2762 upper_bits_clean(am.new_op2, cmp_mode)) {
2763 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2766 if (get_mode_size_bits(cmp_mode) == 8) {
2767 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2768 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2771 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2772 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2775 /* Cmp(left, right) */
2776 match_arguments(&am, block, left, right, NULL,
2777 match_commutative | match_am | match_8bit_am |
2778 match_16bit_am | match_am_and_immediates |
2780 /* use 32bit compare mode if possible since the opcode is smaller */
2781 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2782 upper_bits_clean(am.new_op2, cmp_mode)) {
2783 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2786 if (get_mode_size_bits(cmp_mode) == 8) {
2787 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2788 addr->index, addr->mem, am.new_op1,
2789 am.new_op2, am.ins_permuted,
2792 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2793 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2796 set_am_attributes(new_node, &am);
2797 set_ia32_ls_mode(new_node, cmp_mode);
2799 SET_IA32_ORIG_NODE(new_node, node);
2801 new_node = fix_mem_proj(new_node, &am);
2806 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2809 dbg_info *dbgi = get_irn_dbg_info(node);
2810 ir_node *block = get_nodes_block(node);
2811 ir_node *new_block = be_transform_node(block);
2812 ir_node *val_true = get_Mux_true(node);
2813 ir_node *val_false = get_Mux_false(node);
2815 ia32_address_mode_t am;
2816 ia32_address_t *addr;
2818 assert(ia32_cg_config.use_cmov);
2819 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2823 match_arguments(&am, block, val_false, val_true, flags,
2824 match_commutative | match_am | match_16bit_am | match_mode_neutral);
2826 new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2827 addr->mem, am.new_op1, am.new_op2, new_flags,
2828 am.ins_permuted, pnc);
2829 set_am_attributes(new_node, &am);
2831 SET_IA32_ORIG_NODE(new_node, node);
2833 new_node = fix_mem_proj(new_node, &am);
2839 * Creates a ia32 Setcc instruction.
2841 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2842 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2845 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2846 ir_node *nomem = new_NoMem();
2847 ir_mode *mode = get_irn_mode(orig_node);
2850 new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2851 SET_IA32_ORIG_NODE(new_node, orig_node);
2853 /* we might need to conv the result up */
2854 if (get_mode_size_bits(mode) > 8) {
2855 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg, noreg,
2856 nomem, new_node, mode_Bu);
2857 SET_IA32_ORIG_NODE(new_node, orig_node);
2864 * Create instruction for an unsigned Difference or Zero.
2866 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2868 ir_graph *irg = current_ir_graph;
2869 ir_mode *mode = get_irn_mode(psi);
2870 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2873 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2874 match_mode_neutral | match_am | match_immediate | match_two_users);
2876 block = get_nodes_block(new_node);
2878 if (is_Proj(new_node)) {
2879 sub = get_Proj_pred(new_node);
2880 assert(is_ia32_Sub(sub));
2883 set_irn_mode(sub, mode_T);
2884 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2886 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2888 dbgi = get_irn_dbg_info(psi);
2889 noreg = ia32_new_NoReg_gp(env_cg);
2890 tmpreg = new_bd_ia32_ProduceVal(dbgi, block);
2891 nomem = new_NoMem();
2892 sbb = new_bd_ia32_Sbb(dbgi, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2894 new_node = new_bd_ia32_And(dbgi, block, noreg, noreg, nomem, new_node, sbb);
2895 set_ia32_commutative(new_node);
2900 * Transforms a Mux node into CMov.
2902 * @return The transformed node.
2904 static ir_node *gen_Mux(ir_node *node)
2906 dbg_info *dbgi = get_irn_dbg_info(node);
2907 ir_node *block = get_nodes_block(node);
2908 ir_node *new_block = be_transform_node(block);
2909 ir_node *mux_true = get_Mux_true(node);
2910 ir_node *mux_false = get_Mux_false(node);
2911 ir_node *cond = get_Mux_sel(node);
2912 ir_mode *mode = get_irn_mode(node);
2915 assert(get_irn_mode(cond) == mode_b);
2917 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2918 if (mode_is_float(mode)) {
2919 ir_node *cmp = get_Proj_pred(cond);
2920 ir_node *cmp_left = get_Cmp_left(cmp);
2921 ir_node *cmp_right = get_Cmp_right(cmp);
2922 pn_Cmp pnc = get_Proj_proj(cond);
2924 if (ia32_cg_config.use_sse2) {
2925 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2926 if (cmp_left == mux_true && cmp_right == mux_false) {
2927 /* Mux(a <= b, a, b) => MIN */
2928 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2929 match_commutative | match_am | match_two_users);
2930 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2931 /* Mux(a <= b, b, a) => MAX */
2932 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2933 match_commutative | match_am | match_two_users);
2935 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2936 if (cmp_left == mux_true && cmp_right == mux_false) {
2937 /* Mux(a >= b, a, b) => MAX */
2938 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2939 match_commutative | match_am | match_two_users);
2940 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2941 /* Mux(a >= b, b, a) => MIN */
2942 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2943 match_commutative | match_am | match_two_users);
2947 panic("cannot transform floating point Mux");
2953 assert(ia32_mode_needs_gp_reg(mode));
2955 if (is_Proj(cond)) {
2956 ir_node *cmp = get_Proj_pred(cond);
2958 ir_node *cmp_left = get_Cmp_left(cmp);
2959 ir_node *cmp_right = get_Cmp_right(cmp);
2960 pn_Cmp pnc = get_Proj_proj(cond);
2962 /* check for unsigned Doz first */
2963 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2964 is_Const_0(mux_false) && is_Sub(mux_true) &&
2965 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2966 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2967 return create_Doz(node, cmp_left, cmp_right);
2968 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2969 is_Const_0(mux_true) && is_Sub(mux_false) &&
2970 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2971 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2972 return create_Doz(node, cmp_left, cmp_right);
2977 flags = get_flags_node(cond, &pnc);
2979 if (is_Const(mux_true) && is_Const(mux_false)) {
2980 /* both are const, good */
2981 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2982 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2983 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2984 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2986 /* Not that simple. */
2991 new_node = create_CMov(node, cond, flags, pnc);
2999 * Create a conversion from x87 state register to general purpose.
3001 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3003 ir_node *block = be_transform_node(get_nodes_block(node));
3004 ir_node *op = get_Conv_op(node);
3005 ir_node *new_op = be_transform_node(op);
3006 ia32_code_gen_t *cg = env_cg;
3007 ir_graph *irg = current_ir_graph;
3008 dbg_info *dbgi = get_irn_dbg_info(node);
3009 ir_node *noreg = ia32_new_NoReg_gp(cg);
3010 ir_mode *mode = get_irn_mode(node);
3011 ir_node *fist, *load, *mem;
3013 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3014 set_irn_pinned(fist, op_pin_state_floats);
3015 set_ia32_use_frame(fist);
3016 set_ia32_op_type(fist, ia32_AddrModeD);
3018 assert(get_mode_size_bits(mode) <= 32);
3019 /* exception we can only store signed 32 bit integers, so for unsigned
3020 we store a 64bit (signed) integer and load the lower bits */
3021 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3022 set_ia32_ls_mode(fist, mode_Ls);
3024 set_ia32_ls_mode(fist, mode_Is);
3026 SET_IA32_ORIG_NODE(fist, node);
3029 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg, mem);
3031 set_irn_pinned(load, op_pin_state_floats);
3032 set_ia32_use_frame(load);
3033 set_ia32_op_type(load, ia32_AddrModeS);
3034 set_ia32_ls_mode(load, mode_Is);
3035 if (get_ia32_ls_mode(fist) == mode_Ls) {
3036 ia32_attr_t *attr = get_ia32_attr(load);
3037 attr->data.need_64bit_stackent = 1;
3039 ia32_attr_t *attr = get_ia32_attr(load);
3040 attr->data.need_32bit_stackent = 1;
3042 SET_IA32_ORIG_NODE(load, node);
3044 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3048 * Creates a x87 strict Conv by placing a Store and a Load
3050 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3052 ir_node *block = get_nodes_block(node);
3053 ir_graph *irg = current_ir_graph;
3054 dbg_info *dbgi = get_irn_dbg_info(node);
3055 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3056 ir_node *nomem = new_NoMem();
3057 ir_node *frame = get_irg_frame(irg);
3058 ir_node *store, *load;
3061 store = new_bd_ia32_vfst(dbgi, block, frame, noreg, nomem, node, tgt_mode);
3062 set_ia32_use_frame(store);
3063 set_ia32_op_type(store, ia32_AddrModeD);
3064 SET_IA32_ORIG_NODE(store, node);
3066 load = new_bd_ia32_vfld(dbgi, block, frame, noreg, store, tgt_mode);
3067 set_ia32_use_frame(load);
3068 set_ia32_op_type(load, ia32_AddrModeS);
3069 SET_IA32_ORIG_NODE(load, node);
3071 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3075 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3076 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3078 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3080 func = get_mode_size_bits(mode) == 8 ?
3081 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3082 return func(dbgi, block, base, index, mem, val, mode);
3086 * Create a conversion from general purpose to x87 register
3088 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3090 ir_node *src_block = get_nodes_block(node);
3091 ir_node *block = be_transform_node(src_block);
3092 ir_graph *irg = current_ir_graph;
3093 dbg_info *dbgi = get_irn_dbg_info(node);
3094 ir_node *op = get_Conv_op(node);
3095 ir_node *new_op = NULL;
3099 ir_mode *store_mode;
3104 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3105 if (possible_int_mode_for_fp(src_mode)) {
3106 ia32_address_mode_t am;
3108 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3109 if (am.op_type == ia32_AddrModeS) {
3110 ia32_address_t *addr = &am.addr;
3112 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index,
3114 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3117 set_am_attributes(fild, &am);
3118 SET_IA32_ORIG_NODE(fild, node);
3120 fix_mem_proj(fild, &am);
3125 if (new_op == NULL) {
3126 new_op = be_transform_node(op);
3129 noreg = ia32_new_NoReg_gp(env_cg);
3130 nomem = new_NoMem();
3131 mode = get_irn_mode(op);
3133 /* first convert to 32 bit signed if necessary */
3134 if (get_mode_size_bits(src_mode) < 32) {
3135 if (!upper_bits_clean(new_op, src_mode)) {
3136 new_op = create_Conv_I2I(dbgi, block, noreg, noreg, nomem, new_op, src_mode);
3137 SET_IA32_ORIG_NODE(new_op, node);
3142 assert(get_mode_size_bits(mode) == 32);
3145 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg, nomem,
3148 set_ia32_use_frame(store);
3149 set_ia32_op_type(store, ia32_AddrModeD);
3150 set_ia32_ls_mode(store, mode_Iu);
3152 /* exception for 32bit unsigned, do a 64bit spill+load */
3153 if (!mode_is_signed(mode)) {
3156 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3158 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3159 noreg, nomem, zero_const);
3161 set_ia32_use_frame(zero_store);
3162 set_ia32_op_type(zero_store, ia32_AddrModeD);
3163 add_ia32_am_offs_int(zero_store, 4);
3164 set_ia32_ls_mode(zero_store, mode_Iu);
3169 store = new_rd_Sync(dbgi, irg, block, 2, in);
3170 store_mode = mode_Ls;
3172 store_mode = mode_Is;
3176 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg, store);
3178 set_ia32_use_frame(fild);
3179 set_ia32_op_type(fild, ia32_AddrModeS);
3180 set_ia32_ls_mode(fild, store_mode);
3182 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3188 * Create a conversion from one integer mode into another one
3190 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3191 dbg_info *dbgi, ir_node *block, ir_node *op,
3194 ir_node *new_block = be_transform_node(block);
3196 ir_mode *smaller_mode;
3197 ia32_address_mode_t am;
3198 ia32_address_t *addr = &am.addr;
3201 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3202 smaller_mode = src_mode;
3204 smaller_mode = tgt_mode;
3207 #ifdef DEBUG_libfirm
3209 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3214 match_arguments(&am, block, NULL, op, NULL,
3215 match_am | match_8bit_am | match_16bit_am);
3217 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3218 /* unnecessary conv. in theory it shouldn't have been AM */
3219 assert(is_ia32_NoReg_GP(addr->base));
3220 assert(is_ia32_NoReg_GP(addr->index));
3221 assert(is_NoMem(addr->mem));
3222 assert(am.addr.offset == 0);
3223 assert(am.addr.symconst_ent == NULL);
3227 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3228 addr->mem, am.new_op2, smaller_mode);
3229 set_am_attributes(new_node, &am);
3230 /* match_arguments assume that out-mode = in-mode, this isn't true here
3232 set_ia32_ls_mode(new_node, smaller_mode);
3233 SET_IA32_ORIG_NODE(new_node, node);
3234 new_node = fix_mem_proj(new_node, &am);
3239 * Transforms a Conv node.
3241 * @return The created ia32 Conv node
3243 static ir_node *gen_Conv(ir_node *node)
3245 ir_node *block = get_nodes_block(node);
3246 ir_node *new_block = be_transform_node(block);
3247 ir_node *op = get_Conv_op(node);
3248 ir_node *new_op = NULL;
3249 dbg_info *dbgi = get_irn_dbg_info(node);
3250 ir_mode *src_mode = get_irn_mode(op);
3251 ir_mode *tgt_mode = get_irn_mode(node);
3252 int src_bits = get_mode_size_bits(src_mode);
3253 int tgt_bits = get_mode_size_bits(tgt_mode);
3254 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3255 ir_node *nomem = new_NoMem();
3256 ir_node *res = NULL;
3258 if (src_mode == mode_b) {
3259 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3260 /* nothing to do, we already model bools as 0/1 ints */
3261 return be_transform_node(op);
3264 if (src_mode == tgt_mode) {
3265 if (get_Conv_strict(node)) {
3266 if (ia32_cg_config.use_sse2) {
3267 /* when we are in SSE mode, we can kill all strict no-op conversion */
3268 return be_transform_node(op);
3271 /* this should be optimized already, but who knows... */
3272 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3273 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3274 return be_transform_node(op);
3278 if (mode_is_float(src_mode)) {
3279 new_op = be_transform_node(op);
3280 /* we convert from float ... */
3281 if (mode_is_float(tgt_mode)) {
3282 if (src_mode == mode_E && tgt_mode == mode_D
3283 && !get_Conv_strict(node)) {
3284 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3289 if (ia32_cg_config.use_sse2) {
3290 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3291 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg, noreg,
3293 set_ia32_ls_mode(res, tgt_mode);
3295 if (get_Conv_strict(node)) {
3296 res = gen_x87_strict_conv(tgt_mode, new_op);
3297 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3300 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3305 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3306 if (ia32_cg_config.use_sse2) {
3307 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg, noreg,
3309 set_ia32_ls_mode(res, src_mode);
3311 return gen_x87_fp_to_gp(node);
3315 /* we convert from int ... */
3316 if (mode_is_float(tgt_mode)) {
3318 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3319 if (ia32_cg_config.use_sse2) {
3320 new_op = be_transform_node(op);
3321 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg, noreg,
3323 set_ia32_ls_mode(res, tgt_mode);
3325 res = gen_x87_gp_to_fp(node, src_mode);
3326 if (get_Conv_strict(node)) {
3327 /* The strict-Conv is only necessary, if the int mode has more bits
3328 * than the float mantissa */
3329 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3330 size_t float_mantissa;
3331 /* FIXME There is no way to get the mantissa size of a mode */
3332 switch (get_mode_size_bits(tgt_mode)) {
3333 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3334 case 64: float_mantissa = 52 + 1; break;
3336 case 96: float_mantissa = 64; break;
3337 default: float_mantissa = 0; break;
3339 if (float_mantissa < int_mantissa) {
3340 res = gen_x87_strict_conv(tgt_mode, res);
3341 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3346 } else if (tgt_mode == mode_b) {
3347 /* mode_b lowering already took care that we only have 0/1 values */
3348 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3349 src_mode, tgt_mode));
3350 return be_transform_node(op);
3353 if (src_bits == tgt_bits) {
3354 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3355 src_mode, tgt_mode));
3356 return be_transform_node(op);
3359 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3367 static ir_node *create_immediate_or_transform(ir_node *node,
3368 char immediate_constraint_type)
3370 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3371 if (new_node == NULL) {
3372 new_node = be_transform_node(node);
3378 * Transforms a FrameAddr into an ia32 Add.
3380 static ir_node *gen_be_FrameAddr(ir_node *node)
3382 ir_node *block = be_transform_node(get_nodes_block(node));
3383 ir_node *op = be_get_FrameAddr_frame(node);
3384 ir_node *new_op = be_transform_node(op);
3385 dbg_info *dbgi = get_irn_dbg_info(node);
3386 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3389 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg);
3390 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3391 set_ia32_use_frame(new_node);
3393 SET_IA32_ORIG_NODE(new_node, node);
3399 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3401 static ir_node *gen_be_Return(ir_node *node)
3403 ir_graph *irg = current_ir_graph;
3404 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3405 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3406 ir_entity *ent = get_irg_entity(irg);
3407 ir_type *tp = get_entity_type(ent);
3412 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3413 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3416 int pn_ret_val, pn_ret_mem, arity, i;
3418 assert(ret_val != NULL);
3419 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3420 return be_duplicate_node(node);
3423 res_type = get_method_res_type(tp, 0);
3425 if (! is_Primitive_type(res_type)) {
3426 return be_duplicate_node(node);
3429 mode = get_type_mode(res_type);
3430 if (! mode_is_float(mode)) {
3431 return be_duplicate_node(node);
3434 assert(get_method_n_ress(tp) == 1);
3436 pn_ret_val = get_Proj_proj(ret_val);
3437 pn_ret_mem = get_Proj_proj(ret_mem);
3439 /* get the Barrier */
3440 barrier = get_Proj_pred(ret_val);
3442 /* get result input of the Barrier */
3443 ret_val = get_irn_n(barrier, pn_ret_val);
3444 new_ret_val = be_transform_node(ret_val);
3446 /* get memory input of the Barrier */
3447 ret_mem = get_irn_n(barrier, pn_ret_mem);
3448 new_ret_mem = be_transform_node(ret_mem);
3450 frame = get_irg_frame(irg);
3452 dbgi = get_irn_dbg_info(barrier);
3453 block = be_transform_node(get_nodes_block(barrier));
3455 noreg = ia32_new_NoReg_gp(env_cg);
3457 /* store xmm0 onto stack */
3458 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg,
3459 new_ret_mem, new_ret_val);
3460 set_ia32_ls_mode(sse_store, mode);
3461 set_ia32_op_type(sse_store, ia32_AddrModeD);
3462 set_ia32_use_frame(sse_store);
3464 /* load into x87 register */
3465 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg, sse_store, mode);
3466 set_ia32_op_type(fld, ia32_AddrModeS);
3467 set_ia32_use_frame(fld);
3469 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3470 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3472 /* create a new barrier */
3473 arity = get_irn_arity(barrier);
3474 in = ALLOCAN(ir_node*, arity);
3475 for (i = 0; i < arity; ++i) {
3478 if (i == pn_ret_val) {
3480 } else if (i == pn_ret_mem) {
3483 ir_node *in = get_irn_n(barrier, i);
3484 new_in = be_transform_node(in);
3489 new_barrier = new_ir_node(dbgi, irg, block,
3490 get_irn_op(barrier), get_irn_mode(barrier),
3492 copy_node_attr(barrier, new_barrier);
3493 be_duplicate_deps(barrier, new_barrier);
3494 be_set_transformed_node(barrier, new_barrier);
3496 /* transform normally */
3497 return be_duplicate_node(node);
3501 * Transform a be_AddSP into an ia32_SubSP.
3503 static ir_node *gen_be_AddSP(ir_node *node)
3505 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3506 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3508 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3509 match_am | match_immediate);
3513 * Transform a be_SubSP into an ia32_AddSP
3515 static ir_node *gen_be_SubSP(ir_node *node)
3517 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3518 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3520 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3521 match_am | match_immediate);
3525 * Change some phi modes
3527 static ir_node *gen_Phi(ir_node *node)
3529 ir_node *block = be_transform_node(get_nodes_block(node));
3530 ir_graph *irg = current_ir_graph;
3531 dbg_info *dbgi = get_irn_dbg_info(node);
3532 ir_mode *mode = get_irn_mode(node);
3535 if (ia32_mode_needs_gp_reg(mode)) {
3536 /* we shouldn't have any 64bit stuff around anymore */
3537 assert(get_mode_size_bits(mode) <= 32);
3538 /* all integer operations are on 32bit registers now */
3540 } else if (mode_is_float(mode)) {
3541 if (ia32_cg_config.use_sse2) {
3548 /* phi nodes allow loops, so we use the old arguments for now
3549 * and fix this later */
3550 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3551 get_irn_in(node) + 1);
3552 copy_node_attr(node, phi);
3553 be_duplicate_deps(node, phi);
3555 be_enqueue_preds(node);
3563 static ir_node *gen_IJmp(ir_node *node)
3565 ir_node *block = get_nodes_block(node);
3566 ir_node *new_block = be_transform_node(block);
3567 dbg_info *dbgi = get_irn_dbg_info(node);
3568 ir_node *op = get_IJmp_target(node);
3570 ia32_address_mode_t am;
3571 ia32_address_t *addr = &am.addr;
3573 assert(get_irn_mode(op) == mode_P);
3575 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3577 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3578 addr->mem, am.new_op2);
3579 set_am_attributes(new_node, &am);
3580 SET_IA32_ORIG_NODE(new_node, node);
3582 new_node = fix_mem_proj(new_node, &am);
3588 * Transform a Bound node.
3590 static ir_node *gen_Bound(ir_node *node)
3593 ir_node *lower = get_Bound_lower(node);
3594 dbg_info *dbgi = get_irn_dbg_info(node);
3596 if (is_Const_0(lower)) {
3597 /* typical case for Java */
3598 ir_node *sub, *res, *flags, *block;
3599 ir_graph *irg = current_ir_graph;
3601 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3602 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3604 block = get_nodes_block(res);
3605 if (! is_Proj(res)) {
3607 set_irn_mode(sub, mode_T);
3608 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3610 sub = get_Proj_pred(res);
3612 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3613 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3614 SET_IA32_ORIG_NODE(new_node, node);
3616 panic("generic Bound not supported in ia32 Backend");
3622 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3624 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3625 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3627 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3628 match_immediate | match_mode_neutral);
3631 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3633 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3634 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3635 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3639 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3641 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3642 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3643 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3647 static ir_node *gen_ia32_l_Add(ir_node *node)
3649 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3650 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3651 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3652 match_commutative | match_am | match_immediate |
3653 match_mode_neutral);
3655 if (is_Proj(lowered)) {
3656 lowered = get_Proj_pred(lowered);
3658 assert(is_ia32_Add(lowered));
3659 set_irn_mode(lowered, mode_T);
3665 static ir_node *gen_ia32_l_Adc(ir_node *node)
3667 return gen_binop_flags(node, new_bd_ia32_Adc,
3668 match_commutative | match_am | match_immediate |
3669 match_mode_neutral);
3673 * Transforms a l_MulS into a "real" MulS node.
3675 * @return the created ia32 Mul node
3677 static ir_node *gen_ia32_l_Mul(ir_node *node)
3679 ir_node *left = get_binop_left(node);
3680 ir_node *right = get_binop_right(node);
3682 return gen_binop(node, left, right, new_bd_ia32_Mul,
3683 match_commutative | match_am | match_mode_neutral);
3687 * Transforms a l_IMulS into a "real" IMul1OPS node.
3689 * @return the created ia32 IMul1OP node
3691 static ir_node *gen_ia32_l_IMul(ir_node *node)
3693 ir_node *left = get_binop_left(node);
3694 ir_node *right = get_binop_right(node);
3696 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3697 match_commutative | match_am | match_mode_neutral);
3700 static ir_node *gen_ia32_l_Sub(ir_node *node)
3702 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3703 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3704 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3705 match_am | match_immediate | match_mode_neutral);
3707 if (is_Proj(lowered)) {
3708 lowered = get_Proj_pred(lowered);
3710 assert(is_ia32_Sub(lowered));
3711 set_irn_mode(lowered, mode_T);
3717 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3719 return gen_binop_flags(node, new_bd_ia32_Sbb,
3720 match_am | match_immediate | match_mode_neutral);
3724 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3725 * op1 - target to be shifted
3726 * op2 - contains bits to be shifted into target
3728 * Only op3 can be an immediate.
3730 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3731 ir_node *low, ir_node *count)
3733 ir_node *block = get_nodes_block(node);
3734 ir_node *new_block = be_transform_node(block);
3735 dbg_info *dbgi = get_irn_dbg_info(node);
3736 ir_node *new_high = be_transform_node(high);
3737 ir_node *new_low = be_transform_node(low);
3741 /* the shift amount can be any mode that is bigger than 5 bits, since all
3742 * other bits are ignored anyway */
3743 while (is_Conv(count) &&
3744 get_irn_n_edges(count) == 1 &&
3745 mode_is_int(get_irn_mode(count))) {
3746 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3747 count = get_Conv_op(count);
3749 new_count = create_immediate_or_transform(count, 0);
3751 if (is_ia32_l_ShlD(node)) {
3752 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3755 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3758 SET_IA32_ORIG_NODE(new_node, node);
3763 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3765 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3766 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3767 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3768 return gen_lowered_64bit_shifts(node, high, low, count);
3771 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3773 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3774 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3775 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3776 return gen_lowered_64bit_shifts(node, high, low, count);
3779 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3781 ir_node *src_block = get_nodes_block(node);
3782 ir_node *block = be_transform_node(src_block);
3783 ir_graph *irg = current_ir_graph;
3784 dbg_info *dbgi = get_irn_dbg_info(node);
3785 ir_node *frame = get_irg_frame(irg);
3786 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3787 ir_node *nomem = new_NoMem();
3788 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3789 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3790 ir_node *new_val_low = be_transform_node(val_low);
3791 ir_node *new_val_high = be_transform_node(val_high);
3796 ir_node *store_high;
3798 if (!mode_is_signed(get_irn_mode(val_high))) {
3799 panic("unsigned long long -> float not supported yet (%+F)", node);
3803 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3805 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3807 SET_IA32_ORIG_NODE(store_low, node);
3808 SET_IA32_ORIG_NODE(store_high, node);
3810 set_ia32_use_frame(store_low);
3811 set_ia32_use_frame(store_high);
3812 set_ia32_op_type(store_low, ia32_AddrModeD);
3813 set_ia32_op_type(store_high, ia32_AddrModeD);
3814 set_ia32_ls_mode(store_low, mode_Iu);
3815 set_ia32_ls_mode(store_high, mode_Is);
3816 add_ia32_am_offs_int(store_high, 4);
3820 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3823 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg, sync);
3825 set_ia32_use_frame(fild);
3826 set_ia32_op_type(fild, ia32_AddrModeS);
3827 set_ia32_ls_mode(fild, mode_Ls);
3829 SET_IA32_ORIG_NODE(fild, node);
3831 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3834 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3836 ir_node *src_block = get_nodes_block(node);
3837 ir_node *block = be_transform_node(src_block);
3838 ir_graph *irg = current_ir_graph;
3839 dbg_info *dbgi = get_irn_dbg_info(node);
3840 ir_node *frame = get_irg_frame(irg);
3841 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3842 ir_node *nomem = new_NoMem();
3843 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3844 ir_node *new_val = be_transform_node(val);
3845 ir_node *fist, *mem;
3847 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3848 SET_IA32_ORIG_NODE(fist, node);
3849 set_ia32_use_frame(fist);
3850 set_ia32_op_type(fist, ia32_AddrModeD);
3851 set_ia32_ls_mode(fist, mode_Ls);
3857 * the BAD transformer.
3859 static ir_node *bad_transform(ir_node *node)
3861 panic("No transform function for %+F available.", node);
3865 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3867 ir_graph *irg = current_ir_graph;
3868 ir_node *block = be_transform_node(get_nodes_block(node));
3869 ir_node *pred = get_Proj_pred(node);
3870 ir_node *new_pred = be_transform_node(pred);
3871 ir_node *frame = get_irg_frame(irg);
3872 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3873 dbg_info *dbgi = get_irn_dbg_info(node);
3874 long pn = get_Proj_proj(node);
3879 load = new_bd_ia32_Load(dbgi, block, frame, noreg, new_pred);
3880 SET_IA32_ORIG_NODE(load, node);
3881 set_ia32_use_frame(load);
3882 set_ia32_op_type(load, ia32_AddrModeS);
3883 set_ia32_ls_mode(load, mode_Iu);
3884 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3885 * 32 bit from it with this particular load */
3886 attr = get_ia32_attr(load);
3887 attr->data.need_64bit_stackent = 1;
3889 if (pn == pn_ia32_l_FloattoLL_res_high) {
3890 add_ia32_am_offs_int(load, 4);
3892 assert(pn == pn_ia32_l_FloattoLL_res_low);
3895 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3901 * Transform the Projs of an AddSP.
3903 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3905 ir_node *block = be_transform_node(get_nodes_block(node));
3906 ir_node *pred = get_Proj_pred(node);
3907 ir_node *new_pred = be_transform_node(pred);
3908 ir_graph *irg = current_ir_graph;
3909 dbg_info *dbgi = get_irn_dbg_info(node);
3910 long proj = get_Proj_proj(node);
3912 if (proj == pn_be_AddSP_sp) {
3913 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3914 pn_ia32_SubSP_stack);
3915 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3917 } else if (proj == pn_be_AddSP_res) {
3918 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3919 pn_ia32_SubSP_addr);
3920 } else if (proj == pn_be_AddSP_M) {
3921 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3924 panic("No idea how to transform proj->AddSP");
3928 * Transform the Projs of a SubSP.
3930 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3932 ir_node *block = be_transform_node(get_nodes_block(node));
3933 ir_node *pred = get_Proj_pred(node);
3934 ir_node *new_pred = be_transform_node(pred);
3935 ir_graph *irg = current_ir_graph;
3936 dbg_info *dbgi = get_irn_dbg_info(node);
3937 long proj = get_Proj_proj(node);
3939 if (proj == pn_be_SubSP_sp) {
3940 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3941 pn_ia32_AddSP_stack);
3942 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3944 } else if (proj == pn_be_SubSP_M) {
3945 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3948 panic("No idea how to transform proj->SubSP");
3952 * Transform and renumber the Projs from a Load.
3954 static ir_node *gen_Proj_Load(ir_node *node)
3957 ir_node *block = be_transform_node(get_nodes_block(node));
3958 ir_node *pred = get_Proj_pred(node);
3959 ir_graph *irg = current_ir_graph;
3960 dbg_info *dbgi = get_irn_dbg_info(node);
3961 long proj = get_Proj_proj(node);
3963 /* loads might be part of source address mode matches, so we don't
3964 * transform the ProjMs yet (with the exception of loads whose result is
3967 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
3970 /* this is needed, because sometimes we have loops that are only
3971 reachable through the ProjM */
3972 be_enqueue_preds(node);
3973 /* do it in 2 steps, to silence firm verifier */
3974 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
3975 set_Proj_proj(res, pn_ia32_mem);
3979 /* renumber the proj */
3980 new_pred = be_transform_node(pred);
3981 if (is_ia32_Load(new_pred)) {
3984 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
3986 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
3987 case pn_Load_X_regular:
3988 return new_rd_Jmp(dbgi, irg, block);
3989 case pn_Load_X_except:
3990 /* This Load might raise an exception. Mark it. */
3991 set_ia32_exc_label(new_pred, 1);
3992 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
3996 } else if (is_ia32_Conv_I2I(new_pred) ||
3997 is_ia32_Conv_I2I8Bit(new_pred)) {
3998 set_irn_mode(new_pred, mode_T);
3999 if (proj == pn_Load_res) {
4000 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4001 } else if (proj == pn_Load_M) {
4002 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4004 } else if (is_ia32_xLoad(new_pred)) {
4007 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4009 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4010 case pn_Load_X_regular:
4011 return new_rd_Jmp(dbgi, irg, block);
4012 case pn_Load_X_except:
4013 /* This Load might raise an exception. Mark it. */
4014 set_ia32_exc_label(new_pred, 1);
4015 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4019 } else if (is_ia32_vfld(new_pred)) {
4022 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4024 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4025 case pn_Load_X_regular:
4026 return new_rd_Jmp(dbgi, irg, block);
4027 case pn_Load_X_except:
4028 /* This Load might raise an exception. Mark it. */
4029 set_ia32_exc_label(new_pred, 1);
4030 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4035 /* can happen for ProJMs when source address mode happened for the
4038 /* however it should not be the result proj, as that would mean the
4039 load had multiple users and should not have been used for
4041 if (proj != pn_Load_M) {
4042 panic("internal error: transformed node not a Load");
4044 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4047 panic("No idea how to transform proj");
4051 * Transform and renumber the Projs from a DivMod like instruction.
4053 static ir_node *gen_Proj_DivMod(ir_node *node)
4055 ir_node *block = be_transform_node(get_nodes_block(node));
4056 ir_node *pred = get_Proj_pred(node);
4057 ir_node *new_pred = be_transform_node(pred);
4058 ir_graph *irg = current_ir_graph;
4059 dbg_info *dbgi = get_irn_dbg_info(node);
4060 long proj = get_Proj_proj(node);
4062 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4064 switch (get_irn_opcode(pred)) {
4068 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4070 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4071 case pn_Div_X_regular:
4072 return new_rd_Jmp(dbgi, irg, block);
4073 case pn_Div_X_except:
4074 set_ia32_exc_label(new_pred, 1);
4075 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4083 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4085 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4086 case pn_Mod_X_except:
4087 set_ia32_exc_label(new_pred, 1);
4088 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4096 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4097 case pn_DivMod_res_div:
4098 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4099 case pn_DivMod_res_mod:
4100 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4101 case pn_DivMod_X_regular:
4102 return new_rd_Jmp(dbgi, irg, block);
4103 case pn_DivMod_X_except:
4104 set_ia32_exc_label(new_pred, 1);
4105 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4114 panic("No idea how to transform proj->DivMod");
4118 * Transform and renumber the Projs from a CopyB.
4120 static ir_node *gen_Proj_CopyB(ir_node *node)
4122 ir_node *block = be_transform_node(get_nodes_block(node));
4123 ir_node *pred = get_Proj_pred(node);
4124 ir_node *new_pred = be_transform_node(pred);
4125 ir_graph *irg = current_ir_graph;
4126 dbg_info *dbgi = get_irn_dbg_info(node);
4127 long proj = get_Proj_proj(node);
4130 case pn_CopyB_M_regular:
4131 if (is_ia32_CopyB_i(new_pred)) {
4132 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4133 } else if (is_ia32_CopyB(new_pred)) {
4134 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4141 panic("No idea how to transform proj->CopyB");
4145 * Transform and renumber the Projs from a Quot.
4147 static ir_node *gen_Proj_Quot(ir_node *node)
4149 ir_node *block = be_transform_node(get_nodes_block(node));
4150 ir_node *pred = get_Proj_pred(node);
4151 ir_node *new_pred = be_transform_node(pred);
4152 ir_graph *irg = current_ir_graph;
4153 dbg_info *dbgi = get_irn_dbg_info(node);
4154 long proj = get_Proj_proj(node);
4158 if (is_ia32_xDiv(new_pred)) {
4159 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4160 } else if (is_ia32_vfdiv(new_pred)) {
4161 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4165 if (is_ia32_xDiv(new_pred)) {
4166 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4167 } else if (is_ia32_vfdiv(new_pred)) {
4168 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4171 case pn_Quot_X_regular:
4172 case pn_Quot_X_except:
4177 panic("No idea how to transform proj->Quot");
4180 static ir_node *gen_be_Call(ir_node *node)
4182 dbg_info *const dbgi = get_irn_dbg_info(node);
4183 ir_graph *const irg = current_ir_graph;
4184 ir_node *const src_block = get_nodes_block(node);
4185 ir_node *const block = be_transform_node(src_block);
4186 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4187 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4188 ir_node *const sp = be_transform_node(src_sp);
4189 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4190 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4191 ia32_address_mode_t am;
4192 ia32_address_t *const addr = &am.addr;
4197 ir_node * eax = noreg;
4198 ir_node * ecx = noreg;
4199 ir_node * edx = noreg;
4200 unsigned const pop = be_Call_get_pop(node);
4201 ir_type *const call_tp = be_Call_get_type(node);
4203 /* Run the x87 simulator if the call returns a float value */
4204 if (get_method_n_ress(call_tp) > 0) {
4205 ir_type *const res_type = get_method_res_type(call_tp, 0);
4206 ir_mode *const res_mode = get_type_mode(res_type);
4208 if (res_mode != NULL && mode_is_float(res_mode)) {
4209 env_cg->do_x87_sim = 1;
4213 /* We do not want be_Call direct calls */
4214 assert(be_Call_get_entity(node) == NULL);
4216 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4217 match_am | match_immediate);
4219 i = get_irn_arity(node) - 1;
4220 fpcw = be_transform_node(get_irn_n(node, i--));
4221 for (; i >= be_pos_Call_first_arg; --i) {
4222 arch_register_req_t const *const req = arch_get_register_req(node, i);
4223 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4225 assert(req->type == arch_register_req_type_limited);
4226 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4228 switch (*req->limited) {
4229 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4230 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4231 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4232 default: panic("Invalid GP register for register parameter");
4236 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4237 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4238 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4239 set_am_attributes(call, &am);
4240 call = fix_mem_proj(call, &am);
4242 if (get_irn_pinned(node) == op_pin_state_pinned)
4243 set_irn_pinned(call, op_pin_state_pinned);
4245 SET_IA32_ORIG_NODE(call, node);
4249 static ir_node *gen_be_IncSP(ir_node *node)
4251 ir_node *res = be_duplicate_node(node);
4252 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4258 * Transform the Projs from a be_Call.
4260 static ir_node *gen_Proj_be_Call(ir_node *node)
4262 ir_node *block = be_transform_node(get_nodes_block(node));
4263 ir_node *call = get_Proj_pred(node);
4264 ir_node *new_call = be_transform_node(call);
4265 ir_graph *irg = current_ir_graph;
4266 dbg_info *dbgi = get_irn_dbg_info(node);
4267 ir_type *method_type = be_Call_get_type(call);
4268 int n_res = get_method_n_ress(method_type);
4269 long proj = get_Proj_proj(node);
4270 ir_mode *mode = get_irn_mode(node);
4274 /* The following is kinda tricky: If we're using SSE, then we have to
4275 * move the result value of the call in floating point registers to an
4276 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4277 * after the call, we have to make sure to correctly make the
4278 * MemProj and the result Proj use these 2 nodes
4280 if (proj == pn_be_Call_M_regular) {
4281 // get new node for result, are we doing the sse load/store hack?
4282 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4283 ir_node *call_res_new;
4284 ir_node *call_res_pred = NULL;
4286 if (call_res != NULL) {
4287 call_res_new = be_transform_node(call_res);
4288 call_res_pred = get_Proj_pred(call_res_new);
4291 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4292 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4295 assert(is_ia32_xLoad(call_res_pred));
4296 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4300 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4301 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4303 ir_node *frame = get_irg_frame(irg);
4304 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4306 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4309 /* in case there is no memory output: create one to serialize the copy
4311 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4312 pn_be_Call_M_regular);
4313 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4314 pn_be_Call_first_res);
4316 /* store st(0) onto stack */
4317 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg, call_mem,
4319 set_ia32_op_type(fstp, ia32_AddrModeD);
4320 set_ia32_use_frame(fstp);
4322 /* load into SSE register */
4323 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg, fstp, mode);
4324 set_ia32_op_type(sse_load, ia32_AddrModeS);
4325 set_ia32_use_frame(sse_load);
4327 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4333 /* transform call modes */
4334 if (mode_is_data(mode)) {
4335 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4339 /* Map from be_Call to ia32_Call proj number */
4340 if (proj == pn_be_Call_sp) {
4341 proj = pn_ia32_Call_stack;
4342 } else if (proj == pn_be_Call_M_regular) {
4343 proj = pn_ia32_Call_M;
4345 arch_register_req_t const *const req = arch_get_register_req_out(node);
4346 int const n_outs = arch_irn_get_n_outs(new_call);
4349 assert(proj >= pn_be_Call_first_res);
4350 assert(req->type & arch_register_req_type_limited);
4352 for (i = 0; i < n_outs; ++i) {
4353 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4355 if (!(new_req->type & arch_register_req_type_limited) ||
4356 new_req->cls != req->cls ||
4357 *new_req->limited != *req->limited)
4366 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4368 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4370 case pn_ia32_Call_stack:
4371 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4374 case pn_ia32_Call_fpcw:
4375 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4383 * Transform the Projs from a Cmp.
4385 static ir_node *gen_Proj_Cmp(ir_node *node)
4387 /* this probably means not all mode_b nodes were lowered... */
4388 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4393 * Transform the Projs from a Bound.
4395 static ir_node *gen_Proj_Bound(ir_node *node)
4397 ir_node *new_node, *block;
4398 ir_node *pred = get_Proj_pred(node);
4400 switch (get_Proj_proj(node)) {
4402 return be_transform_node(get_Bound_mem(pred));
4403 case pn_Bound_X_regular:
4404 new_node = be_transform_node(pred);
4405 block = get_nodes_block(new_node);
4406 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4407 case pn_Bound_X_except:
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_false);
4412 return be_transform_node(get_Bound_index(pred));
4414 panic("unsupported Proj from Bound");
4418 static ir_node *gen_Proj_ASM(ir_node *node)
4424 if (get_irn_mode(node) != mode_M)
4425 return be_duplicate_node(node);
4427 pred = get_Proj_pred(node);
4428 new_pred = be_transform_node(pred);
4429 block = get_nodes_block(new_pred);
4430 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4431 arch_irn_get_n_outs(new_pred) + 1);
4435 * Transform and potentially renumber Proj nodes.
4437 static ir_node *gen_Proj(ir_node *node)
4439 ir_node *pred = get_Proj_pred(node);
4442 switch (get_irn_opcode(pred)) {
4444 proj = get_Proj_proj(node);
4445 if (proj == pn_Store_M) {
4446 return be_transform_node(pred);
4448 panic("No idea how to transform proj->Store");
4451 return gen_Proj_Load(node);
4453 return gen_Proj_ASM(node);
4457 return gen_Proj_DivMod(node);
4459 return gen_Proj_CopyB(node);
4461 return gen_Proj_Quot(node);
4463 return gen_Proj_be_SubSP(node);
4465 return gen_Proj_be_AddSP(node);
4467 return gen_Proj_be_Call(node);
4469 return gen_Proj_Cmp(node);
4471 return gen_Proj_Bound(node);
4473 proj = get_Proj_proj(node);
4475 case pn_Start_X_initial_exec: {
4476 ir_node *block = get_nodes_block(pred);
4477 ir_node *new_block = be_transform_node(block);
4478 dbg_info *dbgi = get_irn_dbg_info(node);
4479 /* we exchange the ProjX with a jump */
4480 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4485 case pn_Start_P_tls:
4486 return gen_Proj_tls(node);
4491 if (is_ia32_l_FloattoLL(pred)) {
4492 return gen_Proj_l_FloattoLL(node);
4494 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4498 ir_mode *mode = get_irn_mode(node);
4499 if (ia32_mode_needs_gp_reg(mode)) {
4500 ir_node *new_pred = be_transform_node(pred);
4501 ir_node *block = be_transform_node(get_nodes_block(node));
4502 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4503 mode_Iu, get_Proj_proj(node));
4504 #ifdef DEBUG_libfirm
4505 new_proj->node_nr = node->node_nr;
4511 return be_duplicate_node(node);
4515 * Enters all transform functions into the generic pointer
4517 static void register_transformers(void)
4521 /* first clear the generic function pointer for all ops */
4522 clear_irp_opcodes_generic_func();
4524 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4525 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4563 /* transform ops from intrinsic lowering */
4575 GEN(ia32_l_LLtoFloat);
4576 GEN(ia32_l_FloattoLL);
4582 /* we should never see these nodes */
4597 /* handle generic backend nodes */
4606 op_Mulh = get_op_Mulh();
4615 * Pre-transform all unknown and noreg nodes.
4617 static void ia32_pretransform_node(void)
4619 ia32_code_gen_t *cg = env_cg;
4621 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4622 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4623 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4624 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4625 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4626 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4631 * Walker, checks if all ia32 nodes producing more than one result have their
4632 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4634 static void add_missing_keep_walker(ir_node *node, void *data)
4637 unsigned found_projs = 0;
4638 const ir_edge_t *edge;
4639 ir_mode *mode = get_irn_mode(node);
4644 if (!is_ia32_irn(node))
4647 n_outs = arch_irn_get_n_outs(node);
4650 if (is_ia32_SwitchJmp(node))
4653 assert(n_outs < (int) sizeof(unsigned) * 8);
4654 foreach_out_edge(node, edge) {
4655 ir_node *proj = get_edge_src_irn(edge);
4658 /* The node could be kept */
4662 if (get_irn_mode(proj) == mode_M)
4665 pn = get_Proj_proj(proj);
4666 assert(pn < n_outs);
4667 found_projs |= 1 << pn;
4671 /* are keeps missing? */
4673 for (i = 0; i < n_outs; ++i) {
4676 const arch_register_req_t *req;
4677 const arch_register_class_t *cls;
4679 if (found_projs & (1 << i)) {
4683 req = get_ia32_out_req(node, i);
4688 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4692 block = get_nodes_block(node);
4693 in[0] = new_r_Proj(current_ir_graph, block, node,
4694 arch_register_class_mode(cls), i);
4695 if (last_keep != NULL) {
4696 be_Keep_add_node(last_keep, cls, in[0]);
4698 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4699 if (sched_is_scheduled(node)) {
4700 sched_add_after(node, last_keep);
4707 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4710 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4712 ir_graph *irg = be_get_birg_irg(cg->birg);
4713 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4716 /* do the transformation */
4717 void ia32_transform_graph(ia32_code_gen_t *cg)
4721 register_transformers();
4723 initial_fpcw = NULL;
4725 BE_TIMER_PUSH(t_heights);
4726 heights = heights_new(cg->irg);
4727 BE_TIMER_POP(t_heights);
4728 ia32_calculate_non_address_mode_nodes(cg->birg);
4730 /* the transform phase is not safe for CSE (yet) because several nodes get
4731 * attributes set after their creation */
4732 cse_last = get_opt_cse();
4735 be_transform_graph(cg->birg, ia32_pretransform_node);
4737 set_opt_cse(cse_last);
4739 ia32_free_non_address_mode_nodes();
4740 heights_free(heights);
4744 void ia32_init_transform(void)
4746 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");