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
35 #include "irgraph_t.h"
40 #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_graph *irg,
102 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
103 ir_node *op1, ir_node *op2);
105 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
106 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
107 ir_node *op1, ir_node *op2, ir_node *flags);
109 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
110 ir_node *block, ir_node *op1, ir_node *op2);
112 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
113 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
116 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
117 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
119 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
120 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
121 ir_node *op1, ir_node *op2, ir_node *fpcw);
123 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
124 ir_node *block, ir_node *op);
126 static ir_node *create_immediate_or_transform(ir_node *node,
127 char immediate_constraint_type);
129 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
130 dbg_info *dbgi, ir_node *block,
131 ir_node *op, ir_node *orig_node);
133 /** Return non-zero is a node represents the 0 constant. */
134 static int is_Const_0(ir_node *node) {
135 return is_Const(node) && is_Const_null(node);
138 /** Return non-zero is a node represents the 1 constant. */
139 static int 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 int is_Const_Minus_1(ir_node *node) {
145 return is_Const(node) && is_Const_all_one(node);
149 * returns true if constant can be created with a simple float command
151 static int is_simple_x87_Const(ir_node *node)
153 tarval *tv = get_Const_tarval(node);
154 if (tarval_is_null(tv) || tarval_is_one(tv))
157 /* TODO: match all the other float constants */
162 * returns true if constant can be created with a simple float command
164 static int is_simple_sse_Const(ir_node *node)
166 tarval *tv = get_Const_tarval(node);
167 ir_mode *mode = get_tarval_mode(tv);
172 if (tarval_is_null(tv) || tarval_is_one(tv))
175 if (mode == mode_D) {
176 unsigned val = get_tarval_sub_bits(tv, 0) |
177 (get_tarval_sub_bits(tv, 1) << 8) |
178 (get_tarval_sub_bits(tv, 2) << 16) |
179 (get_tarval_sub_bits(tv, 3) << 24);
181 /* lower 32bit are zero, really a 32bit constant */
185 /* TODO: match all the other float constants */
190 * Transforms a Const.
192 static ir_node *gen_Const(ir_node *node) {
193 ir_graph *irg = current_ir_graph;
194 ir_node *old_block = get_nodes_block(node);
195 ir_node *block = be_transform_node(old_block);
196 dbg_info *dbgi = get_irn_dbg_info(node);
197 ir_mode *mode = get_irn_mode(node);
199 assert(is_Const(node));
201 if (mode_is_float(mode)) {
203 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
204 ir_node *nomem = new_NoMem();
208 if (ia32_cg_config.use_sse2) {
209 tarval *tv = get_Const_tarval(node);
210 if (tarval_is_null(tv)) {
211 load = new_rd_ia32_xZero(dbgi, irg, block);
212 set_ia32_ls_mode(load, mode);
214 } else if (tarval_is_one(tv)) {
215 int cnst = mode == mode_F ? 26 : 55;
216 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
217 ir_node *imm2 = create_Immediate(NULL, 0, 2);
218 ir_node *pslld, *psrld;
220 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
221 set_ia32_ls_mode(load, mode);
222 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
223 set_ia32_ls_mode(pslld, mode);
224 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
225 set_ia32_ls_mode(psrld, mode);
227 } else if (mode == mode_F) {
228 /* we can place any 32bit constant by using a movd gp, sse */
229 unsigned val = get_tarval_sub_bits(tv, 0) |
230 (get_tarval_sub_bits(tv, 1) << 8) |
231 (get_tarval_sub_bits(tv, 2) << 16) |
232 (get_tarval_sub_bits(tv, 3) << 24);
233 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
234 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
235 set_ia32_ls_mode(load, mode);
238 if (mode == mode_D) {
239 unsigned val = get_tarval_sub_bits(tv, 0) |
240 (get_tarval_sub_bits(tv, 1) << 8) |
241 (get_tarval_sub_bits(tv, 2) << 16) |
242 (get_tarval_sub_bits(tv, 3) << 24);
244 ir_node *imm32 = create_Immediate(NULL, 0, 32);
245 ir_node *cnst, *psllq;
247 /* fine, lower 32bit are zero, produce 32bit value */
248 val = get_tarval_sub_bits(tv, 4) |
249 (get_tarval_sub_bits(tv, 5) << 8) |
250 (get_tarval_sub_bits(tv, 6) << 16) |
251 (get_tarval_sub_bits(tv, 7) << 24);
252 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
253 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
254 set_ia32_ls_mode(load, mode);
255 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
256 set_ia32_ls_mode(psllq, mode);
261 floatent = create_float_const_entity(node);
263 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
265 set_ia32_op_type(load, ia32_AddrModeS);
266 set_ia32_am_sc(load, floatent);
267 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
268 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
271 if (is_Const_null(node)) {
272 load = new_rd_ia32_vfldz(dbgi, irg, block);
274 set_ia32_ls_mode(load, mode);
275 } else if (is_Const_one(node)) {
276 load = new_rd_ia32_vfld1(dbgi, irg, block);
278 set_ia32_ls_mode(load, mode);
280 floatent = create_float_const_entity(node);
282 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
283 set_ia32_op_type(load, ia32_AddrModeS);
284 set_ia32_am_sc(load, floatent);
285 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
286 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
287 /* take the mode from the entity */
288 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
292 /* Const Nodes before the initial IncSP are a bad idea, because
293 * they could be spilled and we have no SP ready at that point yet.
294 * So add a dependency to the initial frame pointer calculation to
295 * avoid that situation.
297 if (get_irg_start_block(irg) == block) {
298 add_irn_dep(load, get_irg_frame(irg));
301 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
303 } else { /* non-float mode */
305 tarval *tv = get_Const_tarval(node);
308 tv = tarval_convert_to(tv, mode_Iu);
310 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
312 panic("couldn't convert constant tarval (%+F)", node);
314 val = get_tarval_long(tv);
316 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
317 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
320 if (get_irg_start_block(irg) == block) {
321 add_irn_dep(cnst, get_irg_frame(irg));
329 * Transforms a SymConst.
331 static ir_node *gen_SymConst(ir_node *node) {
332 ir_graph *irg = current_ir_graph;
333 ir_node *old_block = get_nodes_block(node);
334 ir_node *block = be_transform_node(old_block);
335 dbg_info *dbgi = get_irn_dbg_info(node);
336 ir_mode *mode = get_irn_mode(node);
339 if (mode_is_float(mode)) {
340 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
341 ir_node *nomem = new_NoMem();
343 if (ia32_cg_config.use_sse2)
344 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
346 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
347 set_ia32_am_sc(cnst, get_SymConst_entity(node));
348 set_ia32_use_frame(cnst);
352 if(get_SymConst_kind(node) != symconst_addr_ent) {
353 panic("backend only support symconst_addr_ent (at %+F)", node);
355 entity = get_SymConst_entity(node);
356 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
359 /* Const Nodes before the initial IncSP are a bad idea, because
360 * they could be spilled and we have no SP ready at that point yet
362 if (get_irg_start_block(irg) == block) {
363 add_irn_dep(cnst, get_irg_frame(irg));
366 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
371 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
372 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
373 static const struct {
375 const char *ent_name;
376 const char *cnst_str;
379 } names [ia32_known_const_max] = {
380 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
381 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
382 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
383 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
384 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
386 static ir_entity *ent_cache[ia32_known_const_max];
388 const char *tp_name, *ent_name, *cnst_str;
396 ent_name = names[kct].ent_name;
397 if (! ent_cache[kct]) {
398 tp_name = names[kct].tp_name;
399 cnst_str = names[kct].cnst_str;
401 switch (names[kct].mode) {
402 case 0: mode = mode_Iu; break;
403 case 1: mode = mode_Lu; break;
404 default: mode = mode_F; break;
406 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
407 tp = new_type_primitive(new_id_from_str(tp_name), mode);
408 /* set the specified alignment */
409 set_type_alignment_bytes(tp, names[kct].align);
411 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
413 set_entity_ld_ident(ent, get_entity_ident(ent));
414 set_entity_visibility(ent, visibility_local);
415 set_entity_variability(ent, variability_constant);
416 set_entity_allocation(ent, allocation_static);
418 /* we create a new entity here: It's initialization must resist on the
420 rem = current_ir_graph;
421 current_ir_graph = get_const_code_irg();
422 cnst = new_Const(mode, tv);
423 current_ir_graph = rem;
425 set_atomic_ent_value(ent, cnst);
427 /* cache the entry */
428 ent_cache[kct] = ent;
431 return ent_cache[kct];
435 * return true if the node is a Proj(Load) and could be used in source address
436 * mode for another node. Will return only true if the @p other node is not
437 * dependent on the memory of the Load (for binary operations use the other
438 * input here, for unary operations use NULL).
440 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
441 ir_node *other, ir_node *other2, match_flags_t flags)
446 /* float constants are always available */
447 if (is_Const(node)) {
448 ir_mode *mode = get_irn_mode(node);
449 if (mode_is_float(mode)) {
450 if (ia32_cg_config.use_sse2) {
451 if (is_simple_sse_Const(node))
454 if (is_simple_x87_Const(node))
457 if (get_irn_n_edges(node) > 1)
465 load = get_Proj_pred(node);
466 pn = get_Proj_proj(node);
467 if (!is_Load(load) || pn != pn_Load_res)
469 if (get_nodes_block(load) != block)
471 /* we only use address mode if we're the only user of the load */
472 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
474 /* in some edge cases with address mode we might reach the load normally
475 * and through some AM sequence, if it is already materialized then we
476 * can't create an AM node from it */
477 if (be_is_transformed(node))
480 /* don't do AM if other node inputs depend on the load (via mem-proj) */
481 if (other != NULL && get_nodes_block(other) == block &&
482 heights_reachable_in_block(heights, other, load))
484 if (other2 != NULL && get_nodes_block(other2) == block &&
485 heights_reachable_in_block(heights, other2, load))
491 typedef struct ia32_address_mode_t ia32_address_mode_t;
492 struct ia32_address_mode_t {
496 ia32_op_type_t op_type;
500 unsigned commutative : 1;
501 unsigned ins_permuted : 1;
504 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
508 /* construct load address */
509 memset(addr, 0, sizeof(addr[0]));
510 ia32_create_address_mode(addr, ptr, /*force=*/0);
512 noreg_gp = ia32_new_NoReg_gp(env_cg);
513 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
514 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
515 addr->mem = be_transform_node(mem);
518 static void build_address(ia32_address_mode_t *am, ir_node *node)
520 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
521 ia32_address_t *addr = &am->addr;
527 if (is_Const(node)) {
528 ir_entity *entity = create_float_const_entity(node);
529 addr->base = noreg_gp;
530 addr->index = noreg_gp;
531 addr->mem = new_NoMem();
532 addr->symconst_ent = entity;
534 am->ls_mode = get_type_mode(get_entity_type(entity));
535 am->pinned = op_pin_state_floats;
539 load = get_Proj_pred(node);
540 ptr = get_Load_ptr(load);
541 mem = get_Load_mem(load);
542 new_mem = be_transform_node(mem);
543 am->pinned = get_irn_pinned(load);
544 am->ls_mode = get_Load_mode(load);
545 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
547 /* construct load address */
548 ia32_create_address_mode(addr, ptr, /*force=*/0);
550 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
551 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
555 static void set_address(ir_node *node, const ia32_address_t *addr)
557 set_ia32_am_scale(node, addr->scale);
558 set_ia32_am_sc(node, addr->symconst_ent);
559 set_ia32_am_offs_int(node, addr->offset);
560 if(addr->symconst_sign)
561 set_ia32_am_sc_sign(node);
563 set_ia32_use_frame(node);
564 set_ia32_frame_ent(node, addr->frame_entity);
568 * Apply attributes of a given address mode to a node.
570 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
572 set_address(node, &am->addr);
574 set_ia32_op_type(node, am->op_type);
575 set_ia32_ls_mode(node, am->ls_mode);
576 if (am->pinned == op_pin_state_pinned) {
577 /* beware: some nodes are already pinned and did not allow to change the state */
578 if (get_irn_pinned(node) != op_pin_state_pinned)
579 set_irn_pinned(node, op_pin_state_pinned);
582 set_ia32_commutative(node);
586 * Check, if a given node is a Down-Conv, ie. a integer Conv
587 * from a mode with a mode with more bits to a mode with lesser bits.
588 * Moreover, we return only true if the node has not more than 1 user.
590 * @param node the node
591 * @return non-zero if node is a Down-Conv
593 static int is_downconv(const ir_node *node)
601 /* we only want to skip the conv when we're the only user
602 * (not optimal but for now...)
604 if(get_irn_n_edges(node) > 1)
607 src_mode = get_irn_mode(get_Conv_op(node));
608 dest_mode = get_irn_mode(node);
609 return ia32_mode_needs_gp_reg(src_mode)
610 && ia32_mode_needs_gp_reg(dest_mode)
611 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
614 /* Skip all Down-Conv's on a given node and return the resulting node. */
615 ir_node *ia32_skip_downconv(ir_node *node) {
616 while (is_downconv(node))
617 node = get_Conv_op(node);
622 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
624 ir_mode *mode = get_irn_mode(node);
629 if(mode_is_signed(mode)) {
634 block = get_nodes_block(node);
635 dbgi = get_irn_dbg_info(node);
637 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
641 * matches operands of a node into ia32 addressing/operand modes. This covers
642 * usage of source address mode, immediates, operations with non 32-bit modes,
644 * The resulting data is filled into the @p am struct. block is the block
645 * of the node whose arguments are matched. op1, op2 are the first and second
646 * input that are matched (op1 may be NULL). other_op is another unrelated
647 * input that is not matched! but which is needed sometimes to check if AM
648 * for op1/op2 is legal.
649 * @p flags describes the supported modes of the operation in detail.
651 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
652 ir_node *op1, ir_node *op2, ir_node *other_op,
655 ia32_address_t *addr = &am->addr;
656 ir_mode *mode = get_irn_mode(op2);
657 int mode_bits = get_mode_size_bits(mode);
658 ir_node *noreg_gp, *new_op1, *new_op2;
660 unsigned commutative;
661 int use_am_and_immediates;
664 memset(am, 0, sizeof(am[0]));
666 commutative = (flags & match_commutative) != 0;
667 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
668 use_am = (flags & match_am) != 0;
669 use_immediate = (flags & match_immediate) != 0;
670 assert(!use_am_and_immediates || use_immediate);
673 assert(!commutative || op1 != NULL);
674 assert(use_am || !(flags & match_8bit_am));
675 assert(use_am || !(flags & match_16bit_am));
677 if (mode_bits == 8) {
678 if (!(flags & match_8bit_am))
680 /* we don't automatically add upconvs yet */
681 assert((flags & match_mode_neutral) || (flags & match_8bit));
682 } else if (mode_bits == 16) {
683 if (!(flags & match_16bit_am))
685 /* we don't automatically add upconvs yet */
686 assert((flags & match_mode_neutral) || (flags & match_16bit));
689 /* we can simply skip downconvs for mode neutral nodes: the upper bits
690 * can be random for these operations */
691 if (flags & match_mode_neutral) {
692 op2 = ia32_skip_downconv(op2);
694 op1 = ia32_skip_downconv(op1);
698 /* match immediates. firm nodes are normalized: constants are always on the
701 if (!(flags & match_try_am) && use_immediate) {
702 new_op2 = try_create_Immediate(op2, 0);
705 noreg_gp = ia32_new_NoReg_gp(env_cg);
706 if (new_op2 == NULL &&
707 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
708 build_address(am, op2);
709 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
710 if (mode_is_float(mode)) {
711 new_op2 = ia32_new_NoReg_vfp(env_cg);
715 am->op_type = ia32_AddrModeS;
716 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
718 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
720 build_address(am, op1);
722 if (mode_is_float(mode)) {
723 noreg = ia32_new_NoReg_vfp(env_cg);
728 if (new_op2 != NULL) {
731 new_op1 = be_transform_node(op2);
733 am->ins_permuted = 1;
735 am->op_type = ia32_AddrModeS;
737 if (flags & match_try_am) {
740 am->op_type = ia32_Normal;
744 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
746 new_op2 = be_transform_node(op2);
747 am->op_type = ia32_Normal;
748 am->ls_mode = get_irn_mode(op2);
749 if (flags & match_mode_neutral)
750 am->ls_mode = mode_Iu;
752 if (addr->base == NULL)
753 addr->base = noreg_gp;
754 if (addr->index == NULL)
755 addr->index = noreg_gp;
756 if (addr->mem == NULL)
757 addr->mem = new_NoMem();
759 am->new_op1 = new_op1;
760 am->new_op2 = new_op2;
761 am->commutative = commutative;
764 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
769 if (am->mem_proj == NULL)
772 /* we have to create a mode_T so the old MemProj can attach to us */
773 mode = get_irn_mode(node);
774 load = get_Proj_pred(am->mem_proj);
776 mark_irn_visited(load);
777 be_set_transformed_node(load, node);
779 if (mode != mode_T) {
780 set_irn_mode(node, mode_T);
781 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
788 * Construct a standard binary operation, set AM and immediate if required.
790 * @param node The original node for which the binop is created
791 * @param op1 The first operand
792 * @param op2 The second operand
793 * @param func The node constructor function
794 * @return The constructed ia32 node.
796 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
797 construct_binop_func *func, match_flags_t flags)
800 ir_node *block, *new_block, *new_node;
801 ia32_address_mode_t am;
802 ia32_address_t *addr = &am.addr;
804 block = get_nodes_block(node);
805 match_arguments(&am, block, op1, op2, NULL, flags);
807 dbgi = get_irn_dbg_info(node);
808 new_block = be_transform_node(block);
809 new_node = func(dbgi, current_ir_graph, new_block,
810 addr->base, addr->index, addr->mem,
811 am.new_op1, am.new_op2);
812 set_am_attributes(new_node, &am);
813 /* we can't use source address mode anymore when using immediates */
814 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
815 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
816 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
818 new_node = fix_mem_proj(new_node, &am);
825 n_ia32_l_binop_right,
826 n_ia32_l_binop_eflags
828 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
829 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
830 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
831 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
832 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
833 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
836 * Construct a binary operation which also consumes the eflags.
838 * @param node The node to transform
839 * @param func The node constructor function
840 * @param flags The match flags
841 * @return The constructor ia32 node
843 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
846 ir_node *src_block = get_nodes_block(node);
847 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
848 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
850 ir_node *block, *new_node, *eflags, *new_eflags;
851 ia32_address_mode_t am;
852 ia32_address_t *addr = &am.addr;
854 match_arguments(&am, src_block, op1, op2, NULL, flags);
856 dbgi = get_irn_dbg_info(node);
857 block = be_transform_node(src_block);
858 eflags = get_irn_n(node, n_ia32_l_binop_eflags);
859 new_eflags = be_transform_node(eflags);
860 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
861 addr->mem, am.new_op1, am.new_op2, new_eflags);
862 set_am_attributes(new_node, &am);
863 /* we can't use source address mode anymore when using immediates */
864 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
865 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
866 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
868 new_node = fix_mem_proj(new_node, &am);
873 static ir_node *get_fpcw(void)
876 if (initial_fpcw != NULL)
879 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
880 &ia32_fp_cw_regs[REG_FPCW]);
881 initial_fpcw = be_transform_node(fpcw);
887 * Construct a standard binary operation, set AM and immediate if required.
889 * @param op1 The first operand
890 * @param op2 The second operand
891 * @param func The node constructor function
892 * @return The constructed ia32 node.
894 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
895 construct_binop_float_func *func,
898 ir_mode *mode = get_irn_mode(node);
900 ir_node *block, *new_block, *new_node;
901 ia32_address_mode_t am;
902 ia32_address_t *addr = &am.addr;
904 /* cannot use address mode with long double on x87 */
905 if (get_mode_size_bits(mode) > 64)
908 block = get_nodes_block(node);
909 match_arguments(&am, block, op1, op2, NULL, flags);
911 dbgi = get_irn_dbg_info(node);
912 new_block = be_transform_node(block);
913 new_node = func(dbgi, current_ir_graph, new_block,
914 addr->base, addr->index, addr->mem,
915 am.new_op1, am.new_op2, get_fpcw());
916 set_am_attributes(new_node, &am);
918 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
920 new_node = fix_mem_proj(new_node, &am);
926 * Construct a shift/rotate binary operation, sets AM and immediate if required.
928 * @param op1 The first operand
929 * @param op2 The second operand
930 * @param func The node constructor function
931 * @return The constructed ia32 node.
933 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
934 construct_shift_func *func,
938 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
940 assert(! mode_is_float(get_irn_mode(node)));
941 assert(flags & match_immediate);
942 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
944 if (flags & match_mode_neutral) {
945 op1 = ia32_skip_downconv(op1);
946 new_op1 = be_transform_node(op1);
947 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
948 new_op1 = create_upconv(op1, node);
950 new_op1 = be_transform_node(op1);
953 /* the shift amount can be any mode that is bigger than 5 bits, since all
954 * other bits are ignored anyway */
955 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
956 ir_node *const op = get_Conv_op(op2);
957 if (mode_is_float(get_irn_mode(op)))
960 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
962 new_op2 = create_immediate_or_transform(op2, 0);
964 dbgi = get_irn_dbg_info(node);
965 block = get_nodes_block(node);
966 new_block = be_transform_node(block);
967 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
968 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
970 /* lowered shift instruction may have a dependency operand, handle it here */
971 if (get_irn_arity(node) == 3) {
972 /* we have a dependency */
973 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
974 add_irn_dep(new_node, new_dep);
982 * Construct a standard unary operation, set AM and immediate if required.
984 * @param op The operand
985 * @param func The node constructor function
986 * @return The constructed ia32 node.
988 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
992 ir_node *block, *new_block, *new_op, *new_node;
994 assert(flags == 0 || flags == match_mode_neutral);
995 if (flags & match_mode_neutral) {
996 op = ia32_skip_downconv(op);
999 new_op = be_transform_node(op);
1000 dbgi = get_irn_dbg_info(node);
1001 block = get_nodes_block(node);
1002 new_block = be_transform_node(block);
1003 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1005 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1010 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1011 ia32_address_t *addr)
1013 ir_node *base, *index, *res;
1017 base = ia32_new_NoReg_gp(env_cg);
1019 base = be_transform_node(base);
1022 index = addr->index;
1023 if (index == NULL) {
1024 index = ia32_new_NoReg_gp(env_cg);
1026 index = be_transform_node(index);
1029 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1030 set_address(res, addr);
1036 * Returns non-zero if a given address mode has a symbolic or
1037 * numerical offset != 0.
1039 static int am_has_immediates(const ia32_address_t *addr)
1041 return addr->offset != 0 || addr->symconst_ent != NULL
1042 || addr->frame_entity || addr->use_frame;
1046 * Creates an ia32 Add.
1048 * @return the created ia32 Add node
1050 static ir_node *gen_Add(ir_node *node) {
1051 ir_mode *mode = get_irn_mode(node);
1052 ir_node *op1 = get_Add_left(node);
1053 ir_node *op2 = get_Add_right(node);
1055 ir_node *block, *new_block, *new_node, *add_immediate_op;
1056 ia32_address_t addr;
1057 ia32_address_mode_t am;
1059 if (mode_is_float(mode)) {
1060 if (ia32_cg_config.use_sse2)
1061 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1062 match_commutative | match_am);
1064 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1065 match_commutative | match_am);
1068 ia32_mark_non_am(node);
1070 op2 = ia32_skip_downconv(op2);
1071 op1 = ia32_skip_downconv(op1);
1075 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1076 * 1. Add with immediate -> Lea
1077 * 2. Add with possible source address mode -> Add
1078 * 3. Otherwise -> Lea
1080 memset(&addr, 0, sizeof(addr));
1081 ia32_create_address_mode(&addr, node, /*force=*/1);
1082 add_immediate_op = NULL;
1084 dbgi = get_irn_dbg_info(node);
1085 block = get_nodes_block(node);
1086 new_block = be_transform_node(block);
1089 if(addr.base == NULL && addr.index == NULL) {
1090 ir_graph *irg = current_ir_graph;
1091 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1092 addr.symconst_sign, addr.offset);
1093 add_irn_dep(new_node, get_irg_frame(irg));
1094 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1097 /* add with immediate? */
1098 if(addr.index == NULL) {
1099 add_immediate_op = addr.base;
1100 } else if(addr.base == NULL && addr.scale == 0) {
1101 add_immediate_op = addr.index;
1104 if(add_immediate_op != NULL) {
1105 if(!am_has_immediates(&addr)) {
1106 #ifdef DEBUG_libfirm
1107 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1110 return be_transform_node(add_immediate_op);
1113 new_node = create_lea_from_address(dbgi, new_block, &addr);
1114 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1118 /* test if we can use source address mode */
1119 match_arguments(&am, block, op1, op2, NULL, match_commutative
1120 | match_mode_neutral | match_am | match_immediate | match_try_am);
1122 /* construct an Add with source address mode */
1123 if (am.op_type == ia32_AddrModeS) {
1124 ir_graph *irg = current_ir_graph;
1125 ia32_address_t *am_addr = &am.addr;
1126 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1127 am_addr->index, am_addr->mem, am.new_op1,
1129 set_am_attributes(new_node, &am);
1130 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1132 new_node = fix_mem_proj(new_node, &am);
1137 /* otherwise construct a lea */
1138 new_node = create_lea_from_address(dbgi, new_block, &addr);
1139 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1144 * Creates an ia32 Mul.
1146 * @return the created ia32 Mul node
1148 static ir_node *gen_Mul(ir_node *node) {
1149 ir_node *op1 = get_Mul_left(node);
1150 ir_node *op2 = get_Mul_right(node);
1151 ir_mode *mode = get_irn_mode(node);
1153 if (mode_is_float(mode)) {
1154 if (ia32_cg_config.use_sse2)
1155 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1156 match_commutative | match_am);
1158 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1159 match_commutative | match_am);
1161 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1162 match_commutative | match_am | match_mode_neutral |
1163 match_immediate | match_am_and_immediates);
1167 * Creates an ia32 Mulh.
1168 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1169 * this result while Mul returns the lower 32 bit.
1171 * @return the created ia32 Mulh node
1173 static ir_node *gen_Mulh(ir_node *node)
1175 ir_node *block = get_nodes_block(node);
1176 ir_node *new_block = be_transform_node(block);
1177 ir_graph *irg = current_ir_graph;
1178 dbg_info *dbgi = get_irn_dbg_info(node);
1179 ir_mode *mode = get_irn_mode(node);
1180 ir_node *op1 = get_Mulh_left(node);
1181 ir_node *op2 = get_Mulh_right(node);
1182 ir_node *proj_res_high;
1184 ia32_address_mode_t am;
1185 ia32_address_t *addr = &am.addr;
1187 assert(!mode_is_float(mode) && "Mulh with float not supported");
1188 assert(get_mode_size_bits(mode) == 32);
1190 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1192 if (mode_is_signed(mode)) {
1193 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1194 addr->index, addr->mem, am.new_op1,
1197 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1198 addr->index, addr->mem, am.new_op1,
1202 set_am_attributes(new_node, &am);
1203 /* we can't use source address mode anymore when using immediates */
1204 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1205 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1206 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1208 assert(get_irn_mode(new_node) == mode_T);
1210 fix_mem_proj(new_node, &am);
1212 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1213 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1214 mode_Iu, pn_ia32_IMul1OP_res_high);
1216 return proj_res_high;
1222 * Creates an ia32 And.
1224 * @return The created ia32 And node
1226 static ir_node *gen_And(ir_node *node) {
1227 ir_node *op1 = get_And_left(node);
1228 ir_node *op2 = get_And_right(node);
1229 assert(! mode_is_float(get_irn_mode(node)));
1231 /* is it a zero extension? */
1232 if (is_Const(op2)) {
1233 tarval *tv = get_Const_tarval(op2);
1234 long v = get_tarval_long(tv);
1236 if (v == 0xFF || v == 0xFFFF) {
1237 dbg_info *dbgi = get_irn_dbg_info(node);
1238 ir_node *block = get_nodes_block(node);
1245 assert(v == 0xFFFF);
1248 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1253 return gen_binop(node, op1, op2, new_rd_ia32_And,
1254 match_commutative | match_mode_neutral | match_am
1261 * Creates an ia32 Or.
1263 * @return The created ia32 Or node
1265 static ir_node *gen_Or(ir_node *node) {
1266 ir_node *op1 = get_Or_left(node);
1267 ir_node *op2 = get_Or_right(node);
1269 assert (! mode_is_float(get_irn_mode(node)));
1270 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1271 | match_mode_neutral | match_am | match_immediate);
1277 * Creates an ia32 Eor.
1279 * @return The created ia32 Eor node
1281 static ir_node *gen_Eor(ir_node *node) {
1282 ir_node *op1 = get_Eor_left(node);
1283 ir_node *op2 = get_Eor_right(node);
1285 assert(! mode_is_float(get_irn_mode(node)));
1286 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1287 | match_mode_neutral | match_am | match_immediate);
1292 * Creates an ia32 Sub.
1294 * @return The created ia32 Sub node
1296 static ir_node *gen_Sub(ir_node *node) {
1297 ir_node *op1 = get_Sub_left(node);
1298 ir_node *op2 = get_Sub_right(node);
1299 ir_mode *mode = get_irn_mode(node);
1301 if (mode_is_float(mode)) {
1302 if (ia32_cg_config.use_sse2)
1303 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1305 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1309 if (is_Const(op2)) {
1310 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1314 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1315 | match_am | match_immediate);
1319 * Generates an ia32 DivMod with additional infrastructure for the
1320 * register allocator if needed.
1322 static ir_node *create_Div(ir_node *node)
1324 ir_graph *irg = current_ir_graph;
1325 dbg_info *dbgi = get_irn_dbg_info(node);
1326 ir_node *block = get_nodes_block(node);
1327 ir_node *new_block = be_transform_node(block);
1334 ir_node *sign_extension;
1335 ia32_address_mode_t am;
1336 ia32_address_t *addr = &am.addr;
1338 /* the upper bits have random contents for smaller modes */
1339 switch (get_irn_opcode(node)) {
1341 op1 = get_Div_left(node);
1342 op2 = get_Div_right(node);
1343 mem = get_Div_mem(node);
1344 mode = get_Div_resmode(node);
1347 op1 = get_Mod_left(node);
1348 op2 = get_Mod_right(node);
1349 mem = get_Mod_mem(node);
1350 mode = get_Mod_resmode(node);
1353 op1 = get_DivMod_left(node);
1354 op2 = get_DivMod_right(node);
1355 mem = get_DivMod_mem(node);
1356 mode = get_DivMod_resmode(node);
1359 panic("invalid divmod node %+F", node);
1362 match_arguments(&am, block, op1, op2, NULL, match_am);
1364 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1365 is the memory of the consumed address. We can have only the second op as address
1366 in Div nodes, so check only op2. */
1367 if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1368 new_mem = be_transform_node(mem);
1369 if(!is_NoMem(addr->mem)) {
1373 new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1376 new_mem = addr->mem;
1379 if (mode_is_signed(mode)) {
1380 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1381 add_irn_dep(produceval, get_irg_frame(irg));
1382 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1385 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1386 addr->index, new_mem, am.new_op2,
1387 am.new_op1, sign_extension);
1389 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1390 add_irn_dep(sign_extension, get_irg_frame(irg));
1392 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1393 addr->index, new_mem, am.new_op2,
1394 am.new_op1, sign_extension);
1397 set_irn_pinned(new_node, get_irn_pinned(node));
1399 set_am_attributes(new_node, &am);
1400 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1402 new_node = fix_mem_proj(new_node, &am);
1408 static ir_node *gen_Mod(ir_node *node) {
1409 return create_Div(node);
1412 static ir_node *gen_Div(ir_node *node) {
1413 return create_Div(node);
1416 static ir_node *gen_DivMod(ir_node *node) {
1417 return create_Div(node);
1423 * Creates an ia32 floating Div.
1425 * @return The created ia32 xDiv node
1427 static ir_node *gen_Quot(ir_node *node)
1429 ir_node *op1 = get_Quot_left(node);
1430 ir_node *op2 = get_Quot_right(node);
1432 if (ia32_cg_config.use_sse2) {
1433 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1435 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1441 * Creates an ia32 Shl.
1443 * @return The created ia32 Shl node
1445 static ir_node *gen_Shl(ir_node *node) {
1446 ir_node *left = get_Shl_left(node);
1447 ir_node *right = get_Shl_right(node);
1449 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1450 match_mode_neutral | match_immediate);
1454 * Creates an ia32 Shr.
1456 * @return The created ia32 Shr node
1458 static ir_node *gen_Shr(ir_node *node) {
1459 ir_node *left = get_Shr_left(node);
1460 ir_node *right = get_Shr_right(node);
1462 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1468 * Creates an ia32 Sar.
1470 * @return The created ia32 Shrs node
1472 static ir_node *gen_Shrs(ir_node *node) {
1473 ir_node *left = get_Shrs_left(node);
1474 ir_node *right = get_Shrs_right(node);
1475 ir_mode *mode = get_irn_mode(node);
1477 if(is_Const(right) && mode == mode_Is) {
1478 tarval *tv = get_Const_tarval(right);
1479 long val = get_tarval_long(tv);
1481 /* this is a sign extension */
1482 ir_graph *irg = current_ir_graph;
1483 dbg_info *dbgi = get_irn_dbg_info(node);
1484 ir_node *block = be_transform_node(get_nodes_block(node));
1486 ir_node *new_op = be_transform_node(op);
1487 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1488 add_irn_dep(pval, get_irg_frame(irg));
1490 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1494 /* 8 or 16 bit sign extension? */
1495 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1496 ir_node *shl_left = get_Shl_left(left);
1497 ir_node *shl_right = get_Shl_right(left);
1498 if(is_Const(shl_right)) {
1499 tarval *tv1 = get_Const_tarval(right);
1500 tarval *tv2 = get_Const_tarval(shl_right);
1501 if(tv1 == tv2 && tarval_is_long(tv1)) {
1502 long val = get_tarval_long(tv1);
1503 if(val == 16 || val == 24) {
1504 dbg_info *dbgi = get_irn_dbg_info(node);
1505 ir_node *block = get_nodes_block(node);
1515 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1524 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1530 * Creates an ia32 Rol.
1532 * @param op1 The first operator
1533 * @param op2 The second operator
1534 * @return The created ia32 RotL node
1536 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1537 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1543 * Creates an ia32 Ror.
1544 * NOTE: There is no RotR with immediate because this would always be a RotL
1545 * "imm-mode_size_bits" which can be pre-calculated.
1547 * @param op1 The first operator
1548 * @param op2 The second operator
1549 * @return The created ia32 RotR node
1551 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1552 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1558 * Creates an ia32 RotR or RotL (depending on the found pattern).
1560 * @return The created ia32 RotL or RotR node
1562 static ir_node *gen_Rotl(ir_node *node) {
1563 ir_node *rotate = NULL;
1564 ir_node *op1 = get_Rotl_left(node);
1565 ir_node *op2 = get_Rotl_right(node);
1567 /* Firm has only RotL, so we are looking for a right (op2)
1568 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1569 that means we can create a RotR instead of an Add and a RotL */
1573 ir_node *left = get_Add_left(add);
1574 ir_node *right = get_Add_right(add);
1575 if (is_Const(right)) {
1576 tarval *tv = get_Const_tarval(right);
1577 ir_mode *mode = get_irn_mode(node);
1578 long bits = get_mode_size_bits(mode);
1580 if (is_Minus(left) &&
1581 tarval_is_long(tv) &&
1582 get_tarval_long(tv) == bits &&
1585 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1586 rotate = gen_Ror(node, op1, get_Minus_op(left));
1591 if (rotate == NULL) {
1592 rotate = gen_Rol(node, op1, op2);
1601 * Transforms a Minus node.
1603 * @return The created ia32 Minus node
1605 static ir_node *gen_Minus(ir_node *node)
1607 ir_node *op = get_Minus_op(node);
1608 ir_node *block = be_transform_node(get_nodes_block(node));
1609 ir_graph *irg = current_ir_graph;
1610 dbg_info *dbgi = get_irn_dbg_info(node);
1611 ir_mode *mode = get_irn_mode(node);
1616 if (mode_is_float(mode)) {
1617 ir_node *new_op = be_transform_node(op);
1618 if (ia32_cg_config.use_sse2) {
1619 /* TODO: non-optimal... if we have many xXors, then we should
1620 * rather create a load for the const and use that instead of
1621 * several AM nodes... */
1622 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1623 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1624 ir_node *nomem = new_rd_NoMem(irg);
1626 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1627 nomem, new_op, noreg_xmm);
1629 size = get_mode_size_bits(mode);
1630 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1632 set_ia32_am_sc(new_node, ent);
1633 set_ia32_op_type(new_node, ia32_AddrModeS);
1634 set_ia32_ls_mode(new_node, mode);
1636 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1639 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1642 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1648 * Transforms a Not node.
1650 * @return The created ia32 Not node
1652 static ir_node *gen_Not(ir_node *node) {
1653 ir_node *op = get_Not_op(node);
1655 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1656 assert (! mode_is_float(get_irn_mode(node)));
1658 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1664 * Transforms an Abs node.
1666 * @return The created ia32 Abs node
1668 static ir_node *gen_Abs(ir_node *node)
1670 ir_node *block = get_nodes_block(node);
1671 ir_node *new_block = be_transform_node(block);
1672 ir_node *op = get_Abs_op(node);
1673 ir_graph *irg = current_ir_graph;
1674 dbg_info *dbgi = get_irn_dbg_info(node);
1675 ir_mode *mode = get_irn_mode(node);
1676 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1677 ir_node *nomem = new_NoMem();
1683 if (mode_is_float(mode)) {
1684 new_op = be_transform_node(op);
1686 if (ia32_cg_config.use_sse2) {
1687 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1688 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1689 nomem, new_op, noreg_fp);
1691 size = get_mode_size_bits(mode);
1692 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1694 set_ia32_am_sc(new_node, ent);
1696 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1698 set_ia32_op_type(new_node, ia32_AddrModeS);
1699 set_ia32_ls_mode(new_node, mode);
1701 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1702 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1705 ir_node *xor, *pval, *sign_extension;
1707 if (get_mode_size_bits(mode) == 32) {
1708 new_op = be_transform_node(op);
1710 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1713 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1714 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1717 add_irn_dep(pval, get_irg_frame(irg));
1718 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1720 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1721 nomem, new_op, sign_extension);
1722 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1724 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1725 nomem, xor, sign_extension);
1726 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1733 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1735 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1736 dbg_info *dbgi = get_irn_dbg_info(cmp);
1737 ir_node *block = get_nodes_block(cmp);
1738 ir_node *new_block = be_transform_node(block);
1739 ir_node *op1 = be_transform_node(x);
1740 ir_node *op2 = be_transform_node(n);
1742 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1746 * Transform a node returning a "flag" result.
1748 * @param node the node to transform
1749 * @param pnc_out the compare mode to use
1751 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1760 /* we have a Cmp as input */
1761 if (is_Proj(node)) {
1762 ir_node *pred = get_Proj_pred(node);
1764 pn_Cmp pnc = get_Proj_proj(node);
1765 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1766 ir_node *l = get_Cmp_left(pred);
1767 ir_node *r = get_Cmp_right(pred);
1769 ir_node *la = get_And_left(l);
1770 ir_node *ra = get_And_right(l);
1772 ir_node *c = get_Shl_left(la);
1773 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1774 /* (1 << n) & ra) */
1775 ir_node *n = get_Shl_right(la);
1776 flags = gen_bt(pred, ra, n);
1777 /* we must generate a Jc/Jnc jump */
1778 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1781 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1786 ir_node *c = get_Shl_left(ra);
1787 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1788 /* la & (1 << n)) */
1789 ir_node *n = get_Shl_right(ra);
1790 flags = gen_bt(pred, la, n);
1791 /* we must generate a Jc/Jnc jump */
1792 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1795 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1801 flags = be_transform_node(pred);
1807 /* a mode_b value, we have to compare it against 0 */
1808 dbgi = get_irn_dbg_info(node);
1809 new_block = be_transform_node(get_nodes_block(node));
1810 new_op = be_transform_node(node);
1811 noreg = ia32_new_NoReg_gp(env_cg);
1812 nomem = new_NoMem();
1813 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1814 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1815 *pnc_out = pn_Cmp_Lg;
1820 * Transforms a Load.
1822 * @return the created ia32 Load node
1824 static ir_node *gen_Load(ir_node *node) {
1825 ir_node *old_block = get_nodes_block(node);
1826 ir_node *block = be_transform_node(old_block);
1827 ir_node *ptr = get_Load_ptr(node);
1828 ir_node *mem = get_Load_mem(node);
1829 ir_node *new_mem = be_transform_node(mem);
1832 ir_graph *irg = current_ir_graph;
1833 dbg_info *dbgi = get_irn_dbg_info(node);
1834 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1835 ir_mode *mode = get_Load_mode(node);
1838 ia32_address_t addr;
1840 /* construct load address */
1841 memset(&addr, 0, sizeof(addr));
1842 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1849 base = be_transform_node(base);
1855 index = be_transform_node(index);
1858 if (mode_is_float(mode)) {
1859 if (ia32_cg_config.use_sse2) {
1860 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1862 res_mode = mode_xmm;
1864 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1866 res_mode = mode_vfp;
1869 assert(mode != mode_b);
1871 /* create a conv node with address mode for smaller modes */
1872 if(get_mode_size_bits(mode) < 32) {
1873 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1874 new_mem, noreg, mode);
1876 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1881 set_irn_pinned(new_node, get_irn_pinned(node));
1882 set_ia32_op_type(new_node, ia32_AddrModeS);
1883 set_ia32_ls_mode(new_node, mode);
1884 set_address(new_node, &addr);
1886 if(get_irn_pinned(node) == op_pin_state_floats) {
1887 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1890 /* make sure we are scheduled behind the initial IncSP/Barrier
1891 * to avoid spills being placed before it
1893 if (block == get_irg_start_block(irg)) {
1894 add_irn_dep(new_node, get_irg_frame(irg));
1897 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1902 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1903 ir_node *ptr, ir_node *other)
1910 /* we only use address mode if we're the only user of the load */
1911 if(get_irn_n_edges(node) > 1)
1914 load = get_Proj_pred(node);
1917 if(get_nodes_block(load) != block)
1920 /* Store should be attached to the load */
1921 if(!is_Proj(mem) || get_Proj_pred(mem) != load)
1923 /* store should have the same pointer as the load */
1924 if(get_Load_ptr(load) != ptr)
1927 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1928 if(other != NULL && get_nodes_block(other) == block
1929 && heights_reachable_in_block(heights, other, load))
1935 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
1937 mark_irn_visited(old_node);
1938 be_set_transformed_node(old_node, new_node);
1941 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1942 ir_node *mem, ir_node *ptr, ir_mode *mode,
1943 construct_binop_dest_func *func,
1944 construct_binop_dest_func *func8bit,
1945 match_flags_t flags)
1947 ir_node *src_block = get_nodes_block(node);
1949 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1950 ir_graph *irg = current_ir_graph;
1956 ia32_address_mode_t am;
1957 ia32_address_t *addr = &am.addr;
1958 memset(&am, 0, sizeof(am));
1960 assert(flags & match_dest_am);
1961 assert(flags & match_immediate); /* there is no destam node without... */
1962 commutative = (flags & match_commutative) != 0;
1964 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
1965 build_address(&am, op1);
1966 new_op = create_immediate_or_transform(op2, 0);
1967 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1968 build_address(&am, op2);
1969 new_op = create_immediate_or_transform(op1, 0);
1974 if(addr->base == NULL)
1975 addr->base = noreg_gp;
1976 if(addr->index == NULL)
1977 addr->index = noreg_gp;
1978 if(addr->mem == NULL)
1979 addr->mem = new_NoMem();
1981 dbgi = get_irn_dbg_info(node);
1982 block = be_transform_node(src_block);
1983 if(get_mode_size_bits(mode) == 8) {
1984 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
1987 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
1990 set_address(new_node, addr);
1991 set_ia32_op_type(new_node, ia32_AddrModeD);
1992 set_ia32_ls_mode(new_node, mode);
1993 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1995 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
1996 mem_proj = be_transform_node(am.mem_proj);
1997 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2002 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2003 ir_node *ptr, ir_mode *mode,
2004 construct_unop_dest_func *func)
2006 ir_graph *irg = current_ir_graph;
2007 ir_node *src_block = get_nodes_block(node);
2012 ia32_address_mode_t am;
2013 ia32_address_t *addr = &am.addr;
2014 memset(&am, 0, sizeof(am));
2016 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2019 build_address(&am, op);
2021 dbgi = get_irn_dbg_info(node);
2022 block = be_transform_node(src_block);
2023 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2024 set_address(new_node, addr);
2025 set_ia32_op_type(new_node, ia32_AddrModeD);
2026 set_ia32_ls_mode(new_node, mode);
2027 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2029 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2030 mem_proj = be_transform_node(am.mem_proj);
2031 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2036 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2037 ir_mode *mode = get_irn_mode(node);
2038 ir_node *mux_true = get_Mux_true(node);
2039 ir_node *mux_false = get_Mux_false(node);
2050 ia32_address_t addr;
2052 if(get_mode_size_bits(mode) != 8)
2055 if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2057 } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2063 build_address_ptr(&addr, ptr, mem);
2065 irg = current_ir_graph;
2066 dbgi = get_irn_dbg_info(node);
2067 block = get_nodes_block(node);
2068 new_block = be_transform_node(block);
2069 cond = get_Mux_sel(node);
2070 flags = get_flags_node(cond, &pnc);
2071 new_mem = be_transform_node(mem);
2072 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2073 addr.index, addr.mem, flags, pnc, negated);
2074 set_address(new_node, &addr);
2075 set_ia32_op_type(new_node, ia32_AddrModeD);
2076 set_ia32_ls_mode(new_node, mode);
2077 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2082 static ir_node *try_create_dest_am(ir_node *node) {
2083 ir_node *val = get_Store_value(node);
2084 ir_node *mem = get_Store_mem(node);
2085 ir_node *ptr = get_Store_ptr(node);
2086 ir_mode *mode = get_irn_mode(val);
2087 unsigned bits = get_mode_size_bits(mode);
2092 /* handle only GP modes for now... */
2093 if(!ia32_mode_needs_gp_reg(mode))
2097 /* store must be the only user of the val node */
2098 if(get_irn_n_edges(val) > 1)
2100 /* skip pointless convs */
2102 ir_node *conv_op = get_Conv_op(val);
2103 ir_mode *pred_mode = get_irn_mode(conv_op);
2104 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2112 /* value must be in the same block */
2113 if(get_nodes_block(node) != get_nodes_block(val))
2116 switch (get_irn_opcode(val)) {
2118 op1 = get_Add_left(val);
2119 op2 = get_Add_right(val);
2120 if(is_Const_1(op2)) {
2121 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2122 new_rd_ia32_IncMem);
2124 } else if(is_Const_Minus_1(op2)) {
2125 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2126 new_rd_ia32_DecMem);
2129 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2130 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2131 match_dest_am | match_commutative |
2135 op1 = get_Sub_left(val);
2136 op2 = get_Sub_right(val);
2138 ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2141 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2142 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2143 match_dest_am | match_immediate |
2147 op1 = get_And_left(val);
2148 op2 = get_And_right(val);
2149 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2150 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2151 match_dest_am | match_commutative |
2155 op1 = get_Or_left(val);
2156 op2 = get_Or_right(val);
2157 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2158 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2159 match_dest_am | match_commutative |
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_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2167 match_dest_am | match_commutative |
2171 op1 = get_Shl_left(val);
2172 op2 = get_Shl_right(val);
2173 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2174 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2175 match_dest_am | match_immediate);
2178 op1 = get_Shr_left(val);
2179 op2 = get_Shr_right(val);
2180 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2181 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2182 match_dest_am | match_immediate);
2185 op1 = get_Shrs_left(val);
2186 op2 = get_Shrs_right(val);
2187 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2188 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2189 match_dest_am | match_immediate);
2192 op1 = get_Rotl_left(val);
2193 op2 = get_Rotl_right(val);
2194 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2195 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2196 match_dest_am | match_immediate);
2198 /* TODO: match ROR patterns... */
2200 new_node = try_create_SetMem(val, ptr, mem);
2203 op1 = get_Minus_op(val);
2204 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2207 /* should be lowered already */
2208 assert(mode != mode_b);
2209 op1 = get_Not_op(val);
2210 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2216 if(new_node != NULL) {
2217 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2218 get_irn_pinned(node) == op_pin_state_pinned) {
2219 set_irn_pinned(new_node, op_pin_state_pinned);
2226 static int is_float_to_int32_conv(const ir_node *node)
2228 ir_mode *mode = get_irn_mode(node);
2232 if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode))
2234 /* don't report unsigned as conv to 32bit, because we really need to do
2235 * a vfist with 64bit signed in this case */
2236 if(!mode_is_signed(mode))
2241 conv_op = get_Conv_op(node);
2242 conv_mode = get_irn_mode(conv_op);
2244 if(!mode_is_float(conv_mode))
2251 * Transform a Store(floatConst).
2253 * @return the created ia32 Store node
2255 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2256 ir_mode *mode = get_irn_mode(cns);
2257 int size = get_mode_size_bits(mode);
2258 tarval *tv = get_Const_tarval(cns);
2259 ir_node *block = get_nodes_block(node);
2260 ir_node *new_block = be_transform_node(block);
2261 ir_node *ptr = get_Store_ptr(node);
2262 ir_node *mem = get_Store_mem(node);
2263 ir_graph *irg = current_ir_graph;
2264 dbg_info *dbgi = get_irn_dbg_info(node);
2265 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2268 ia32_address_t addr;
2270 unsigned val = get_tarval_sub_bits(tv, 0) |
2271 (get_tarval_sub_bits(tv, 1) << 8) |
2272 (get_tarval_sub_bits(tv, 2) << 16) |
2273 (get_tarval_sub_bits(tv, 3) << 24);
2274 ir_node *imm = create_Immediate(NULL, 0, val);
2276 /* construct store address */
2277 memset(&addr, 0, sizeof(addr));
2278 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2280 if (addr.base == NULL) {
2283 addr.base = be_transform_node(addr.base);
2286 if (addr.index == NULL) {
2289 addr.index = be_transform_node(addr.index);
2291 addr.mem = be_transform_node(mem);
2293 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2294 addr.index, addr.mem, imm);
2296 set_irn_pinned(new_node, get_irn_pinned(node));
2297 set_ia32_op_type(new_node, ia32_AddrModeD);
2298 set_ia32_ls_mode(new_node, mode_Iu);
2300 set_address(new_node, &addr);
2302 /** add more stores if needed */
2304 unsigned val = get_tarval_sub_bits(tv, ofs) |
2305 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2306 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2307 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2308 ir_node *imm = create_Immediate(NULL, 0, val);
2311 addr.mem = new_node;
2313 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2314 addr.index, addr.mem, imm);
2316 set_irn_pinned(new_node, get_irn_pinned(node));
2317 set_ia32_op_type(new_node, ia32_AddrModeD);
2318 set_ia32_ls_mode(new_node, mode_Iu);
2320 set_address(new_node, &addr);
2325 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2330 * Generate a vfist or vfisttp instruction.
2332 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2333 ir_node *mem, ir_node *val, ir_node **fist)
2337 if (ia32_cg_config.use_fisttp) {
2338 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2339 if other users exists */
2340 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2341 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2342 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2343 be_new_Keep(reg_class, irg, block, 1, &value);
2345 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2348 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2351 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2357 * Transforms a normal Store.
2359 * @return the created ia32 Store node
2361 static ir_node *gen_normal_Store(ir_node *node)
2363 ir_node *val = get_Store_value(node);
2364 ir_mode *mode = get_irn_mode(val);
2365 ir_node *block = get_nodes_block(node);
2366 ir_node *new_block = be_transform_node(block);
2367 ir_node *ptr = get_Store_ptr(node);
2368 ir_node *mem = get_Store_mem(node);
2369 ir_graph *irg = current_ir_graph;
2370 dbg_info *dbgi = get_irn_dbg_info(node);
2371 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2372 ir_node *new_val, *new_node, *store;
2373 ia32_address_t addr;
2375 /* check for destination address mode */
2376 new_node = try_create_dest_am(node);
2377 if (new_node != NULL)
2380 /* construct store address */
2381 memset(&addr, 0, sizeof(addr));
2382 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2384 if (addr.base == NULL) {
2387 addr.base = be_transform_node(addr.base);
2390 if (addr.index == NULL) {
2393 addr.index = be_transform_node(addr.index);
2395 addr.mem = be_transform_node(mem);
2397 if (mode_is_float(mode)) {
2398 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2400 while (is_Conv(val) && mode == get_irn_mode(val)) {
2401 ir_node *op = get_Conv_op(val);
2402 if (!mode_is_float(get_irn_mode(op)))
2406 new_val = be_transform_node(val);
2407 if (ia32_cg_config.use_sse2) {
2408 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2409 addr.index, addr.mem, new_val);
2411 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2412 addr.index, addr.mem, new_val, mode);
2415 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2416 val = get_Conv_op(val);
2418 /* TODO: is this optimisation still necessary at all (middleend)? */
2419 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2420 while (is_Conv(val)) {
2421 ir_node *op = get_Conv_op(val);
2422 if (!mode_is_float(get_irn_mode(op)))
2424 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2428 new_val = be_transform_node(val);
2429 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2431 new_val = create_immediate_or_transform(val, 0);
2432 assert(mode != mode_b);
2434 if (get_mode_size_bits(mode) == 8) {
2435 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2436 addr.index, addr.mem, new_val);
2438 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2439 addr.index, addr.mem, new_val);
2444 set_irn_pinned(store, get_irn_pinned(node));
2445 set_ia32_op_type(store, ia32_AddrModeD);
2446 set_ia32_ls_mode(store, mode);
2448 set_address(store, &addr);
2449 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2455 * Transforms a Store.
2457 * @return the created ia32 Store node
2459 static ir_node *gen_Store(ir_node *node)
2461 ir_node *val = get_Store_value(node);
2462 ir_mode *mode = get_irn_mode(val);
2464 if (mode_is_float(mode) && is_Const(val)) {
2467 /* we are storing a floating point constant */
2468 if (ia32_cg_config.use_sse2) {
2469 transform = !is_simple_sse_Const(val);
2471 transform = !is_simple_x87_Const(val);
2474 return gen_float_const_Store(node, val);
2476 return gen_normal_Store(node);
2480 * Transforms a Switch.
2482 * @return the created ia32 SwitchJmp node
2484 static ir_node *create_Switch(ir_node *node)
2486 ir_graph *irg = current_ir_graph;
2487 dbg_info *dbgi = get_irn_dbg_info(node);
2488 ir_node *block = be_transform_node(get_nodes_block(node));
2489 ir_node *sel = get_Cond_selector(node);
2490 ir_node *new_sel = be_transform_node(sel);
2491 int switch_min = INT_MAX;
2492 int switch_max = INT_MIN;
2493 long default_pn = get_Cond_defaultProj(node);
2495 const ir_edge_t *edge;
2497 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2499 /* determine the smallest switch case value */
2500 foreach_out_edge(node, edge) {
2501 ir_node *proj = get_edge_src_irn(edge);
2502 long pn = get_Proj_proj(proj);
2503 if(pn == default_pn)
2512 if((unsigned) (switch_max - switch_min) > 256000) {
2513 panic("Size of switch %+F bigger than 256000", node);
2516 if (switch_min != 0) {
2517 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2519 /* if smallest switch case is not 0 we need an additional sub */
2520 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2521 add_ia32_am_offs_int(new_sel, -switch_min);
2522 set_ia32_op_type(new_sel, ia32_AddrModeS);
2524 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2527 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2528 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2534 * Transform a Cond node.
2536 static ir_node *gen_Cond(ir_node *node) {
2537 ir_node *block = get_nodes_block(node);
2538 ir_node *new_block = be_transform_node(block);
2539 ir_graph *irg = current_ir_graph;
2540 dbg_info *dbgi = get_irn_dbg_info(node);
2541 ir_node *sel = get_Cond_selector(node);
2542 ir_mode *sel_mode = get_irn_mode(sel);
2543 ir_node *flags = NULL;
2547 if (sel_mode != mode_b) {
2548 return create_Switch(node);
2551 /* we get flags from a Cmp */
2552 flags = get_flags_node(sel, &pnc);
2554 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2555 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2561 * Transforms a CopyB node.
2563 * @return The transformed node.
2565 static ir_node *gen_CopyB(ir_node *node) {
2566 ir_node *block = be_transform_node(get_nodes_block(node));
2567 ir_node *src = get_CopyB_src(node);
2568 ir_node *new_src = be_transform_node(src);
2569 ir_node *dst = get_CopyB_dst(node);
2570 ir_node *new_dst = be_transform_node(dst);
2571 ir_node *mem = get_CopyB_mem(node);
2572 ir_node *new_mem = be_transform_node(mem);
2573 ir_node *res = NULL;
2574 ir_graph *irg = current_ir_graph;
2575 dbg_info *dbgi = get_irn_dbg_info(node);
2576 int size = get_type_size_bytes(get_CopyB_type(node));
2579 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2580 /* then we need the size explicitly in ECX. */
2581 if (size >= 32 * 4) {
2582 rem = size & 0x3; /* size % 4 */
2585 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2586 add_irn_dep(res, get_irg_frame(irg));
2588 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2591 ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2594 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2597 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2602 static ir_node *gen_be_Copy(ir_node *node)
2604 ir_node *new_node = be_duplicate_node(node);
2605 ir_mode *mode = get_irn_mode(new_node);
2607 if (ia32_mode_needs_gp_reg(mode)) {
2608 set_irn_mode(new_node, mode_Iu);
2614 static ir_node *create_Fucom(ir_node *node)
2616 ir_graph *irg = current_ir_graph;
2617 dbg_info *dbgi = get_irn_dbg_info(node);
2618 ir_node *block = get_nodes_block(node);
2619 ir_node *new_block = be_transform_node(block);
2620 ir_node *left = get_Cmp_left(node);
2621 ir_node *new_left = be_transform_node(left);
2622 ir_node *right = get_Cmp_right(node);
2626 if(ia32_cg_config.use_fucomi) {
2627 new_right = be_transform_node(right);
2628 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2630 set_ia32_commutative(new_node);
2631 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2633 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2634 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2637 new_right = be_transform_node(right);
2638 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2642 set_ia32_commutative(new_node);
2644 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2646 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2647 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2653 static ir_node *create_Ucomi(ir_node *node)
2655 ir_graph *irg = current_ir_graph;
2656 dbg_info *dbgi = get_irn_dbg_info(node);
2657 ir_node *src_block = get_nodes_block(node);
2658 ir_node *new_block = be_transform_node(src_block);
2659 ir_node *left = get_Cmp_left(node);
2660 ir_node *right = get_Cmp_right(node);
2662 ia32_address_mode_t am;
2663 ia32_address_t *addr = &am.addr;
2665 match_arguments(&am, src_block, left, right, NULL,
2666 match_commutative | match_am);
2668 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2669 addr->mem, am.new_op1, am.new_op2,
2671 set_am_attributes(new_node, &am);
2673 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2675 new_node = fix_mem_proj(new_node, &am);
2681 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2682 * to fold an and into a test node
2684 static int can_fold_test_and(ir_node *node)
2686 const ir_edge_t *edge;
2688 /** we can only have eq and lg projs */
2689 foreach_out_edge(node, edge) {
2690 ir_node *proj = get_edge_src_irn(edge);
2691 pn_Cmp pnc = get_Proj_proj(proj);
2692 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2700 * Generate code for a Cmp.
2702 static ir_node *gen_Cmp(ir_node *node)
2704 ir_graph *irg = current_ir_graph;
2705 dbg_info *dbgi = get_irn_dbg_info(node);
2706 ir_node *block = get_nodes_block(node);
2707 ir_node *new_block = be_transform_node(block);
2708 ir_node *left = get_Cmp_left(node);
2709 ir_node *right = get_Cmp_right(node);
2710 ir_mode *cmp_mode = get_irn_mode(left);
2712 ia32_address_mode_t am;
2713 ia32_address_t *addr = &am.addr;
2716 if(mode_is_float(cmp_mode)) {
2717 if (ia32_cg_config.use_sse2) {
2718 return create_Ucomi(node);
2720 return create_Fucom(node);
2724 assert(ia32_mode_needs_gp_reg(cmp_mode));
2726 /* we prefer the Test instruction where possible except cases where
2727 * we can use SourceAM */
2728 cmp_unsigned = !mode_is_signed(cmp_mode);
2729 if (is_Const_0(right)) {
2731 get_irn_n_edges(left) == 1 &&
2732 can_fold_test_and(node)) {
2733 /* Test(and_left, and_right) */
2734 ir_node *and_left = get_And_left(left);
2735 ir_node *and_right = get_And_right(left);
2736 ir_mode *mode = get_irn_mode(and_left);
2738 match_arguments(&am, block, and_left, and_right, NULL,
2740 match_am | match_8bit_am | match_16bit_am |
2741 match_am_and_immediates | match_immediate |
2742 match_8bit | match_16bit);
2743 if (get_mode_size_bits(mode) == 8) {
2744 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2745 addr->index, addr->mem, am.new_op1,
2746 am.new_op2, am.ins_permuted,
2749 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2750 addr->index, addr->mem, am.new_op1,
2751 am.new_op2, am.ins_permuted, cmp_unsigned);
2754 match_arguments(&am, block, NULL, left, NULL,
2755 match_am | match_8bit_am | match_16bit_am |
2756 match_8bit | match_16bit);
2757 if (am.op_type == ia32_AddrModeS) {
2759 ir_node *imm_zero = try_create_Immediate(right, 0);
2760 if (get_mode_size_bits(cmp_mode) == 8) {
2761 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2762 addr->index, addr->mem, am.new_op2,
2763 imm_zero, am.ins_permuted,
2766 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2767 addr->index, addr->mem, am.new_op2,
2768 imm_zero, am.ins_permuted, cmp_unsigned);
2771 /* Test(left, left) */
2772 if (get_mode_size_bits(cmp_mode) == 8) {
2773 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2774 addr->index, addr->mem, am.new_op2,
2775 am.new_op2, am.ins_permuted,
2778 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2779 addr->index, addr->mem, am.new_op2,
2780 am.new_op2, am.ins_permuted,
2786 /* Cmp(left, right) */
2787 match_arguments(&am, block, left, right, NULL,
2788 match_commutative | match_am | match_8bit_am |
2789 match_16bit_am | match_am_and_immediates |
2790 match_immediate | match_8bit | match_16bit);
2791 if (get_mode_size_bits(cmp_mode) == 8) {
2792 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2793 addr->index, addr->mem, am.new_op1,
2794 am.new_op2, am.ins_permuted,
2797 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2798 addr->index, addr->mem, am.new_op1,
2799 am.new_op2, am.ins_permuted, cmp_unsigned);
2802 set_am_attributes(new_node, &am);
2803 set_ia32_ls_mode(new_node, cmp_mode);
2805 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2807 new_node = fix_mem_proj(new_node, &am);
2812 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2815 ir_graph *irg = current_ir_graph;
2816 dbg_info *dbgi = get_irn_dbg_info(node);
2817 ir_node *block = get_nodes_block(node);
2818 ir_node *new_block = be_transform_node(block);
2819 ir_node *val_true = get_Mux_true(node);
2820 ir_node *val_false = get_Mux_false(node);
2822 match_flags_t match_flags;
2823 ia32_address_mode_t am;
2824 ia32_address_t *addr;
2826 assert(ia32_cg_config.use_cmov);
2827 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2831 match_flags = match_commutative | match_am | match_16bit_am |
2834 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2836 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2837 addr->mem, am.new_op1, am.new_op2, new_flags,
2838 am.ins_permuted, pnc);
2839 set_am_attributes(new_node, &am);
2841 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2843 new_node = fix_mem_proj(new_node, &am);
2849 * Creates a ia32 Setcc instruction.
2851 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2852 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2855 ir_graph *irg = current_ir_graph;
2856 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2857 ir_node *nomem = new_NoMem();
2858 ir_mode *mode = get_irn_mode(orig_node);
2861 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2862 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2864 /* we might need to conv the result up */
2865 if (get_mode_size_bits(mode) > 8) {
2866 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2867 nomem, new_node, mode_Bu);
2868 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2875 * Create instruction for an unsigned Difference or Zero.
2877 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2878 ir_graph *irg = current_ir_graph;
2879 ir_mode *mode = get_irn_mode(psi);
2880 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2883 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2884 match_mode_neutral | match_am | match_immediate | match_two_users);
2886 block = get_nodes_block(new_node);
2888 if (is_Proj(new_node)) {
2889 sub = get_Proj_pred(new_node);
2890 assert(is_ia32_Sub(sub));
2893 set_irn_mode(sub, mode_T);
2894 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2896 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2898 dbgi = get_irn_dbg_info(psi);
2899 noreg = ia32_new_NoReg_gp(env_cg);
2900 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2901 nomem = new_NoMem();
2902 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2904 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2905 set_ia32_commutative(new_node);
2910 * Transforms a Mux node into CMov.
2912 * @return The transformed node.
2914 static ir_node *gen_Mux(ir_node *node)
2916 dbg_info *dbgi = get_irn_dbg_info(node);
2917 ir_node *block = get_nodes_block(node);
2918 ir_node *new_block = be_transform_node(block);
2919 ir_node *mux_true = get_Mux_true(node);
2920 ir_node *mux_false = get_Mux_false(node);
2921 ir_node *cond = get_Mux_sel(node);
2922 ir_mode *mode = get_irn_mode(node);
2925 assert(get_irn_mode(cond) == mode_b);
2927 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2928 if (mode_is_float(mode)) {
2929 ir_node *cmp = get_Proj_pred(cond);
2930 ir_node *cmp_left = get_Cmp_left(cmp);
2931 ir_node *cmp_right = get_Cmp_right(cmp);
2932 pn_Cmp pnc = get_Proj_proj(cond);
2934 if (ia32_cg_config.use_sse2) {
2935 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2936 if (cmp_left == mux_true && cmp_right == mux_false) {
2937 /* Mux(a <= b, a, b) => MIN */
2938 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2939 match_commutative | match_am | match_two_users);
2940 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2941 /* Mux(a <= b, b, a) => MAX */
2942 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2943 match_commutative | match_am | match_two_users);
2945 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2946 if (cmp_left == mux_true && cmp_right == mux_false) {
2947 /* Mux(a >= b, a, b) => MAX */
2948 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2949 match_commutative | match_am | match_two_users);
2950 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2951 /* Mux(a >= b, b, a) => MIN */
2952 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2953 match_commutative | match_am | match_two_users);
2957 panic("cannot transform floating point Mux");
2963 assert(ia32_mode_needs_gp_reg(mode));
2965 if (is_Proj(cond)) {
2966 ir_node *cmp = get_Proj_pred(cond);
2968 ir_node *cmp_left = get_Cmp_left(cmp);
2969 ir_node *cmp_right = get_Cmp_right(cmp);
2970 pn_Cmp pnc = get_Proj_proj(cond);
2972 /* check for unsigned Doz first */
2973 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2974 is_Const_0(mux_false) && is_Sub(mux_true) &&
2975 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2976 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2977 return create_Doz(node, cmp_left, cmp_right);
2978 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2979 is_Const_0(mux_true) && is_Sub(mux_false) &&
2980 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2981 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2982 return create_Doz(node, cmp_left, cmp_right);
2987 flags = get_flags_node(cond, &pnc);
2989 if (is_Const(mux_true) && is_Const(mux_false)) {
2990 /* both are const, good */
2991 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2992 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2993 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2994 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2996 /* Not that simple. */
3001 new_node = create_CMov(node, cond, flags, pnc);
3009 * Create a conversion from x87 state register to general purpose.
3011 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3012 ir_node *block = be_transform_node(get_nodes_block(node));
3013 ir_node *op = get_Conv_op(node);
3014 ir_node *new_op = be_transform_node(op);
3015 ia32_code_gen_t *cg = env_cg;
3016 ir_graph *irg = current_ir_graph;
3017 dbg_info *dbgi = get_irn_dbg_info(node);
3018 ir_node *noreg = ia32_new_NoReg_gp(cg);
3019 ir_mode *mode = get_irn_mode(node);
3020 ir_node *fist, *load, *mem;
3022 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3023 set_irn_pinned(fist, op_pin_state_floats);
3024 set_ia32_use_frame(fist);
3025 set_ia32_op_type(fist, ia32_AddrModeD);
3027 assert(get_mode_size_bits(mode) <= 32);
3028 /* exception we can only store signed 32 bit integers, so for unsigned
3029 we store a 64bit (signed) integer and load the lower bits */
3030 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3031 set_ia32_ls_mode(fist, mode_Ls);
3033 set_ia32_ls_mode(fist, mode_Is);
3035 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3038 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3040 set_irn_pinned(load, op_pin_state_floats);
3041 set_ia32_use_frame(load);
3042 set_ia32_op_type(load, ia32_AddrModeS);
3043 set_ia32_ls_mode(load, mode_Is);
3044 if(get_ia32_ls_mode(fist) == mode_Ls) {
3045 ia32_attr_t *attr = get_ia32_attr(load);
3046 attr->data.need_64bit_stackent = 1;
3048 ia32_attr_t *attr = get_ia32_attr(load);
3049 attr->data.need_32bit_stackent = 1;
3051 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3053 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3057 * Creates a x87 strict Conv by placing a Store and a Load
3059 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3061 ir_node *block = get_nodes_block(node);
3062 ir_graph *irg = current_ir_graph;
3063 dbg_info *dbgi = get_irn_dbg_info(node);
3064 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3065 ir_node *nomem = new_NoMem();
3066 ir_node *frame = get_irg_frame(irg);
3067 ir_node *store, *load;
3070 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3072 set_ia32_use_frame(store);
3073 set_ia32_op_type(store, ia32_AddrModeD);
3074 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3076 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3078 set_ia32_use_frame(load);
3079 set_ia32_op_type(load, ia32_AddrModeS);
3080 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3082 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3087 * Create a conversion from general purpose to x87 register
3089 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
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;
3105 /* fild can use source AM if the operand is a signed 32bit integer */
3106 if (src_mode == mode_Is) {
3107 ia32_address_mode_t am;
3109 match_arguments(&am, src_block, NULL, op, NULL,
3110 match_am | match_try_am);
3111 if (am.op_type == ia32_AddrModeS) {
3112 ia32_address_t *addr = &am.addr;
3114 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3115 addr->index, addr->mem);
3116 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3119 set_am_attributes(fild, &am);
3120 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3122 fix_mem_proj(fild, &am);
3127 if(new_op == NULL) {
3128 new_op = be_transform_node(op);
3131 noreg = ia32_new_NoReg_gp(env_cg);
3132 nomem = new_NoMem();
3133 mode = get_irn_mode(op);
3135 /* first convert to 32 bit signed if necessary */
3136 src_bits = get_mode_size_bits(src_mode);
3137 if (src_bits == 8) {
3138 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3140 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3142 } else if (src_bits < 32) {
3143 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3145 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3149 assert(get_mode_size_bits(mode) == 32);
3152 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3155 set_ia32_use_frame(store);
3156 set_ia32_op_type(store, ia32_AddrModeD);
3157 set_ia32_ls_mode(store, mode_Iu);
3159 /* exception for 32bit unsigned, do a 64bit spill+load */
3160 if(!mode_is_signed(mode)) {
3163 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3165 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3166 get_irg_frame(irg), noreg, nomem,
3169 set_ia32_use_frame(zero_store);
3170 set_ia32_op_type(zero_store, ia32_AddrModeD);
3171 add_ia32_am_offs_int(zero_store, 4);
3172 set_ia32_ls_mode(zero_store, mode_Iu);
3177 store = new_rd_Sync(dbgi, irg, block, 2, in);
3178 store_mode = mode_Ls;
3180 store_mode = mode_Is;
3184 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3186 set_ia32_use_frame(fild);
3187 set_ia32_op_type(fild, ia32_AddrModeS);
3188 set_ia32_ls_mode(fild, store_mode);
3190 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3196 * Create a conversion from one integer mode into another one
3198 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3199 dbg_info *dbgi, ir_node *block, ir_node *op,
3202 ir_graph *irg = current_ir_graph;
3203 int src_bits = get_mode_size_bits(src_mode);
3204 int tgt_bits = get_mode_size_bits(tgt_mode);
3205 ir_node *new_block = be_transform_node(block);
3207 ir_mode *smaller_mode;
3209 ia32_address_mode_t am;
3210 ia32_address_t *addr = &am.addr;
3213 if (src_bits < tgt_bits) {
3214 smaller_mode = src_mode;
3215 smaller_bits = src_bits;
3217 smaller_mode = tgt_mode;
3218 smaller_bits = tgt_bits;
3221 #ifdef DEBUG_libfirm
3223 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3228 match_arguments(&am, block, NULL, op, NULL,
3229 match_8bit | match_16bit |
3230 match_am | match_8bit_am | match_16bit_am);
3231 if (smaller_bits == 8) {
3232 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3233 addr->index, addr->mem, am.new_op2,
3236 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3237 addr->index, addr->mem, am.new_op2,
3240 set_am_attributes(new_node, &am);
3241 /* match_arguments assume that out-mode = in-mode, this isn't true here
3243 set_ia32_ls_mode(new_node, smaller_mode);
3244 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3245 new_node = fix_mem_proj(new_node, &am);
3250 * Transforms a Conv node.
3252 * @return The created ia32 Conv node
3254 static ir_node *gen_Conv(ir_node *node) {
3255 ir_node *block = get_nodes_block(node);
3256 ir_node *new_block = be_transform_node(block);
3257 ir_node *op = get_Conv_op(node);
3258 ir_node *new_op = NULL;
3259 ir_graph *irg = current_ir_graph;
3260 dbg_info *dbgi = get_irn_dbg_info(node);
3261 ir_mode *src_mode = get_irn_mode(op);
3262 ir_mode *tgt_mode = get_irn_mode(node);
3263 int src_bits = get_mode_size_bits(src_mode);
3264 int tgt_bits = get_mode_size_bits(tgt_mode);
3265 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3266 ir_node *nomem = new_rd_NoMem(irg);
3267 ir_node *res = NULL;
3269 if (src_mode == mode_b) {
3270 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3271 /* nothing to do, we already model bools as 0/1 ints */
3272 return be_transform_node(op);
3275 if (src_mode == tgt_mode) {
3276 if (get_Conv_strict(node)) {
3277 if (ia32_cg_config.use_sse2) {
3278 /* when we are in SSE mode, we can kill all strict no-op conversion */
3279 return be_transform_node(op);
3282 /* this should be optimized already, but who knows... */
3283 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3284 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3285 return be_transform_node(op);
3289 if (mode_is_float(src_mode)) {
3290 new_op = be_transform_node(op);
3291 /* we convert from float ... */
3292 if (mode_is_float(tgt_mode)) {
3293 if(src_mode == mode_E && tgt_mode == mode_D
3294 && !get_Conv_strict(node)) {
3295 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3300 if (ia32_cg_config.use_sse2) {
3301 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3302 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3304 set_ia32_ls_mode(res, tgt_mode);
3306 if(get_Conv_strict(node)) {
3307 res = gen_x87_strict_conv(tgt_mode, new_op);
3308 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3311 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3316 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3317 if (ia32_cg_config.use_sse2) {
3318 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3320 set_ia32_ls_mode(res, src_mode);
3322 return gen_x87_fp_to_gp(node);
3326 /* we convert from int ... */
3327 if (mode_is_float(tgt_mode)) {
3329 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3330 if (ia32_cg_config.use_sse2) {
3331 new_op = be_transform_node(op);
3332 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3334 set_ia32_ls_mode(res, tgt_mode);
3336 res = gen_x87_gp_to_fp(node, src_mode);
3337 if(get_Conv_strict(node)) {
3338 /* The strict-Conv is only necessary, if the int mode has more bits
3339 * than the float mantissa */
3340 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3341 size_t float_mantissa;
3342 /* FIXME There is no way to get the mantissa size of a mode */
3343 switch (get_mode_size_bits(tgt_mode)) {
3344 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3345 case 64: float_mantissa = 52 + 1; break;
3346 case 80: float_mantissa = 64 + 1; break;
3347 default: float_mantissa = 0; break;
3349 if (float_mantissa < int_mantissa) {
3350 res = gen_x87_strict_conv(tgt_mode, res);
3351 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3356 } else if(tgt_mode == mode_b) {
3357 /* mode_b lowering already took care that we only have 0/1 values */
3358 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3359 src_mode, tgt_mode));
3360 return be_transform_node(op);
3363 if (src_bits == tgt_bits) {
3364 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3365 src_mode, tgt_mode));
3366 return be_transform_node(op);
3369 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3377 static ir_node *create_immediate_or_transform(ir_node *node,
3378 char immediate_constraint_type)
3380 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3381 if (new_node == NULL) {
3382 new_node = be_transform_node(node);
3388 * Transforms a FrameAddr into an ia32 Add.
3390 static ir_node *gen_be_FrameAddr(ir_node *node) {
3391 ir_node *block = be_transform_node(get_nodes_block(node));
3392 ir_node *op = be_get_FrameAddr_frame(node);
3393 ir_node *new_op = be_transform_node(op);
3394 ir_graph *irg = current_ir_graph;
3395 dbg_info *dbgi = get_irn_dbg_info(node);
3396 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3399 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3400 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3401 set_ia32_use_frame(new_node);
3403 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3409 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3411 static ir_node *gen_be_Return(ir_node *node) {
3412 ir_graph *irg = current_ir_graph;
3413 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3414 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3415 ir_entity *ent = get_irg_entity(irg);
3416 ir_type *tp = get_entity_type(ent);
3421 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3422 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3425 int pn_ret_val, pn_ret_mem, arity, i;
3427 assert(ret_val != NULL);
3428 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3429 return be_duplicate_node(node);
3432 res_type = get_method_res_type(tp, 0);
3434 if (! is_Primitive_type(res_type)) {
3435 return be_duplicate_node(node);
3438 mode = get_type_mode(res_type);
3439 if (! mode_is_float(mode)) {
3440 return be_duplicate_node(node);
3443 assert(get_method_n_ress(tp) == 1);
3445 pn_ret_val = get_Proj_proj(ret_val);
3446 pn_ret_mem = get_Proj_proj(ret_mem);
3448 /* get the Barrier */
3449 barrier = get_Proj_pred(ret_val);
3451 /* get result input of the Barrier */
3452 ret_val = get_irn_n(barrier, pn_ret_val);
3453 new_ret_val = be_transform_node(ret_val);
3455 /* get memory input of the Barrier */
3456 ret_mem = get_irn_n(barrier, pn_ret_mem);
3457 new_ret_mem = be_transform_node(ret_mem);
3459 frame = get_irg_frame(irg);
3461 dbgi = get_irn_dbg_info(barrier);
3462 block = be_transform_node(get_nodes_block(barrier));
3464 noreg = ia32_new_NoReg_gp(env_cg);
3466 /* store xmm0 onto stack */
3467 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3468 new_ret_mem, new_ret_val);
3469 set_ia32_ls_mode(sse_store, mode);
3470 set_ia32_op_type(sse_store, ia32_AddrModeD);
3471 set_ia32_use_frame(sse_store);
3473 /* load into x87 register */
3474 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3475 set_ia32_op_type(fld, ia32_AddrModeS);
3476 set_ia32_use_frame(fld);
3478 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3479 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3481 /* create a new barrier */
3482 arity = get_irn_arity(barrier);
3483 in = alloca(arity * sizeof(in[0]));
3484 for (i = 0; i < arity; ++i) {
3487 if (i == pn_ret_val) {
3489 } else if (i == pn_ret_mem) {
3492 ir_node *in = get_irn_n(barrier, i);
3493 new_in = be_transform_node(in);
3498 new_barrier = new_ir_node(dbgi, irg, block,
3499 get_irn_op(barrier), get_irn_mode(barrier),
3501 copy_node_attr(barrier, new_barrier);
3502 be_duplicate_deps(barrier, new_barrier);
3503 be_set_transformed_node(barrier, new_barrier);
3504 mark_irn_visited(barrier);
3506 /* transform normally */
3507 return be_duplicate_node(node);
3511 * Transform a be_AddSP into an ia32_SubSP.
3513 static ir_node *gen_be_AddSP(ir_node *node)
3515 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3516 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3518 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
3522 * Transform a be_SubSP into an ia32_AddSP
3524 static ir_node *gen_be_SubSP(ir_node *node)
3526 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3527 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3529 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
3533 * Change some phi modes
3535 static ir_node *gen_Phi(ir_node *node) {
3536 ir_node *block = be_transform_node(get_nodes_block(node));
3537 ir_graph *irg = current_ir_graph;
3538 dbg_info *dbgi = get_irn_dbg_info(node);
3539 ir_mode *mode = get_irn_mode(node);
3542 if(ia32_mode_needs_gp_reg(mode)) {
3543 /* we shouldn't have any 64bit stuff around anymore */
3544 assert(get_mode_size_bits(mode) <= 32);
3545 /* all integer operations are on 32bit registers now */
3547 } else if(mode_is_float(mode)) {
3548 if (ia32_cg_config.use_sse2) {
3555 /* phi nodes allow loops, so we use the old arguments for now
3556 * and fix this later */
3557 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3558 get_irn_in(node) + 1);
3559 copy_node_attr(node, phi);
3560 be_duplicate_deps(node, phi);
3562 be_set_transformed_node(node, phi);
3563 be_enqueue_preds(node);
3571 static ir_node *gen_IJmp(ir_node *node)
3573 ir_node *block = get_nodes_block(node);
3574 ir_node *new_block = be_transform_node(block);
3575 dbg_info *dbgi = get_irn_dbg_info(node);
3576 ir_node *op = get_IJmp_target(node);
3578 ia32_address_mode_t am;
3579 ia32_address_t *addr = &am.addr;
3581 assert(get_irn_mode(op) == mode_P);
3583 match_arguments(&am, block, NULL, op, NULL,
3584 match_am | match_8bit_am | match_16bit_am |
3585 match_immediate | match_8bit | match_16bit);
3587 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3588 addr->base, addr->index, addr->mem,
3590 set_am_attributes(new_node, &am);
3591 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3593 new_node = fix_mem_proj(new_node, &am);
3599 * Transform a Bound node.
3601 static ir_node *gen_Bound(ir_node *node)
3604 ir_node *lower = get_Bound_lower(node);
3605 dbg_info *dbgi = get_irn_dbg_info(node);
3607 if (is_Const_0(lower)) {
3608 /* typical case for Java */
3609 ir_node *sub, *res, *flags, *block;
3610 ir_graph *irg = current_ir_graph;
3612 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3613 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3615 block = get_nodes_block(res);
3616 if (! is_Proj(res)) {
3618 set_irn_mode(sub, mode_T);
3619 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3621 sub = get_Proj_pred(res);
3623 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3624 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3625 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3627 panic("generic Bound not supported in ia32 Backend");
3633 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3636 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3637 ir_node *val, ir_node *mem);
3640 * Transforms a lowered Load into a "real" one.
3642 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
3644 ir_node *block = be_transform_node(get_nodes_block(node));
3645 ir_node *ptr = get_irn_n(node, 0);
3646 ir_node *new_ptr = be_transform_node(ptr);
3647 ir_node *mem = get_irn_n(node, 1);
3648 ir_node *new_mem = be_transform_node(mem);
3649 ir_graph *irg = current_ir_graph;
3650 dbg_info *dbgi = get_irn_dbg_info(node);
3651 ir_mode *mode = get_ia32_ls_mode(node);
3652 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3655 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
3657 set_ia32_op_type(new_op, ia32_AddrModeS);
3658 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
3659 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
3660 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
3661 if (is_ia32_am_sc_sign(node))
3662 set_ia32_am_sc_sign(new_op);
3663 set_ia32_ls_mode(new_op, mode);
3664 if (is_ia32_use_frame(node)) {
3665 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3666 set_ia32_use_frame(new_op);
3669 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3675 * Transforms a lowered Store into a "real" one.
3677 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
3679 ir_node *block = be_transform_node(get_nodes_block(node));
3680 ir_node *ptr = get_irn_n(node, 0);
3681 ir_node *new_ptr = be_transform_node(ptr);
3682 ir_node *val = get_irn_n(node, 1);
3683 ir_node *new_val = be_transform_node(val);
3684 ir_node *mem = get_irn_n(node, 2);
3685 ir_node *new_mem = be_transform_node(mem);
3686 ir_graph *irg = current_ir_graph;
3687 dbg_info *dbgi = get_irn_dbg_info(node);
3688 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3689 ir_mode *mode = get_ia32_ls_mode(node);
3693 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
3695 am_offs = get_ia32_am_offs_int(node);
3696 add_ia32_am_offs_int(new_op, am_offs);
3698 set_ia32_op_type(new_op, ia32_AddrModeD);
3699 set_ia32_ls_mode(new_op, mode);
3700 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3701 set_ia32_use_frame(new_op);
3703 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3708 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3710 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3711 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3713 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3714 match_immediate | match_mode_neutral);
3717 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3719 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3720 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3721 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3725 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3727 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3728 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3729 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3733 static ir_node *gen_ia32_l_Add(ir_node *node) {
3734 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3735 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3736 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3737 match_commutative | match_am | match_immediate |
3738 match_mode_neutral);
3740 if(is_Proj(lowered)) {
3741 lowered = get_Proj_pred(lowered);
3743 assert(is_ia32_Add(lowered));
3744 set_irn_mode(lowered, mode_T);
3750 static ir_node *gen_ia32_l_Adc(ir_node *node)
3752 return gen_binop_flags(node, new_rd_ia32_Adc,
3753 match_commutative | match_am | match_immediate |
3754 match_mode_neutral);
3758 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
3760 * @param node The node to transform
3761 * @return the created ia32 vfild node
3763 static ir_node *gen_ia32_l_vfild(ir_node *node) {
3764 return gen_lowered_Load(node, new_rd_ia32_vfild);
3768 * Transforms an ia32_l_Load into a "real" ia32_Load node
3770 * @param node The node to transform
3771 * @return the created ia32 Load node
3773 static ir_node *gen_ia32_l_Load(ir_node *node) {
3774 return gen_lowered_Load(node, new_rd_ia32_Load);
3778 * Transforms an ia32_l_Store into a "real" ia32_Store node
3780 * @param node The node to transform
3781 * @return the created ia32 Store node
3783 static ir_node *gen_ia32_l_Store(ir_node *node) {
3784 return gen_lowered_Store(node, new_rd_ia32_Store);
3788 * Transforms a l_vfist into a "real" vfist node.
3790 * @param node The node to transform
3791 * @return the created ia32 vfist node
3793 static ir_node *gen_ia32_l_vfist(ir_node *node) {
3794 ir_node *block = be_transform_node(get_nodes_block(node));
3795 ir_node *ptr = get_irn_n(node, 0);
3796 ir_node *new_ptr = be_transform_node(ptr);
3797 ir_node *val = get_irn_n(node, 1);
3798 ir_node *new_val = be_transform_node(val);
3799 ir_node *mem = get_irn_n(node, 2);
3800 ir_node *new_mem = be_transform_node(mem);
3801 ir_graph *irg = current_ir_graph;
3802 dbg_info *dbgi = get_irn_dbg_info(node);
3803 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3804 ir_mode *mode = get_ia32_ls_mode(node);
3805 ir_node *memres, *fist;
3808 memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
3809 am_offs = get_ia32_am_offs_int(node);
3810 add_ia32_am_offs_int(fist, am_offs);
3812 set_ia32_op_type(fist, ia32_AddrModeD);
3813 set_ia32_ls_mode(fist, mode);
3814 set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
3815 set_ia32_use_frame(fist);
3817 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3823 * Transforms a l_MulS into a "real" MulS node.
3825 * @return the created ia32 Mul node
3827 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3828 ir_node *left = get_binop_left(node);
3829 ir_node *right = get_binop_right(node);
3831 return gen_binop(node, left, right, new_rd_ia32_Mul,
3832 match_commutative | match_am | match_mode_neutral);
3836 * Transforms a l_IMulS into a "real" IMul1OPS node.
3838 * @return the created ia32 IMul1OP node
3840 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3841 ir_node *left = get_binop_left(node);
3842 ir_node *right = get_binop_right(node);
3844 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3845 match_commutative | match_am | match_mode_neutral);
3848 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3849 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3850 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3851 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3852 match_am | match_immediate | match_mode_neutral);
3854 if(is_Proj(lowered)) {
3855 lowered = get_Proj_pred(lowered);
3857 assert(is_ia32_Sub(lowered));
3858 set_irn_mode(lowered, mode_T);
3864 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3865 return gen_binop_flags(node, new_rd_ia32_Sbb,
3866 match_am | match_immediate | match_mode_neutral);
3870 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3871 * op1 - target to be shifted
3872 * op2 - contains bits to be shifted into target
3874 * Only op3 can be an immediate.
3876 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3877 ir_node *low, ir_node *count)
3879 ir_node *block = get_nodes_block(node);
3880 ir_node *new_block = be_transform_node(block);
3881 ir_graph *irg = current_ir_graph;
3882 dbg_info *dbgi = get_irn_dbg_info(node);
3883 ir_node *new_high = be_transform_node(high);
3884 ir_node *new_low = be_transform_node(low);
3888 /* the shift amount can be any mode that is bigger than 5 bits, since all
3889 * other bits are ignored anyway */
3890 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
3891 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3892 count = get_Conv_op(count);
3894 new_count = create_immediate_or_transform(count, 0);
3896 if (is_ia32_l_ShlD(node)) {
3897 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3900 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3903 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3908 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3910 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3911 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3912 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3913 return gen_lowered_64bit_shifts(node, high, low, count);
3916 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3918 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3919 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3920 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3921 return gen_lowered_64bit_shifts(node, high, low, count);
3924 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3925 ir_node *src_block = get_nodes_block(node);
3926 ir_node *block = be_transform_node(src_block);
3927 ir_graph *irg = current_ir_graph;
3928 dbg_info *dbgi = get_irn_dbg_info(node);
3929 ir_node *frame = get_irg_frame(irg);
3930 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3931 ir_node *nomem = new_NoMem();
3932 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3933 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3934 ir_node *new_val_low = be_transform_node(val_low);
3935 ir_node *new_val_high = be_transform_node(val_high);
3940 ir_node *store_high;
3942 if(!mode_is_signed(get_irn_mode(val_high))) {
3943 panic("unsigned long long -> float not supported yet (%+F)", node);
3947 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3949 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3951 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3952 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3954 set_ia32_use_frame(store_low);
3955 set_ia32_use_frame(store_high);
3956 set_ia32_op_type(store_low, ia32_AddrModeD);
3957 set_ia32_op_type(store_high, ia32_AddrModeD);
3958 set_ia32_ls_mode(store_low, mode_Iu);
3959 set_ia32_ls_mode(store_high, mode_Is);
3960 add_ia32_am_offs_int(store_high, 4);
3964 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3967 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3969 set_ia32_use_frame(fild);
3970 set_ia32_op_type(fild, ia32_AddrModeS);
3971 set_ia32_ls_mode(fild, mode_Ls);
3973 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3975 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3978 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3979 ir_node *src_block = get_nodes_block(node);
3980 ir_node *block = be_transform_node(src_block);
3981 ir_graph *irg = current_ir_graph;
3982 dbg_info *dbgi = get_irn_dbg_info(node);
3983 ir_node *frame = get_irg_frame(irg);
3984 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3985 ir_node *nomem = new_NoMem();
3986 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3987 ir_node *new_val = be_transform_node(val);
3988 ir_node *fist, *mem;
3990 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3991 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3992 set_ia32_use_frame(fist);
3993 set_ia32_op_type(fist, ia32_AddrModeD);
3994 set_ia32_ls_mode(fist, mode_Ls);
4000 * the BAD transformer.
4002 static ir_node *bad_transform(ir_node *node) {
4003 panic("No transform function for %+F available.\n", node);
4007 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4008 ir_graph *irg = current_ir_graph;
4009 ir_node *block = be_transform_node(get_nodes_block(node));
4010 ir_node *pred = get_Proj_pred(node);
4011 ir_node *new_pred = be_transform_node(pred);
4012 ir_node *frame = get_irg_frame(irg);
4013 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4014 dbg_info *dbgi = get_irn_dbg_info(node);
4015 long pn = get_Proj_proj(node);
4020 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4021 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4022 set_ia32_use_frame(load);
4023 set_ia32_op_type(load, ia32_AddrModeS);
4024 set_ia32_ls_mode(load, mode_Iu);
4025 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4026 * 32 bit from it with this particular load */
4027 attr = get_ia32_attr(load);
4028 attr->data.need_64bit_stackent = 1;
4030 if (pn == pn_ia32_l_FloattoLL_res_high) {
4031 add_ia32_am_offs_int(load, 4);
4033 assert(pn == pn_ia32_l_FloattoLL_res_low);
4036 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4042 * Transform the Projs of an AddSP.
4044 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4045 ir_node *block = be_transform_node(get_nodes_block(node));
4046 ir_node *pred = get_Proj_pred(node);
4047 ir_node *new_pred = be_transform_node(pred);
4048 ir_graph *irg = current_ir_graph;
4049 dbg_info *dbgi = get_irn_dbg_info(node);
4050 long proj = get_Proj_proj(node);
4052 if (proj == pn_be_AddSP_sp) {
4053 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4054 pn_ia32_SubSP_stack);
4055 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4057 } else if(proj == pn_be_AddSP_res) {
4058 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4059 pn_ia32_SubSP_addr);
4060 } else if (proj == pn_be_AddSP_M) {
4061 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4065 return new_rd_Unknown(irg, get_irn_mode(node));
4069 * Transform the Projs of a SubSP.
4071 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4072 ir_node *block = be_transform_node(get_nodes_block(node));
4073 ir_node *pred = get_Proj_pred(node);
4074 ir_node *new_pred = be_transform_node(pred);
4075 ir_graph *irg = current_ir_graph;
4076 dbg_info *dbgi = get_irn_dbg_info(node);
4077 long proj = get_Proj_proj(node);
4079 if (proj == pn_be_SubSP_sp) {
4080 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4081 pn_ia32_AddSP_stack);
4082 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4084 } else if (proj == pn_be_SubSP_M) {
4085 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4089 return new_rd_Unknown(irg, get_irn_mode(node));
4093 * Transform and renumber the Projs from a Load.
4095 static ir_node *gen_Proj_Load(ir_node *node) {
4097 ir_node *block = be_transform_node(get_nodes_block(node));
4098 ir_node *pred = get_Proj_pred(node);
4099 ir_graph *irg = current_ir_graph;
4100 dbg_info *dbgi = get_irn_dbg_info(node);
4101 long proj = get_Proj_proj(node);
4103 /* loads might be part of source address mode matches, so we don't
4104 * transform the ProjMs yet (with the exception of loads whose result is
4107 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4110 /* this is needed, because sometimes we have loops that are only
4111 reachable through the ProjM */
4112 be_enqueue_preds(node);
4113 /* do it in 2 steps, to silence firm verifier */
4114 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4115 set_Proj_proj(res, pn_ia32_mem);
4119 /* renumber the proj */
4120 new_pred = be_transform_node(pred);
4121 if (is_ia32_Load(new_pred)) {
4124 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4126 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4127 case pn_Load_X_regular:
4128 return new_rd_Jmp(dbgi, irg, block);
4129 case pn_Load_X_except:
4130 /* This Load might raise an exception. Mark it. */
4131 set_ia32_exc_label(new_pred, 1);
4132 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4136 } else if (is_ia32_Conv_I2I(new_pred) ||
4137 is_ia32_Conv_I2I8Bit(new_pred)) {
4138 set_irn_mode(new_pred, mode_T);
4139 if (proj == pn_Load_res) {
4140 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4141 } else if (proj == pn_Load_M) {
4142 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4144 } else if (is_ia32_xLoad(new_pred)) {
4147 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4149 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4150 case pn_Load_X_regular:
4151 return new_rd_Jmp(dbgi, irg, block);
4152 case pn_Load_X_except:
4153 /* This Load might raise an exception. Mark it. */
4154 set_ia32_exc_label(new_pred, 1);
4155 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4159 } else if (is_ia32_vfld(new_pred)) {
4162 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4164 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4165 case pn_Load_X_regular:
4166 return new_rd_Jmp(dbgi, irg, block);
4167 case pn_Load_X_except:
4168 /* This Load might raise an exception. Mark it. */
4169 set_ia32_exc_label(new_pred, 1);
4170 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4175 /* can happen for ProJMs when source address mode happened for the
4178 /* however it should not be the result proj, as that would mean the
4179 load had multiple users and should not have been used for
4181 if (proj != pn_Load_M) {
4182 panic("internal error: transformed node not a Load");
4184 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4188 return new_rd_Unknown(irg, get_irn_mode(node));
4192 * Transform and renumber the Projs from a DivMod like instruction.
4194 static ir_node *gen_Proj_DivMod(ir_node *node) {
4195 ir_node *block = be_transform_node(get_nodes_block(node));
4196 ir_node *pred = get_Proj_pred(node);
4197 ir_node *new_pred = be_transform_node(pred);
4198 ir_graph *irg = current_ir_graph;
4199 dbg_info *dbgi = get_irn_dbg_info(node);
4200 ir_mode *mode = get_irn_mode(node);
4201 long proj = get_Proj_proj(node);
4203 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4205 switch (get_irn_opcode(pred)) {
4209 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4211 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4212 case pn_Div_X_regular:
4213 return new_rd_Jmp(dbgi, irg, block);
4214 case pn_Div_X_except:
4215 set_ia32_exc_label(new_pred, 1);
4216 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4224 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4226 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4227 case pn_Mod_X_except:
4228 set_ia32_exc_label(new_pred, 1);
4229 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4237 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4238 case pn_DivMod_res_div:
4239 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4240 case pn_DivMod_res_mod:
4241 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4242 case pn_DivMod_X_regular:
4243 return new_rd_Jmp(dbgi, irg, block);
4244 case pn_DivMod_X_except:
4245 set_ia32_exc_label(new_pred, 1);
4246 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4256 return new_rd_Unknown(irg, mode);
4260 * Transform and renumber the Projs from a CopyB.
4262 static ir_node *gen_Proj_CopyB(ir_node *node) {
4263 ir_node *block = be_transform_node(get_nodes_block(node));
4264 ir_node *pred = get_Proj_pred(node);
4265 ir_node *new_pred = be_transform_node(pred);
4266 ir_graph *irg = current_ir_graph;
4267 dbg_info *dbgi = get_irn_dbg_info(node);
4268 ir_mode *mode = get_irn_mode(node);
4269 long proj = get_Proj_proj(node);
4272 case pn_CopyB_M_regular:
4273 if (is_ia32_CopyB_i(new_pred)) {
4274 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4275 } else if (is_ia32_CopyB(new_pred)) {
4276 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4284 return new_rd_Unknown(irg, mode);
4288 * Transform and renumber the Projs from a Quot.
4290 static ir_node *gen_Proj_Quot(ir_node *node) {
4291 ir_node *block = be_transform_node(get_nodes_block(node));
4292 ir_node *pred = get_Proj_pred(node);
4293 ir_node *new_pred = be_transform_node(pred);
4294 ir_graph *irg = current_ir_graph;
4295 dbg_info *dbgi = get_irn_dbg_info(node);
4296 ir_mode *mode = get_irn_mode(node);
4297 long proj = get_Proj_proj(node);
4301 if (is_ia32_xDiv(new_pred)) {
4302 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4303 } else if (is_ia32_vfdiv(new_pred)) {
4304 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4308 if (is_ia32_xDiv(new_pred)) {
4309 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4310 } else if (is_ia32_vfdiv(new_pred)) {
4311 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4314 case pn_Quot_X_regular:
4315 case pn_Quot_X_except:
4321 return new_rd_Unknown(irg, mode);
4325 * Transform the Thread Local Storage Proj.
4327 static ir_node *gen_Proj_tls(ir_node *node) {
4328 ir_node *block = be_transform_node(get_nodes_block(node));
4329 ir_graph *irg = current_ir_graph;
4330 dbg_info *dbgi = NULL;
4331 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4336 static ir_node *gen_be_Call(ir_node *node) {
4337 ir_node *res = be_duplicate_node(node);
4338 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4343 static ir_node *gen_be_IncSP(ir_node *node) {
4344 ir_node *res = be_duplicate_node(node);
4345 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4351 * Transform the Projs from a be_Call.
4353 static ir_node *gen_Proj_be_Call(ir_node *node) {
4354 ir_node *block = be_transform_node(get_nodes_block(node));
4355 ir_node *call = get_Proj_pred(node);
4356 ir_node *new_call = be_transform_node(call);
4357 ir_graph *irg = current_ir_graph;
4358 dbg_info *dbgi = get_irn_dbg_info(node);
4359 ir_type *method_type = be_Call_get_type(call);
4360 int n_res = get_method_n_ress(method_type);
4361 long proj = get_Proj_proj(node);
4362 ir_mode *mode = get_irn_mode(node);
4364 const arch_register_class_t *cls;
4366 /* The following is kinda tricky: If we're using SSE, then we have to
4367 * move the result value of the call in floating point registers to an
4368 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4369 * after the call, we have to make sure to correctly make the
4370 * MemProj and the result Proj use these 2 nodes
4372 if (proj == pn_be_Call_M_regular) {
4373 // get new node for result, are we doing the sse load/store hack?
4374 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4375 ir_node *call_res_new;
4376 ir_node *call_res_pred = NULL;
4378 if (call_res != NULL) {
4379 call_res_new = be_transform_node(call_res);
4380 call_res_pred = get_Proj_pred(call_res_new);
4383 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4384 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4385 pn_be_Call_M_regular);
4387 assert(is_ia32_xLoad(call_res_pred));
4388 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4392 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4393 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4395 ir_node *frame = get_irg_frame(irg);
4396 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4398 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4401 /* in case there is no memory output: create one to serialize the copy
4403 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4404 pn_be_Call_M_regular);
4405 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4406 pn_be_Call_first_res);
4408 /* store st(0) onto stack */
4409 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4411 set_ia32_op_type(fstp, ia32_AddrModeD);
4412 set_ia32_use_frame(fstp);
4414 /* load into SSE register */
4415 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4417 set_ia32_op_type(sse_load, ia32_AddrModeS);
4418 set_ia32_use_frame(sse_load);
4420 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4426 /* transform call modes */
4427 if (mode_is_data(mode)) {
4428 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4432 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4436 * Transform the Projs from a Cmp.
4438 static ir_node *gen_Proj_Cmp(ir_node *node)
4440 /* this probably means not all mode_b nodes were lowered... */
4441 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4446 * Transform the Projs from a Bound.
4448 static ir_node *gen_Proj_Bound(ir_node *node)
4450 ir_node *new_node, *block;
4451 ir_node *pred = get_Proj_pred(node);
4453 switch (get_Proj_proj(node)) {
4455 return be_transform_node(get_Bound_mem(pred));
4456 case pn_Bound_X_regular:
4457 new_node = be_transform_node(pred);
4458 block = get_nodes_block(new_node);
4459 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4460 case pn_Bound_X_except:
4461 new_node = be_transform_node(pred);
4462 block = get_nodes_block(new_node);
4463 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4465 return be_transform_node(get_Bound_index(pred));
4467 panic("unsupported Proj from Bound");
4471 static ir_node *gen_Proj_ASM(ir_node *node)
4477 if (get_irn_mode(node) != mode_M)
4478 return be_duplicate_node(node);
4480 pred = get_Proj_pred(node);
4481 new_pred = be_transform_node(pred);
4482 block = get_nodes_block(new_pred);
4483 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4484 get_ia32_n_res(new_pred) + 1);
4488 * Transform and potentially renumber Proj nodes.
4490 static ir_node *gen_Proj(ir_node *node) {
4491 ir_node *pred = get_Proj_pred(node);
4494 switch (get_irn_opcode(pred)) {
4496 proj = get_Proj_proj(node);
4497 if (proj == pn_Store_M) {
4498 return be_transform_node(pred);
4501 return new_r_Bad(current_ir_graph);
4504 return gen_Proj_Load(node);
4506 return gen_Proj_ASM(node);
4510 return gen_Proj_DivMod(node);
4512 return gen_Proj_CopyB(node);
4514 return gen_Proj_Quot(node);
4516 return gen_Proj_be_SubSP(node);
4518 return gen_Proj_be_AddSP(node);
4520 return gen_Proj_be_Call(node);
4522 return gen_Proj_Cmp(node);
4524 return gen_Proj_Bound(node);
4526 proj = get_Proj_proj(node);
4527 if (proj == pn_Start_X_initial_exec) {
4528 ir_node *block = get_nodes_block(pred);
4529 dbg_info *dbgi = get_irn_dbg_info(node);
4532 /* we exchange the ProjX with a jump */
4533 block = be_transform_node(block);
4534 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
4537 if (node == be_get_old_anchor(anchor_tls)) {
4538 return gen_Proj_tls(node);
4543 if (is_ia32_l_FloattoLL(pred)) {
4544 return gen_Proj_l_FloattoLL(node);
4546 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4550 ir_mode *mode = get_irn_mode(node);
4551 if (ia32_mode_needs_gp_reg(mode)) {
4552 ir_node *new_pred = be_transform_node(pred);
4553 ir_node *block = be_transform_node(get_nodes_block(node));
4554 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4555 mode_Iu, get_Proj_proj(node));
4556 #ifdef DEBUG_libfirm
4557 new_proj->node_nr = node->node_nr;
4563 return be_duplicate_node(node);
4567 * Enters all transform functions into the generic pointer
4569 static void register_transformers(void)
4573 /* first clear the generic function pointer for all ops */
4574 clear_irp_opcodes_generic_func();
4576 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4577 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4615 /* transform ops from intrinsic lowering */
4631 GEN(ia32_l_LLtoFloat);
4632 GEN(ia32_l_FloattoLL);
4638 /* we should never see these nodes */
4653 /* handle generic backend nodes */
4662 op_Mulh = get_op_Mulh();
4671 * Pre-transform all unknown and noreg nodes.
4673 static void ia32_pretransform_node(void *arch_cg) {
4674 ia32_code_gen_t *cg = arch_cg;
4676 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4677 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4678 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4679 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4680 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4681 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4686 * Walker, checks if all ia32 nodes producing more than one result have
4687 * its Projs, otherwise creates new Projs and keep them using a be_Keep node.
4689 static void add_missing_keep_walker(ir_node *node, void *data)
4692 unsigned found_projs = 0;
4693 const ir_edge_t *edge;
4694 ir_mode *mode = get_irn_mode(node);
4699 if(!is_ia32_irn(node))
4702 n_outs = get_ia32_n_res(node);
4705 if(is_ia32_SwitchJmp(node))
4708 assert(n_outs < (int) sizeof(unsigned) * 8);
4709 foreach_out_edge(node, edge) {
4710 ir_node *proj = get_edge_src_irn(edge);
4711 int pn = get_Proj_proj(proj);
4713 if (get_irn_mode(proj) == mode_M)
4716 assert(pn < n_outs);
4717 found_projs |= 1 << pn;
4721 /* are keeps missing? */
4723 for(i = 0; i < n_outs; ++i) {
4726 const arch_register_req_t *req;
4727 const arch_register_class_t *cls;
4729 if(found_projs & (1 << i)) {
4733 req = get_ia32_out_req(node, i);
4738 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4742 block = get_nodes_block(node);
4743 in[0] = new_r_Proj(current_ir_graph, block, node,
4744 arch_register_class_mode(cls), i);
4745 if(last_keep != NULL) {
4746 be_Keep_add_node(last_keep, cls, in[0]);
4748 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4749 if(sched_is_scheduled(node)) {
4750 sched_add_after(node, last_keep);
4757 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4760 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4762 ir_graph *irg = be_get_birg_irg(cg->birg);
4763 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4766 /* do the transformation */
4767 void ia32_transform_graph(ia32_code_gen_t *cg) {
4769 ir_graph *irg = cg->irg;
4771 register_transformers();
4773 initial_fpcw = NULL;
4775 BE_TIMER_PUSH(t_heights);
4776 heights = heights_new(irg);
4777 BE_TIMER_POP(t_heights);
4778 ia32_calculate_non_address_mode_nodes(cg->birg);
4780 /* the transform phase is not safe for CSE (yet) because several nodes get
4781 * attributes set after their creation */
4782 cse_last = get_opt_cse();
4785 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4787 set_opt_cse(cse_last);
4789 ia32_free_non_address_mode_nodes();
4790 heights_free(heights);
4794 void ia32_init_transform(void)
4796 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");