2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
34 #include "irgraph_t.h"
39 #include "iredges_t.h"
52 #include "../benode_t.h"
53 #include "../besched.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
60 #include "bearch_ia32_t.h"
61 #include "ia32_common_transform.h"
62 #include "ia32_nodes_attr.h"
63 #include "ia32_transform.h"
64 #include "ia32_new_nodes.h"
65 #include "ia32_map_regs.h"
66 #include "ia32_dbg_stat.h"
67 #include "ia32_optimize.h"
68 #include "ia32_util.h"
69 #include "ia32_address_mode.h"
70 #include "ia32_architecture.h"
72 #include "gen_ia32_regalloc_if.h"
74 #define SFP_SIGN "0x80000000"
75 #define DFP_SIGN "0x8000000000000000"
76 #define SFP_ABS "0x7FFFFFFF"
77 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
78 #define DFP_INTMAX "9223372036854775807"
80 #define TP_SFP_SIGN "ia32_sfp_sign"
81 #define TP_DFP_SIGN "ia32_dfp_sign"
82 #define TP_SFP_ABS "ia32_sfp_abs"
83 #define TP_DFP_ABS "ia32_dfp_abs"
84 #define TP_INT_MAX "ia32_int_max"
86 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
87 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
88 #define ENT_SFP_ABS "IA32_SFP_ABS"
89 #define ENT_DFP_ABS "IA32_DFP_ABS"
90 #define ENT_INT_MAX "IA32_INT_MAX"
92 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
93 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
95 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
97 static ir_node *initial_fpcw = NULL;
99 extern ir_op *get_op_Mulh(void);
101 typedef ir_node *construct_binop_func(dbg_info *db, ir_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 bool is_Const_0(ir_node *node)
136 return is_Const(node) && is_Const_null(node);
139 /** Return non-zero is a node represents the 1 constant. */
140 static bool is_Const_1(ir_node *node)
142 return is_Const(node) && is_Const_one(node);
145 /** Return non-zero is a node represents the -1 constant. */
146 static bool is_Const_Minus_1(ir_node *node)
148 return is_Const(node) && is_Const_all_one(node);
152 * returns true if constant can be created with a simple float command
154 static bool is_simple_x87_Const(ir_node *node)
156 tarval *tv = get_Const_tarval(node);
157 if (tarval_is_null(tv) || tarval_is_one(tv))
160 /* TODO: match all the other float constants */
165 * returns true if constant can be created with a simple float command
167 static bool is_simple_sse_Const(ir_node *node)
169 tarval *tv = get_Const_tarval(node);
170 ir_mode *mode = get_tarval_mode(tv);
175 if (tarval_is_null(tv) || tarval_is_one(tv))
178 if (mode == mode_D) {
179 unsigned val = get_tarval_sub_bits(tv, 0) |
180 (get_tarval_sub_bits(tv, 1) << 8) |
181 (get_tarval_sub_bits(tv, 2) << 16) |
182 (get_tarval_sub_bits(tv, 3) << 24);
184 /* lower 32bit are zero, really a 32bit constant */
188 /* TODO: match all the other float constants */
193 * Transforms a Const.
195 static ir_node *gen_Const(ir_node *node)
197 ir_graph *irg = current_ir_graph;
198 ir_node *old_block = get_nodes_block(node);
199 ir_node *block = be_transform_node(old_block);
200 dbg_info *dbgi = get_irn_dbg_info(node);
201 ir_mode *mode = get_irn_mode(node);
203 assert(is_Const(node));
205 if (mode_is_float(mode)) {
207 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
208 ir_node *nomem = new_NoMem();
212 if (ia32_cg_config.use_sse2) {
213 tarval *tv = get_Const_tarval(node);
214 if (tarval_is_null(tv)) {
215 load = new_rd_ia32_xZero(dbgi, irg, block);
216 set_ia32_ls_mode(load, mode);
218 } else if (tarval_is_one(tv)) {
219 int cnst = mode == mode_F ? 26 : 55;
220 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
221 ir_node *imm2 = create_Immediate(NULL, 0, 2);
222 ir_node *pslld, *psrld;
224 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
225 set_ia32_ls_mode(load, mode);
226 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
227 set_ia32_ls_mode(pslld, mode);
228 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
229 set_ia32_ls_mode(psrld, mode);
231 } else if (mode == mode_F) {
232 /* we can place any 32bit constant by using a movd gp, sse */
233 unsigned val = get_tarval_sub_bits(tv, 0) |
234 (get_tarval_sub_bits(tv, 1) << 8) |
235 (get_tarval_sub_bits(tv, 2) << 16) |
236 (get_tarval_sub_bits(tv, 3) << 24);
237 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
238 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
239 set_ia32_ls_mode(load, mode);
242 if (mode == mode_D) {
243 unsigned val = get_tarval_sub_bits(tv, 0) |
244 (get_tarval_sub_bits(tv, 1) << 8) |
245 (get_tarval_sub_bits(tv, 2) << 16) |
246 (get_tarval_sub_bits(tv, 3) << 24);
248 ir_node *imm32 = create_Immediate(NULL, 0, 32);
249 ir_node *cnst, *psllq;
251 /* fine, lower 32bit are zero, produce 32bit value */
252 val = get_tarval_sub_bits(tv, 4) |
253 (get_tarval_sub_bits(tv, 5) << 8) |
254 (get_tarval_sub_bits(tv, 6) << 16) |
255 (get_tarval_sub_bits(tv, 7) << 24);
256 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
257 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
258 set_ia32_ls_mode(load, mode);
259 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
260 set_ia32_ls_mode(psllq, mode);
265 floatent = create_float_const_entity(node);
267 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
269 set_ia32_op_type(load, ia32_AddrModeS);
270 set_ia32_am_sc(load, floatent);
271 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
272 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
275 if (is_Const_null(node)) {
276 load = new_rd_ia32_vfldz(dbgi, irg, block);
278 set_ia32_ls_mode(load, mode);
279 } else if (is_Const_one(node)) {
280 load = new_rd_ia32_vfld1(dbgi, irg, block);
282 set_ia32_ls_mode(load, mode);
284 floatent = create_float_const_entity(node);
286 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
287 set_ia32_op_type(load, ia32_AddrModeS);
288 set_ia32_am_sc(load, floatent);
289 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
290 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
291 /* take the mode from the entity */
292 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
296 SET_IA32_ORIG_NODE(load, node);
298 be_dep_on_frame(load);
300 } else { /* non-float mode */
302 tarval *tv = get_Const_tarval(node);
305 tv = tarval_convert_to(tv, mode_Iu);
307 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
309 panic("couldn't convert constant tarval (%+F)", node);
311 val = get_tarval_long(tv);
313 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
314 SET_IA32_ORIG_NODE(cnst, node);
316 be_dep_on_frame(cnst);
322 * Transforms a SymConst.
324 static ir_node *gen_SymConst(ir_node *node)
326 ir_graph *irg = current_ir_graph;
327 ir_node *old_block = get_nodes_block(node);
328 ir_node *block = be_transform_node(old_block);
329 dbg_info *dbgi = get_irn_dbg_info(node);
330 ir_mode *mode = get_irn_mode(node);
333 if (mode_is_float(mode)) {
334 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
335 ir_node *nomem = new_NoMem();
337 if (ia32_cg_config.use_sse2)
338 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
340 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
341 set_ia32_am_sc(cnst, get_SymConst_entity(node));
342 set_ia32_use_frame(cnst);
346 if (get_SymConst_kind(node) != symconst_addr_ent) {
347 panic("backend only support symconst_addr_ent (at %+F)", node);
349 entity = get_SymConst_entity(node);
350 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
353 SET_IA32_ORIG_NODE(cnst, node);
355 be_dep_on_frame(cnst);
359 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
360 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
362 static const struct {
364 const char *ent_name;
365 const char *cnst_str;
368 } names [ia32_known_const_max] = {
369 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
370 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
371 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
372 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
373 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
375 static ir_entity *ent_cache[ia32_known_const_max];
377 const char *tp_name, *ent_name, *cnst_str;
385 ent_name = names[kct].ent_name;
386 if (! ent_cache[kct]) {
387 tp_name = names[kct].tp_name;
388 cnst_str = names[kct].cnst_str;
390 switch (names[kct].mode) {
391 case 0: mode = mode_Iu; break;
392 case 1: mode = mode_Lu; break;
393 default: mode = mode_F; break;
395 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
396 tp = new_type_primitive(new_id_from_str(tp_name), mode);
397 /* set the specified alignment */
398 set_type_alignment_bytes(tp, names[kct].align);
400 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
402 set_entity_ld_ident(ent, get_entity_ident(ent));
403 set_entity_visibility(ent, visibility_local);
404 set_entity_variability(ent, variability_constant);
405 set_entity_allocation(ent, allocation_static);
407 /* we create a new entity here: It's initialization must resist on the
409 rem = current_ir_graph;
410 current_ir_graph = get_const_code_irg();
411 cnst = new_Const(mode, tv);
412 current_ir_graph = rem;
414 set_atomic_ent_value(ent, cnst);
416 /* cache the entry */
417 ent_cache[kct] = ent;
420 return ent_cache[kct];
424 * return true if the node is a Proj(Load) and could be used in source address
425 * mode for another node. Will return only true if the @p other node is not
426 * dependent on the memory of the Load (for binary operations use the other
427 * input here, for unary operations use NULL).
429 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
430 ir_node *other, ir_node *other2, match_flags_t flags)
435 /* float constants are always available */
436 if (is_Const(node)) {
437 ir_mode *mode = get_irn_mode(node);
438 if (mode_is_float(mode)) {
439 if (ia32_cg_config.use_sse2) {
440 if (is_simple_sse_Const(node))
443 if (is_simple_x87_Const(node))
446 if (get_irn_n_edges(node) > 1)
454 load = get_Proj_pred(node);
455 pn = get_Proj_proj(node);
456 if (!is_Load(load) || pn != pn_Load_res)
458 if (get_nodes_block(load) != block)
460 /* we only use address mode if we're the only user of the load */
461 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
463 /* in some edge cases with address mode we might reach the load normally
464 * and through some AM sequence, if it is already materialized then we
465 * can't create an AM node from it */
466 if (be_is_transformed(node))
469 /* don't do AM if other node inputs depend on the load (via mem-proj) */
470 if (other != NULL && prevents_AM(block, load, other))
473 if (other2 != NULL && prevents_AM(block, load, other2))
479 typedef struct ia32_address_mode_t ia32_address_mode_t;
480 struct ia32_address_mode_t {
485 ia32_op_type_t op_type;
489 unsigned commutative : 1;
490 unsigned ins_permuted : 1;
493 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
497 /* construct load address */
498 memset(addr, 0, sizeof(addr[0]));
499 ia32_create_address_mode(addr, ptr, 0);
501 noreg_gp = ia32_new_NoReg_gp(env_cg);
502 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
503 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
504 addr->mem = be_transform_node(mem);
507 static void build_address(ia32_address_mode_t *am, ir_node *node,
508 ia32_create_am_flags_t flags)
510 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
511 ia32_address_t *addr = &am->addr;
517 if (is_Const(node)) {
518 ir_entity *entity = create_float_const_entity(node);
519 addr->base = noreg_gp;
520 addr->index = noreg_gp;
521 addr->mem = new_NoMem();
522 addr->symconst_ent = entity;
524 am->ls_mode = get_type_mode(get_entity_type(entity));
525 am->pinned = op_pin_state_floats;
529 load = get_Proj_pred(node);
530 ptr = get_Load_ptr(load);
531 mem = get_Load_mem(load);
532 new_mem = be_transform_node(mem);
533 am->pinned = get_irn_pinned(load);
534 am->ls_mode = get_Load_mode(load);
535 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
538 /* construct load address */
539 ia32_create_address_mode(addr, ptr, flags);
541 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
542 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
546 static void set_address(ir_node *node, const ia32_address_t *addr)
548 set_ia32_am_scale(node, addr->scale);
549 set_ia32_am_sc(node, addr->symconst_ent);
550 set_ia32_am_offs_int(node, addr->offset);
551 if (addr->symconst_sign)
552 set_ia32_am_sc_sign(node);
554 set_ia32_use_frame(node);
555 set_ia32_frame_ent(node, addr->frame_entity);
559 * Apply attributes of a given address mode to a node.
561 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
563 set_address(node, &am->addr);
565 set_ia32_op_type(node, am->op_type);
566 set_ia32_ls_mode(node, am->ls_mode);
567 if (am->pinned == op_pin_state_pinned) {
568 /* beware: some nodes are already pinned and did not allow to change the state */
569 if (get_irn_pinned(node) != op_pin_state_pinned)
570 set_irn_pinned(node, op_pin_state_pinned);
573 set_ia32_commutative(node);
577 * Check, if a given node is a Down-Conv, ie. a integer Conv
578 * from a mode with a mode with more bits to a mode with lesser bits.
579 * Moreover, we return only true if the node has not more than 1 user.
581 * @param node the node
582 * @return non-zero if node is a Down-Conv
584 static int is_downconv(const ir_node *node)
592 /* we only want to skip the conv when we're the only user
593 * (not optimal but for now...)
595 if (get_irn_n_edges(node) > 1)
598 src_mode = get_irn_mode(get_Conv_op(node));
599 dest_mode = get_irn_mode(node);
600 return ia32_mode_needs_gp_reg(src_mode)
601 && ia32_mode_needs_gp_reg(dest_mode)
602 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
605 /* Skip all Down-Conv's on a given node and return the resulting node. */
606 ir_node *ia32_skip_downconv(ir_node *node)
608 while (is_downconv(node))
609 node = get_Conv_op(node);
614 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
616 ir_mode *mode = get_irn_mode(node);
621 if (mode_is_signed(mode)) {
626 block = get_nodes_block(node);
627 dbgi = get_irn_dbg_info(node);
629 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
633 * matches operands of a node into ia32 addressing/operand modes. This covers
634 * usage of source address mode, immediates, operations with non 32-bit modes,
636 * The resulting data is filled into the @p am struct. block is the block
637 * of the node whose arguments are matched. op1, op2 are the first and second
638 * input that are matched (op1 may be NULL). other_op is another unrelated
639 * input that is not matched! but which is needed sometimes to check if AM
640 * for op1/op2 is legal.
641 * @p flags describes the supported modes of the operation in detail.
643 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
644 ir_node *op1, ir_node *op2, ir_node *other_op,
647 ia32_address_t *addr = &am->addr;
648 ir_mode *mode = get_irn_mode(op2);
649 int mode_bits = get_mode_size_bits(mode);
650 ir_node *noreg_gp, *new_op1, *new_op2;
652 unsigned commutative;
653 int use_am_and_immediates;
656 memset(am, 0, sizeof(am[0]));
658 commutative = (flags & match_commutative) != 0;
659 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
660 use_am = (flags & match_am) != 0;
661 use_immediate = (flags & match_immediate) != 0;
662 assert(!use_am_and_immediates || use_immediate);
665 assert(!commutative || op1 != NULL);
666 assert(use_am || !(flags & match_8bit_am));
667 assert(use_am || !(flags & match_16bit_am));
669 if (mode_bits == 8) {
670 if (!(flags & match_8bit_am))
672 /* we don't automatically add upconvs yet */
673 assert((flags & match_mode_neutral) || (flags & match_8bit));
674 } else if (mode_bits == 16) {
675 if (!(flags & match_16bit_am))
677 /* we don't automatically add upconvs yet */
678 assert((flags & match_mode_neutral) || (flags & match_16bit));
681 /* we can simply skip downconvs for mode neutral nodes: the upper bits
682 * can be random for these operations */
683 if (flags & match_mode_neutral) {
684 op2 = ia32_skip_downconv(op2);
686 op1 = ia32_skip_downconv(op1);
690 /* match immediates. firm nodes are normalized: constants are always on the
693 if (!(flags & match_try_am) && use_immediate) {
694 new_op2 = try_create_Immediate(op2, 0);
697 noreg_gp = ia32_new_NoReg_gp(env_cg);
698 if (new_op2 == NULL &&
699 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
700 build_address(am, op2, 0);
701 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
702 if (mode_is_float(mode)) {
703 new_op2 = ia32_new_NoReg_vfp(env_cg);
707 am->op_type = ia32_AddrModeS;
708 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
710 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
712 build_address(am, op1, 0);
714 if (mode_is_float(mode)) {
715 noreg = ia32_new_NoReg_vfp(env_cg);
720 if (new_op2 != NULL) {
723 new_op1 = be_transform_node(op2);
725 am->ins_permuted = 1;
727 am->op_type = ia32_AddrModeS;
729 am->op_type = ia32_Normal;
731 if (flags & match_try_am) {
737 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
739 new_op2 = be_transform_node(op2);
741 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
743 if (addr->base == NULL)
744 addr->base = noreg_gp;
745 if (addr->index == NULL)
746 addr->index = noreg_gp;
747 if (addr->mem == NULL)
748 addr->mem = new_NoMem();
750 am->new_op1 = new_op1;
751 am->new_op2 = new_op2;
752 am->commutative = commutative;
755 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
760 if (am->mem_proj == NULL)
763 /* we have to create a mode_T so the old MemProj can attach to us */
764 mode = get_irn_mode(node);
765 load = get_Proj_pred(am->mem_proj);
767 be_set_transformed_node(load, node);
769 if (mode != mode_T) {
770 set_irn_mode(node, mode_T);
771 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
778 * Construct a standard binary operation, set AM and immediate if required.
780 * @param node The original node for which the binop is created
781 * @param op1 The first operand
782 * @param op2 The second operand
783 * @param func The node constructor function
784 * @return The constructed ia32 node.
786 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
787 construct_binop_func *func, match_flags_t flags)
790 ir_node *block, *new_block, *new_node;
791 ia32_address_mode_t am;
792 ia32_address_t *addr = &am.addr;
794 block = get_nodes_block(node);
795 match_arguments(&am, block, op1, op2, NULL, flags);
797 dbgi = get_irn_dbg_info(node);
798 new_block = be_transform_node(block);
799 new_node = func(dbgi, current_ir_graph, new_block,
800 addr->base, addr->index, addr->mem,
801 am.new_op1, am.new_op2);
802 set_am_attributes(new_node, &am);
803 /* we can't use source address mode anymore when using immediates */
804 if (!(flags & match_am_and_immediates) &&
805 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
806 set_ia32_am_support(new_node, ia32_am_none);
807 SET_IA32_ORIG_NODE(new_node, node);
809 new_node = fix_mem_proj(new_node, &am);
816 n_ia32_l_binop_right,
817 n_ia32_l_binop_eflags
819 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
820 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
821 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
822 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
823 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
824 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
827 * Construct a binary operation which also consumes the eflags.
829 * @param node The node to transform
830 * @param func The node constructor function
831 * @param flags The match flags
832 * @return The constructor ia32 node
834 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
837 ir_node *src_block = get_nodes_block(node);
838 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
839 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
840 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
842 ir_node *block, *new_node, *new_eflags;
843 ia32_address_mode_t am;
844 ia32_address_t *addr = &am.addr;
846 match_arguments(&am, src_block, op1, op2, eflags, flags);
848 dbgi = get_irn_dbg_info(node);
849 block = be_transform_node(src_block);
850 new_eflags = be_transform_node(eflags);
851 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
852 addr->mem, am.new_op1, am.new_op2, new_eflags);
853 set_am_attributes(new_node, &am);
854 /* we can't use source address mode anymore when using immediates */
855 if (!(flags & match_am_and_immediates) &&
856 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
857 set_ia32_am_support(new_node, ia32_am_none);
858 SET_IA32_ORIG_NODE(new_node, node);
860 new_node = fix_mem_proj(new_node, &am);
865 static ir_node *get_fpcw(void)
868 if (initial_fpcw != NULL)
871 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
872 &ia32_fp_cw_regs[REG_FPCW]);
873 initial_fpcw = be_transform_node(fpcw);
879 * Construct a standard binary operation, set AM and immediate if required.
881 * @param op1 The first operand
882 * @param op2 The second operand
883 * @param func The node constructor function
884 * @return The constructed ia32 node.
886 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
887 construct_binop_float_func *func)
889 ir_mode *mode = get_irn_mode(node);
891 ir_node *block, *new_block, *new_node;
892 ia32_address_mode_t am;
893 ia32_address_t *addr = &am.addr;
894 ia32_x87_attr_t *attr;
895 /* All operations are considered commutative, because there are reverse
897 match_flags_t flags = match_commutative;
899 /* cannot use address mode with long double on x87 */
900 if (get_mode_size_bits(mode) <= 64)
903 block = get_nodes_block(node);
904 match_arguments(&am, block, op1, op2, NULL, flags);
906 dbgi = get_irn_dbg_info(node);
907 new_block = be_transform_node(block);
908 new_node = func(dbgi, current_ir_graph, new_block,
909 addr->base, addr->index, addr->mem,
910 am.new_op1, am.new_op2, get_fpcw());
911 set_am_attributes(new_node, &am);
913 attr = get_ia32_x87_attr(new_node);
914 attr->attr.data.ins_permuted = am.ins_permuted;
916 SET_IA32_ORIG_NODE(new_node, node);
918 new_node = fix_mem_proj(new_node, &am);
924 * Construct a shift/rotate binary operation, sets AM and immediate if required.
926 * @param op1 The first operand
927 * @param op2 The second operand
928 * @param func The node constructor function
929 * @return The constructed ia32 node.
931 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
932 construct_shift_func *func,
936 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
938 assert(! mode_is_float(get_irn_mode(node)));
939 assert(flags & match_immediate);
940 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
942 if (flags & match_mode_neutral) {
943 op1 = ia32_skip_downconv(op1);
944 new_op1 = be_transform_node(op1);
945 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
946 new_op1 = create_upconv(op1, node);
948 new_op1 = be_transform_node(op1);
951 /* the shift amount can be any mode that is bigger than 5 bits, since all
952 * other bits are ignored anyway */
953 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
954 ir_node *const op = get_Conv_op(op2);
955 if (mode_is_float(get_irn_mode(op)))
958 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
960 new_op2 = create_immediate_or_transform(op2, 0);
962 dbgi = get_irn_dbg_info(node);
963 block = get_nodes_block(node);
964 new_block = be_transform_node(block);
965 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
966 SET_IA32_ORIG_NODE(new_node, node);
968 /* lowered shift instruction may have a dependency operand, handle it here */
969 if (get_irn_arity(node) == 3) {
970 /* we have a dependency */
971 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
972 add_irn_dep(new_node, new_dep);
980 * Construct a standard unary operation, set AM and immediate if required.
982 * @param op The operand
983 * @param func The node constructor function
984 * @return The constructed ia32 node.
986 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
990 ir_node *block, *new_block, *new_op, *new_node;
992 assert(flags == 0 || flags == match_mode_neutral);
993 if (flags & match_mode_neutral) {
994 op = ia32_skip_downconv(op);
997 new_op = be_transform_node(op);
998 dbgi = get_irn_dbg_info(node);
999 block = get_nodes_block(node);
1000 new_block = be_transform_node(block);
1001 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1003 SET_IA32_ORIG_NODE(new_node, node);
1008 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1009 ia32_address_t *addr)
1011 ir_node *base, *index, *res;
1015 base = ia32_new_NoReg_gp(env_cg);
1017 base = be_transform_node(base);
1020 index = addr->index;
1021 if (index == NULL) {
1022 index = ia32_new_NoReg_gp(env_cg);
1024 index = be_transform_node(index);
1027 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1028 set_address(res, addr);
1034 * Returns non-zero if a given address mode has a symbolic or
1035 * numerical offset != 0.
1037 static int am_has_immediates(const ia32_address_t *addr)
1039 return addr->offset != 0 || addr->symconst_ent != NULL
1040 || addr->frame_entity || addr->use_frame;
1044 * Creates an ia32 Add.
1046 * @return the created ia32 Add node
1048 static ir_node *gen_Add(ir_node *node)
1050 ir_mode *mode = get_irn_mode(node);
1051 ir_node *op1 = get_Add_left(node);
1052 ir_node *op2 = get_Add_right(node);
1054 ir_node *block, *new_block, *new_node, *add_immediate_op;
1055 ia32_address_t addr;
1056 ia32_address_mode_t am;
1058 if (mode_is_float(mode)) {
1059 if (ia32_cg_config.use_sse2)
1060 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1061 match_commutative | match_am);
1063 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd);
1066 ia32_mark_non_am(node);
1068 op2 = ia32_skip_downconv(op2);
1069 op1 = ia32_skip_downconv(op1);
1073 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1074 * 1. Add with immediate -> Lea
1075 * 2. Add with possible source address mode -> Add
1076 * 3. Otherwise -> Lea
1078 memset(&addr, 0, sizeof(addr));
1079 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1080 add_immediate_op = NULL;
1082 dbgi = get_irn_dbg_info(node);
1083 block = get_nodes_block(node);
1084 new_block = be_transform_node(block);
1087 if (addr.base == NULL && addr.index == NULL) {
1088 ir_graph *irg = current_ir_graph;
1089 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1090 addr.symconst_sign, addr.offset);
1091 be_dep_on_frame(new_node);
1092 SET_IA32_ORIG_NODE(new_node, node);
1095 /* add with immediate? */
1096 if (addr.index == NULL) {
1097 add_immediate_op = addr.base;
1098 } else if (addr.base == NULL && addr.scale == 0) {
1099 add_immediate_op = addr.index;
1102 if (add_immediate_op != NULL) {
1103 if (!am_has_immediates(&addr)) {
1104 #ifdef DEBUG_libfirm
1105 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1108 return be_transform_node(add_immediate_op);
1111 new_node = create_lea_from_address(dbgi, new_block, &addr);
1112 SET_IA32_ORIG_NODE(new_node, node);
1116 /* test if we can use source address mode */
1117 match_arguments(&am, block, op1, op2, NULL, match_commutative
1118 | match_mode_neutral | match_am | match_immediate | match_try_am);
1120 /* construct an Add with source address mode */
1121 if (am.op_type == ia32_AddrModeS) {
1122 ir_graph *irg = current_ir_graph;
1123 ia32_address_t *am_addr = &am.addr;
1124 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1125 am_addr->index, am_addr->mem, am.new_op1,
1127 set_am_attributes(new_node, &am);
1128 SET_IA32_ORIG_NODE(new_node, node);
1130 new_node = fix_mem_proj(new_node, &am);
1135 /* otherwise construct a lea */
1136 new_node = create_lea_from_address(dbgi, new_block, &addr);
1137 SET_IA32_ORIG_NODE(new_node, node);
1142 * Creates an ia32 Mul.
1144 * @return the created ia32 Mul node
1146 static ir_node *gen_Mul(ir_node *node)
1148 ir_node *op1 = get_Mul_left(node);
1149 ir_node *op2 = get_Mul_right(node);
1150 ir_mode *mode = get_irn_mode(node);
1152 if (mode_is_float(mode)) {
1153 if (ia32_cg_config.use_sse2)
1154 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1155 match_commutative | match_am);
1157 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul);
1159 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1160 match_commutative | match_am | match_mode_neutral |
1161 match_immediate | match_am_and_immediates);
1165 * Creates an ia32 Mulh.
1166 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1167 * this result while Mul returns the lower 32 bit.
1169 * @return the created ia32 Mulh node
1171 static ir_node *gen_Mulh(ir_node *node)
1173 ir_node *block = get_nodes_block(node);
1174 ir_node *new_block = be_transform_node(block);
1175 dbg_info *dbgi = get_irn_dbg_info(node);
1176 ir_node *op1 = get_Mulh_left(node);
1177 ir_node *op2 = get_Mulh_right(node);
1178 ir_mode *mode = get_irn_mode(node);
1180 ir_node *proj_res_high;
1182 if (mode_is_signed(mode)) {
1183 new_node = gen_binop(node, op1, op2, new_rd_ia32_IMul1OP, match_commutative | match_am);
1184 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1185 mode_Iu, pn_ia32_IMul1OP_res_high);
1187 new_node = gen_binop(node, op1, op2, new_rd_ia32_Mul, match_commutative | match_am);
1188 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1189 mode_Iu, pn_ia32_Mul_res_high);
1191 return proj_res_high;
1195 * Creates an ia32 And.
1197 * @return The created ia32 And node
1199 static ir_node *gen_And(ir_node *node)
1201 ir_node *op1 = get_And_left(node);
1202 ir_node *op2 = get_And_right(node);
1203 assert(! mode_is_float(get_irn_mode(node)));
1205 /* is it a zero extension? */
1206 if (is_Const(op2)) {
1207 tarval *tv = get_Const_tarval(op2);
1208 long v = get_tarval_long(tv);
1210 if (v == 0xFF || v == 0xFFFF) {
1211 dbg_info *dbgi = get_irn_dbg_info(node);
1212 ir_node *block = get_nodes_block(node);
1219 assert(v == 0xFFFF);
1222 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1227 return gen_binop(node, op1, op2, new_rd_ia32_And,
1228 match_commutative | match_mode_neutral | match_am
1235 * Creates an ia32 Or.
1237 * @return The created ia32 Or node
1239 static ir_node *gen_Or(ir_node *node)
1241 ir_node *op1 = get_Or_left(node);
1242 ir_node *op2 = get_Or_right(node);
1244 assert (! mode_is_float(get_irn_mode(node)));
1245 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1246 | match_mode_neutral | match_am | match_immediate);
1252 * Creates an ia32 Eor.
1254 * @return The created ia32 Eor node
1256 static ir_node *gen_Eor(ir_node *node)
1258 ir_node *op1 = get_Eor_left(node);
1259 ir_node *op2 = get_Eor_right(node);
1261 assert(! mode_is_float(get_irn_mode(node)));
1262 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1263 | match_mode_neutral | match_am | match_immediate);
1268 * Creates an ia32 Sub.
1270 * @return The created ia32 Sub node
1272 static ir_node *gen_Sub(ir_node *node)
1274 ir_node *op1 = get_Sub_left(node);
1275 ir_node *op2 = get_Sub_right(node);
1276 ir_mode *mode = get_irn_mode(node);
1278 if (mode_is_float(mode)) {
1279 if (ia32_cg_config.use_sse2)
1280 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1282 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub);
1285 if (is_Const(op2)) {
1286 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1290 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1291 | match_am | match_immediate);
1294 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1295 ir_node *const src_val,
1296 ir_node *const src_mem,
1297 ir_node *const am_mem)
1299 if (is_NoMem(am_mem)) {
1300 return be_transform_node(src_mem);
1301 } else if (is_Proj(src_val) &&
1303 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1304 /* avoid memory loop */
1306 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1307 ir_node *const ptr_pred = get_Proj_pred(src_val);
1308 int const arity = get_Sync_n_preds(src_mem);
1313 NEW_ARR_A(ir_node*, ins, arity + 1);
1315 /* NOTE: This sometimes produces dead-code because the old sync in
1316 * src_mem might not be used anymore, we should detect this case
1317 * and kill the sync... */
1318 for (i = arity - 1; i >= 0; --i) {
1319 ir_node *const pred = get_Sync_pred(src_mem, i);
1321 /* avoid memory loop */
1322 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1325 ins[n++] = be_transform_node(pred);
1330 return new_r_Sync(irg, block, n, ins);
1334 ins[0] = be_transform_node(src_mem);
1336 return new_r_Sync(irg, block, 2, ins);
1340 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_graph *irg, ir_node *block,
1341 ir_node *val, const ir_node *orig)
1346 if (ia32_cg_config.use_short_sex_eax) {
1347 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1348 be_dep_on_frame(pval);
1349 res = new_rd_ia32_Cltd(dbgi, irg, block, val, pval);
1351 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1352 res = new_rd_ia32_Sar(dbgi, irg, block, val, imm31);
1354 SET_IA32_ORIG_NODE(res, orig);
1359 * Generates an ia32 DivMod with additional infrastructure for the
1360 * register allocator if needed.
1362 static ir_node *create_Div(ir_node *node)
1364 ir_graph *irg = current_ir_graph;
1365 dbg_info *dbgi = get_irn_dbg_info(node);
1366 ir_node *block = get_nodes_block(node);
1367 ir_node *new_block = be_transform_node(block);
1374 ir_node *sign_extension;
1375 ia32_address_mode_t am;
1376 ia32_address_t *addr = &am.addr;
1378 /* the upper bits have random contents for smaller modes */
1379 switch (get_irn_opcode(node)) {
1381 op1 = get_Div_left(node);
1382 op2 = get_Div_right(node);
1383 mem = get_Div_mem(node);
1384 mode = get_Div_resmode(node);
1387 op1 = get_Mod_left(node);
1388 op2 = get_Mod_right(node);
1389 mem = get_Mod_mem(node);
1390 mode = get_Mod_resmode(node);
1393 op1 = get_DivMod_left(node);
1394 op2 = get_DivMod_right(node);
1395 mem = get_DivMod_mem(node);
1396 mode = get_DivMod_resmode(node);
1399 panic("invalid divmod node %+F", node);
1402 match_arguments(&am, block, op1, op2, NULL, match_am);
1404 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1405 is the memory of the consumed address. We can have only the second op as address
1406 in Div nodes, so check only op2. */
1407 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1409 if (mode_is_signed(mode)) {
1410 sign_extension = create_sex_32_64(dbgi, irg, new_block, am.new_op1, node);
1411 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1412 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1414 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1415 be_dep_on_frame(sign_extension);
1417 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1418 addr->index, new_mem, am.new_op2,
1419 am.new_op1, sign_extension);
1422 set_irn_pinned(new_node, get_irn_pinned(node));
1424 set_am_attributes(new_node, &am);
1425 SET_IA32_ORIG_NODE(new_node, node);
1427 new_node = fix_mem_proj(new_node, &am);
1433 static ir_node *gen_Mod(ir_node *node)
1435 return create_Div(node);
1438 static ir_node *gen_Div(ir_node *node)
1440 return create_Div(node);
1443 static ir_node *gen_DivMod(ir_node *node)
1445 return create_Div(node);
1451 * Creates an ia32 floating Div.
1453 * @return The created ia32 xDiv node
1455 static ir_node *gen_Quot(ir_node *node)
1457 ir_node *op1 = get_Quot_left(node);
1458 ir_node *op2 = get_Quot_right(node);
1460 if (ia32_cg_config.use_sse2) {
1461 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1463 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv);
1469 * Creates an ia32 Shl.
1471 * @return The created ia32 Shl node
1473 static ir_node *gen_Shl(ir_node *node)
1475 ir_node *left = get_Shl_left(node);
1476 ir_node *right = get_Shl_right(node);
1478 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1479 match_mode_neutral | match_immediate);
1483 * Creates an ia32 Shr.
1485 * @return The created ia32 Shr node
1487 static ir_node *gen_Shr(ir_node *node)
1489 ir_node *left = get_Shr_left(node);
1490 ir_node *right = get_Shr_right(node);
1492 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1498 * Creates an ia32 Sar.
1500 * @return The created ia32 Shrs node
1502 static ir_node *gen_Shrs(ir_node *node)
1504 ir_node *left = get_Shrs_left(node);
1505 ir_node *right = get_Shrs_right(node);
1506 ir_mode *mode = get_irn_mode(node);
1508 if (is_Const(right) && mode == mode_Is) {
1509 tarval *tv = get_Const_tarval(right);
1510 long val = get_tarval_long(tv);
1512 /* this is a sign extension */
1513 dbg_info *dbgi = get_irn_dbg_info(node);
1514 ir_node *block = be_transform_node(get_nodes_block(node));
1515 ir_node *new_op = be_transform_node(left);
1517 return create_sex_32_64(dbgi, current_ir_graph, block, new_op, node);
1521 /* 8 or 16 bit sign extension? */
1522 if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1523 ir_node *shl_left = get_Shl_left(left);
1524 ir_node *shl_right = get_Shl_right(left);
1525 if (is_Const(shl_right)) {
1526 tarval *tv1 = get_Const_tarval(right);
1527 tarval *tv2 = get_Const_tarval(shl_right);
1528 if (tv1 == tv2 && tarval_is_long(tv1)) {
1529 long val = get_tarval_long(tv1);
1530 if (val == 16 || val == 24) {
1531 dbg_info *dbgi = get_irn_dbg_info(node);
1532 ir_node *block = get_nodes_block(node);
1542 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1551 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1557 * Creates an ia32 Rol.
1559 * @param op1 The first operator
1560 * @param op2 The second operator
1561 * @return The created ia32 RotL node
1563 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1565 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1571 * Creates an ia32 Ror.
1572 * NOTE: There is no RotR with immediate because this would always be a RotL
1573 * "imm-mode_size_bits" which can be pre-calculated.
1575 * @param op1 The first operator
1576 * @param op2 The second operator
1577 * @return The created ia32 RotR node
1579 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1581 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1587 * Creates an ia32 RotR or RotL (depending on the found pattern).
1589 * @return The created ia32 RotL or RotR node
1591 static ir_node *gen_Rotl(ir_node *node)
1593 ir_node *rotate = NULL;
1594 ir_node *op1 = get_Rotl_left(node);
1595 ir_node *op2 = get_Rotl_right(node);
1597 /* Firm has only RotL, so we are looking for a right (op2)
1598 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1599 that means we can create a RotR instead of an Add and a RotL */
1603 ir_node *left = get_Add_left(add);
1604 ir_node *right = get_Add_right(add);
1605 if (is_Const(right)) {
1606 tarval *tv = get_Const_tarval(right);
1607 ir_mode *mode = get_irn_mode(node);
1608 long bits = get_mode_size_bits(mode);
1610 if (is_Minus(left) &&
1611 tarval_is_long(tv) &&
1612 get_tarval_long(tv) == bits &&
1615 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1616 rotate = gen_Ror(node, op1, get_Minus_op(left));
1621 if (rotate == NULL) {
1622 rotate = gen_Rol(node, op1, op2);
1631 * Transforms a Minus node.
1633 * @return The created ia32 Minus node
1635 static ir_node *gen_Minus(ir_node *node)
1637 ir_node *op = get_Minus_op(node);
1638 ir_node *block = be_transform_node(get_nodes_block(node));
1639 ir_graph *irg = current_ir_graph;
1640 dbg_info *dbgi = get_irn_dbg_info(node);
1641 ir_mode *mode = get_irn_mode(node);
1646 if (mode_is_float(mode)) {
1647 ir_node *new_op = be_transform_node(op);
1648 if (ia32_cg_config.use_sse2) {
1649 /* TODO: non-optimal... if we have many xXors, then we should
1650 * rather create a load for the const and use that instead of
1651 * several AM nodes... */
1652 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1653 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1654 ir_node *nomem = new_rd_NoMem(irg);
1656 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1657 nomem, new_op, noreg_xmm);
1659 size = get_mode_size_bits(mode);
1660 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1662 set_ia32_am_sc(new_node, ent);
1663 set_ia32_op_type(new_node, ia32_AddrModeS);
1664 set_ia32_ls_mode(new_node, mode);
1666 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1669 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1672 SET_IA32_ORIG_NODE(new_node, node);
1678 * Transforms a Not node.
1680 * @return The created ia32 Not node
1682 static ir_node *gen_Not(ir_node *node)
1684 ir_node *op = get_Not_op(node);
1686 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1687 assert (! mode_is_float(get_irn_mode(node)));
1689 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1695 * Transforms an Abs node.
1697 * @return The created ia32 Abs node
1699 static ir_node *gen_Abs(ir_node *node)
1701 ir_node *block = get_nodes_block(node);
1702 ir_node *new_block = be_transform_node(block);
1703 ir_node *op = get_Abs_op(node);
1704 ir_graph *irg = current_ir_graph;
1705 dbg_info *dbgi = get_irn_dbg_info(node);
1706 ir_mode *mode = get_irn_mode(node);
1707 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1708 ir_node *nomem = new_NoMem();
1714 if (mode_is_float(mode)) {
1715 new_op = be_transform_node(op);
1717 if (ia32_cg_config.use_sse2) {
1718 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1719 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1720 nomem, new_op, noreg_fp);
1722 size = get_mode_size_bits(mode);
1723 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1725 set_ia32_am_sc(new_node, ent);
1727 SET_IA32_ORIG_NODE(new_node, node);
1729 set_ia32_op_type(new_node, ia32_AddrModeS);
1730 set_ia32_ls_mode(new_node, mode);
1732 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1733 SET_IA32_ORIG_NODE(new_node, node);
1736 ir_node *xor, *sign_extension;
1738 if (get_mode_size_bits(mode) == 32) {
1739 new_op = be_transform_node(op);
1741 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1744 sign_extension = create_sex_32_64(dbgi, irg, new_block, new_op, node);
1746 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1747 nomem, new_op, sign_extension);
1748 SET_IA32_ORIG_NODE(xor, node);
1750 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1751 nomem, xor, sign_extension);
1752 SET_IA32_ORIG_NODE(new_node, node);
1759 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1761 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1763 dbg_info *dbgi = get_irn_dbg_info(cmp);
1764 ir_node *block = get_nodes_block(cmp);
1765 ir_node *new_block = be_transform_node(block);
1766 ir_node *op1 = be_transform_node(x);
1767 ir_node *op2 = be_transform_node(n);
1769 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1773 * Transform a node returning a "flag" result.
1775 * @param node the node to transform
1776 * @param pnc_out the compare mode to use
1778 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1787 /* we have a Cmp as input */
1788 if (is_Proj(node)) {
1789 ir_node *pred = get_Proj_pred(node);
1791 pn_Cmp pnc = get_Proj_proj(node);
1792 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1793 ir_node *l = get_Cmp_left(pred);
1794 ir_node *r = get_Cmp_right(pred);
1796 ir_node *la = get_And_left(l);
1797 ir_node *ra = get_And_right(l);
1799 ir_node *c = get_Shl_left(la);
1800 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1801 /* (1 << n) & ra) */
1802 ir_node *n = get_Shl_right(la);
1803 flags = gen_bt(pred, ra, n);
1804 /* we must generate a Jc/Jnc jump */
1805 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1808 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1813 ir_node *c = get_Shl_left(ra);
1814 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1815 /* la & (1 << n)) */
1816 ir_node *n = get_Shl_right(ra);
1817 flags = gen_bt(pred, la, n);
1818 /* we must generate a Jc/Jnc jump */
1819 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1822 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1828 flags = be_transform_node(pred);
1834 /* a mode_b value, we have to compare it against 0 */
1835 dbgi = get_irn_dbg_info(node);
1836 new_block = be_transform_node(get_nodes_block(node));
1837 new_op = be_transform_node(node);
1838 noreg = ia32_new_NoReg_gp(env_cg);
1839 nomem = new_NoMem();
1840 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1841 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1842 *pnc_out = pn_Cmp_Lg;
1847 * Transforms a Load.
1849 * @return the created ia32 Load node
1851 static ir_node *gen_Load(ir_node *node)
1853 ir_node *old_block = get_nodes_block(node);
1854 ir_node *block = be_transform_node(old_block);
1855 ir_node *ptr = get_Load_ptr(node);
1856 ir_node *mem = get_Load_mem(node);
1857 ir_node *new_mem = be_transform_node(mem);
1860 ir_graph *irg = current_ir_graph;
1861 dbg_info *dbgi = get_irn_dbg_info(node);
1862 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1863 ir_mode *mode = get_Load_mode(node);
1866 ia32_address_t addr;
1868 /* construct load address */
1869 memset(&addr, 0, sizeof(addr));
1870 ia32_create_address_mode(&addr, ptr, 0);
1877 base = be_transform_node(base);
1880 if (index == NULL) {
1883 index = be_transform_node(index);
1886 if (mode_is_float(mode)) {
1887 if (ia32_cg_config.use_sse2) {
1888 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1890 res_mode = mode_xmm;
1892 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1894 res_mode = mode_vfp;
1897 assert(mode != mode_b);
1899 /* create a conv node with address mode for smaller modes */
1900 if (get_mode_size_bits(mode) < 32) {
1901 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1902 new_mem, noreg, mode);
1904 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1909 set_irn_pinned(new_node, get_irn_pinned(node));
1910 set_ia32_op_type(new_node, ia32_AddrModeS);
1911 set_ia32_ls_mode(new_node, mode);
1912 set_address(new_node, &addr);
1914 if (get_irn_pinned(node) == op_pin_state_floats) {
1915 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1916 && pn_ia32_vfld_res == pn_ia32_Load_res
1917 && pn_ia32_Load_res == pn_ia32_res);
1918 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1921 SET_IA32_ORIG_NODE(new_node, node);
1923 be_dep_on_frame(new_node);
1927 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1928 ir_node *ptr, ir_node *other)
1935 /* we only use address mode if we're the only user of the load */
1936 if (get_irn_n_edges(node) > 1)
1939 load = get_Proj_pred(node);
1942 if (get_nodes_block(load) != block)
1945 /* store should have the same pointer as the load */
1946 if (get_Load_ptr(load) != ptr)
1949 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1950 if (other != NULL &&
1951 get_nodes_block(other) == block &&
1952 heights_reachable_in_block(heights, other, load)) {
1956 if (prevents_AM(block, load, mem))
1958 /* Store should be attached to the load via mem */
1959 assert(heights_reachable_in_block(heights, mem, load));
1964 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1965 ir_node *mem, ir_node *ptr, ir_mode *mode,
1966 construct_binop_dest_func *func,
1967 construct_binop_dest_func *func8bit,
1968 match_flags_t flags)
1970 ir_node *src_block = get_nodes_block(node);
1972 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1973 ir_graph *irg = current_ir_graph;
1980 ia32_address_mode_t am;
1981 ia32_address_t *addr = &am.addr;
1982 memset(&am, 0, sizeof(am));
1984 assert(flags & match_dest_am);
1985 assert(flags & match_immediate); /* there is no destam node without... */
1986 commutative = (flags & match_commutative) != 0;
1988 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1989 build_address(&am, op1, ia32_create_am_double_use);
1990 new_op = create_immediate_or_transform(op2, 0);
1991 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1992 build_address(&am, op2, ia32_create_am_double_use);
1993 new_op = create_immediate_or_transform(op1, 0);
1998 if (addr->base == NULL)
1999 addr->base = noreg_gp;
2000 if (addr->index == NULL)
2001 addr->index = noreg_gp;
2002 if (addr->mem == NULL)
2003 addr->mem = new_NoMem();
2005 dbgi = get_irn_dbg_info(node);
2006 block = be_transform_node(src_block);
2007 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2009 if (get_mode_size_bits(mode) == 8) {
2010 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2013 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
2016 set_address(new_node, addr);
2017 set_ia32_op_type(new_node, ia32_AddrModeD);
2018 set_ia32_ls_mode(new_node, mode);
2019 SET_IA32_ORIG_NODE(new_node, node);
2021 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2022 mem_proj = be_transform_node(am.mem_proj);
2023 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2028 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2029 ir_node *ptr, ir_mode *mode,
2030 construct_unop_dest_func *func)
2032 ir_graph *irg = current_ir_graph;
2033 ir_node *src_block = get_nodes_block(node);
2039 ia32_address_mode_t am;
2040 ia32_address_t *addr = &am.addr;
2042 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2045 memset(&am, 0, sizeof(am));
2046 build_address(&am, op, ia32_create_am_double_use);
2048 dbgi = get_irn_dbg_info(node);
2049 block = be_transform_node(src_block);
2050 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2051 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2052 set_address(new_node, addr);
2053 set_ia32_op_type(new_node, ia32_AddrModeD);
2054 set_ia32_ls_mode(new_node, mode);
2055 SET_IA32_ORIG_NODE(new_node, node);
2057 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2058 mem_proj = be_transform_node(am.mem_proj);
2059 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2064 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2066 ir_mode *mode = get_irn_mode(node);
2067 ir_node *mux_true = get_Mux_true(node);
2068 ir_node *mux_false = get_Mux_false(node);
2079 ia32_address_t addr;
2081 if (get_mode_size_bits(mode) != 8)
2084 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2086 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2092 build_address_ptr(&addr, ptr, mem);
2094 irg = current_ir_graph;
2095 dbgi = get_irn_dbg_info(node);
2096 block = get_nodes_block(node);
2097 new_block = be_transform_node(block);
2098 cond = get_Mux_sel(node);
2099 flags = get_flags_node(cond, &pnc);
2100 new_mem = be_transform_node(mem);
2101 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2102 addr.index, addr.mem, flags, pnc, negated);
2103 set_address(new_node, &addr);
2104 set_ia32_op_type(new_node, ia32_AddrModeD);
2105 set_ia32_ls_mode(new_node, mode);
2106 SET_IA32_ORIG_NODE(new_node, node);
2111 static ir_node *try_create_dest_am(ir_node *node)
2113 ir_node *val = get_Store_value(node);
2114 ir_node *mem = get_Store_mem(node);
2115 ir_node *ptr = get_Store_ptr(node);
2116 ir_mode *mode = get_irn_mode(val);
2117 unsigned bits = get_mode_size_bits(mode);
2122 /* handle only GP modes for now... */
2123 if (!ia32_mode_needs_gp_reg(mode))
2127 /* store must be the only user of the val node */
2128 if (get_irn_n_edges(val) > 1)
2130 /* skip pointless convs */
2132 ir_node *conv_op = get_Conv_op(val);
2133 ir_mode *pred_mode = get_irn_mode(conv_op);
2134 if (!ia32_mode_needs_gp_reg(pred_mode))
2136 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2144 /* value must be in the same block */
2145 if (get_nodes_block(node) != get_nodes_block(val))
2148 switch (get_irn_opcode(val)) {
2150 op1 = get_Add_left(val);
2151 op2 = get_Add_right(val);
2152 if (ia32_cg_config.use_incdec) {
2153 if (is_Const_1(op2)) {
2154 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_IncMem);
2156 } else if (is_Const_Minus_1(op2)) {
2157 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_DecMem);
2161 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2162 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2163 match_dest_am | match_commutative |
2167 op1 = get_Sub_left(val);
2168 op2 = get_Sub_right(val);
2169 if (is_Const(op2)) {
2170 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2172 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2173 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2174 match_dest_am | match_immediate);
2177 op1 = get_And_left(val);
2178 op2 = get_And_right(val);
2179 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2180 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2181 match_dest_am | match_commutative |
2185 op1 = get_Or_left(val);
2186 op2 = get_Or_right(val);
2187 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2188 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2189 match_dest_am | match_commutative |
2193 op1 = get_Eor_left(val);
2194 op2 = get_Eor_right(val);
2195 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2196 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2197 match_dest_am | match_commutative |
2201 op1 = get_Shl_left(val);
2202 op2 = get_Shl_right(val);
2203 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2204 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2205 match_dest_am | match_immediate);
2208 op1 = get_Shr_left(val);
2209 op2 = get_Shr_right(val);
2210 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2211 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2212 match_dest_am | match_immediate);
2215 op1 = get_Shrs_left(val);
2216 op2 = get_Shrs_right(val);
2217 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2218 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2219 match_dest_am | match_immediate);
2222 op1 = get_Rotl_left(val);
2223 op2 = get_Rotl_right(val);
2224 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2225 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2226 match_dest_am | match_immediate);
2228 /* TODO: match ROR patterns... */
2230 new_node = try_create_SetMem(val, ptr, mem);
2233 op1 = get_Minus_op(val);
2234 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2237 /* should be lowered already */
2238 assert(mode != mode_b);
2239 op1 = get_Not_op(val);
2240 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2246 if (new_node != NULL) {
2247 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2248 get_irn_pinned(node) == op_pin_state_pinned) {
2249 set_irn_pinned(new_node, op_pin_state_pinned);
2256 static int is_float_to_int_conv(const ir_node *node)
2258 ir_mode *mode = get_irn_mode(node);
2262 if (mode != mode_Is && mode != mode_Hs)
2267 conv_op = get_Conv_op(node);
2268 conv_mode = get_irn_mode(conv_op);
2270 if (!mode_is_float(conv_mode))
2277 * Transform a Store(floatConst) into a sequence of
2280 * @return the created ia32 Store node
2282 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2284 ir_mode *mode = get_irn_mode(cns);
2285 unsigned size = get_mode_size_bytes(mode);
2286 tarval *tv = get_Const_tarval(cns);
2287 ir_node *block = get_nodes_block(node);
2288 ir_node *new_block = be_transform_node(block);
2289 ir_node *ptr = get_Store_ptr(node);
2290 ir_node *mem = get_Store_mem(node);
2291 ir_graph *irg = current_ir_graph;
2292 dbg_info *dbgi = get_irn_dbg_info(node);
2296 ia32_address_t addr;
2298 assert(size % 4 == 0);
2301 build_address_ptr(&addr, ptr, mem);
2305 get_tarval_sub_bits(tv, ofs) |
2306 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2307 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2308 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2309 ir_node *imm = create_Immediate(NULL, 0, val);
2311 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2312 addr.index, addr.mem, imm);
2314 set_irn_pinned(new_node, get_irn_pinned(node));
2315 set_ia32_op_type(new_node, ia32_AddrModeD);
2316 set_ia32_ls_mode(new_node, mode_Iu);
2317 set_address(new_node, &addr);
2318 SET_IA32_ORIG_NODE(new_node, node);
2321 ins[i++] = new_node;
2326 } while (size != 0);
2329 return new_rd_Sync(dbgi, irg, new_block, i, ins);
2336 * Generate a vfist or vfisttp instruction.
2338 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2339 ir_node *mem, ir_node *val, ir_node **fist)
2343 if (ia32_cg_config.use_fisttp) {
2344 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2345 if other users exists */
2346 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2347 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2348 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2349 be_new_Keep(reg_class, irg, block, 1, &value);
2351 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2354 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2357 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2363 * Transforms a general (no special case) Store.
2365 * @return the created ia32 Store node
2367 static ir_node *gen_general_Store(ir_node *node)
2369 ir_node *val = get_Store_value(node);
2370 ir_mode *mode = get_irn_mode(val);
2371 ir_node *block = get_nodes_block(node);
2372 ir_node *new_block = be_transform_node(block);
2373 ir_node *ptr = get_Store_ptr(node);
2374 ir_node *mem = get_Store_mem(node);
2375 ir_graph *irg = current_ir_graph;
2376 dbg_info *dbgi = get_irn_dbg_info(node);
2377 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2378 ir_node *new_val, *new_node, *store;
2379 ia32_address_t addr;
2381 /* check for destination address mode */
2382 new_node = try_create_dest_am(node);
2383 if (new_node != NULL)
2386 /* construct store address */
2387 memset(&addr, 0, sizeof(addr));
2388 ia32_create_address_mode(&addr, ptr, 0);
2390 if (addr.base == NULL) {
2393 addr.base = be_transform_node(addr.base);
2396 if (addr.index == NULL) {
2399 addr.index = be_transform_node(addr.index);
2401 addr.mem = be_transform_node(mem);
2403 if (mode_is_float(mode)) {
2404 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2406 while (is_Conv(val) && mode == get_irn_mode(val)) {
2407 ir_node *op = get_Conv_op(val);
2408 if (!mode_is_float(get_irn_mode(op)))
2412 new_val = be_transform_node(val);
2413 if (ia32_cg_config.use_sse2) {
2414 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2415 addr.index, addr.mem, new_val);
2417 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2418 addr.index, addr.mem, new_val, mode);
2421 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2422 val = get_Conv_op(val);
2424 /* TODO: is this optimisation still necessary at all (middleend)? */
2425 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2426 while (is_Conv(val)) {
2427 ir_node *op = get_Conv_op(val);
2428 if (!mode_is_float(get_irn_mode(op)))
2430 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2434 new_val = be_transform_node(val);
2435 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2437 new_val = create_immediate_or_transform(val, 0);
2438 assert(mode != mode_b);
2440 if (get_mode_size_bits(mode) == 8) {
2441 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2442 addr.index, addr.mem, new_val);
2444 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2445 addr.index, addr.mem, new_val);
2450 set_irn_pinned(store, get_irn_pinned(node));
2451 set_ia32_op_type(store, ia32_AddrModeD);
2452 set_ia32_ls_mode(store, mode);
2454 set_address(store, &addr);
2455 SET_IA32_ORIG_NODE(store, node);
2461 * Transforms a Store.
2463 * @return the created ia32 Store node
2465 static ir_node *gen_Store(ir_node *node)
2467 ir_node *val = get_Store_value(node);
2468 ir_mode *mode = get_irn_mode(val);
2470 if (mode_is_float(mode) && is_Const(val)) {
2471 /* We can transform every floating const store
2472 into a sequence of integer stores.
2473 If the constant is already in a register,
2474 it would be better to use it, but we don't
2475 have this information here. */
2476 return gen_float_const_Store(node, val);
2478 return gen_general_Store(node);
2482 * Transforms a Switch.
2484 * @return the created ia32 SwitchJmp node
2486 static ir_node *create_Switch(ir_node *node)
2488 ir_graph *irg = current_ir_graph;
2489 dbg_info *dbgi = get_irn_dbg_info(node);
2490 ir_node *block = be_transform_node(get_nodes_block(node));
2491 ir_node *sel = get_Cond_selector(node);
2492 ir_node *new_sel = be_transform_node(sel);
2493 int switch_min = INT_MAX;
2494 int switch_max = INT_MIN;
2495 long default_pn = get_Cond_defaultProj(node);
2497 const ir_edge_t *edge;
2499 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2501 /* determine the smallest switch case value */
2502 foreach_out_edge(node, edge) {
2503 ir_node *proj = get_edge_src_irn(edge);
2504 long pn = get_Proj_proj(proj);
2505 if (pn == default_pn)
2508 if (pn < switch_min)
2510 if (pn > switch_max)
2514 if ((unsigned) (switch_max - switch_min) > 256000) {
2515 panic("Size of switch %+F bigger than 256000", node);
2518 if (switch_min != 0) {
2519 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2521 /* if smallest switch case is not 0 we need an additional sub */
2522 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2523 add_ia32_am_offs_int(new_sel, -switch_min);
2524 set_ia32_op_type(new_sel, ia32_AddrModeS);
2526 SET_IA32_ORIG_NODE(new_sel, node);
2529 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2530 SET_IA32_ORIG_NODE(new_node, node);
2536 * Transform a Cond node.
2538 static ir_node *gen_Cond(ir_node *node)
2540 ir_node *block = get_nodes_block(node);
2541 ir_node *new_block = be_transform_node(block);
2542 ir_graph *irg = current_ir_graph;
2543 dbg_info *dbgi = get_irn_dbg_info(node);
2544 ir_node *sel = get_Cond_selector(node);
2545 ir_mode *sel_mode = get_irn_mode(sel);
2546 ir_node *flags = NULL;
2550 if (sel_mode != mode_b) {
2551 return create_Switch(node);
2554 /* we get flags from a Cmp */
2555 flags = get_flags_node(sel, &pnc);
2557 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2558 SET_IA32_ORIG_NODE(new_node, node);
2563 static ir_node *gen_be_Copy(ir_node *node)
2565 ir_node *new_node = be_duplicate_node(node);
2566 ir_mode *mode = get_irn_mode(new_node);
2568 if (ia32_mode_needs_gp_reg(mode)) {
2569 set_irn_mode(new_node, mode_Iu);
2575 static ir_node *create_Fucom(ir_node *node)
2577 ir_graph *irg = current_ir_graph;
2578 dbg_info *dbgi = get_irn_dbg_info(node);
2579 ir_node *block = get_nodes_block(node);
2580 ir_node *new_block = be_transform_node(block);
2581 ir_node *left = get_Cmp_left(node);
2582 ir_node *new_left = be_transform_node(left);
2583 ir_node *right = get_Cmp_right(node);
2587 if (ia32_cg_config.use_fucomi) {
2588 new_right = be_transform_node(right);
2589 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2591 set_ia32_commutative(new_node);
2592 SET_IA32_ORIG_NODE(new_node, node);
2594 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2595 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2598 new_right = be_transform_node(right);
2599 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2603 set_ia32_commutative(new_node);
2605 SET_IA32_ORIG_NODE(new_node, node);
2607 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2608 SET_IA32_ORIG_NODE(new_node, node);
2614 static ir_node *create_Ucomi(ir_node *node)
2616 ir_graph *irg = current_ir_graph;
2617 dbg_info *dbgi = get_irn_dbg_info(node);
2618 ir_node *src_block = get_nodes_block(node);
2619 ir_node *new_block = be_transform_node(src_block);
2620 ir_node *left = get_Cmp_left(node);
2621 ir_node *right = get_Cmp_right(node);
2623 ia32_address_mode_t am;
2624 ia32_address_t *addr = &am.addr;
2626 match_arguments(&am, src_block, left, right, NULL,
2627 match_commutative | match_am);
2629 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2630 addr->mem, am.new_op1, am.new_op2,
2632 set_am_attributes(new_node, &am);
2634 SET_IA32_ORIG_NODE(new_node, node);
2636 new_node = fix_mem_proj(new_node, &am);
2642 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2643 * to fold an and into a test node
2645 static bool can_fold_test_and(ir_node *node)
2647 const ir_edge_t *edge;
2649 /** we can only have eq and lg projs */
2650 foreach_out_edge(node, edge) {
2651 ir_node *proj = get_edge_src_irn(edge);
2652 pn_Cmp pnc = get_Proj_proj(proj);
2653 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2661 * returns true if it is assured, that the upper bits of a node are "clean"
2662 * which means for a 16 or 8 bit value, that the upper bits in the register
2663 * are 0 for unsigned and a copy of the last significant bit for signed
2666 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2668 assert(ia32_mode_needs_gp_reg(mode));
2669 if (get_mode_size_bits(mode) >= 32)
2672 if (is_Proj(transformed_node))
2673 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2675 if (is_ia32_Conv_I2I(transformed_node)
2676 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2677 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2678 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2680 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2686 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2687 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2688 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2689 const ia32_immediate_attr_t *attr
2690 = get_ia32_immediate_attr_const(right);
2691 if (attr->symconst == 0
2692 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2696 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2699 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2700 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2701 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2702 const ia32_immediate_attr_t *attr
2703 = get_ia32_immediate_attr_const(right);
2704 if (attr->symconst == 0
2705 && (unsigned) attr->offset
2706 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2713 /* TODO recurse on Or, Xor, ... if appropriate? */
2715 if (is_ia32_Immediate(transformed_node)
2716 || is_ia32_Const(transformed_node)) {
2717 const ia32_immediate_attr_t *attr
2718 = get_ia32_immediate_attr_const(transformed_node);
2719 if (mode_is_signed(mode)) {
2720 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2721 if (shifted == 0 || shifted == -1)
2724 unsigned long shifted = (unsigned long) attr->offset;
2725 shifted >>= get_mode_size_bits(mode);
2735 * Generate code for a Cmp.
2737 static ir_node *gen_Cmp(ir_node *node)
2739 ir_graph *irg = current_ir_graph;
2740 dbg_info *dbgi = get_irn_dbg_info(node);
2741 ir_node *block = get_nodes_block(node);
2742 ir_node *new_block = be_transform_node(block);
2743 ir_node *left = get_Cmp_left(node);
2744 ir_node *right = get_Cmp_right(node);
2745 ir_mode *cmp_mode = get_irn_mode(left);
2747 ia32_address_mode_t am;
2748 ia32_address_t *addr = &am.addr;
2751 if (mode_is_float(cmp_mode)) {
2752 if (ia32_cg_config.use_sse2) {
2753 return create_Ucomi(node);
2755 return create_Fucom(node);
2759 assert(ia32_mode_needs_gp_reg(cmp_mode));
2761 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2762 cmp_unsigned = !mode_is_signed(cmp_mode);
2763 if (is_Const_0(right) &&
2765 get_irn_n_edges(left) == 1 &&
2766 can_fold_test_and(node)) {
2767 /* Test(and_left, and_right) */
2768 ir_node *and_left = get_And_left(left);
2769 ir_node *and_right = get_And_right(left);
2771 /* matze: code here used mode instead of cmd_mode, I think it is always
2772 * the same as cmp_mode, but I leave this here to see if this is really
2775 assert(get_irn_mode(and_left) == cmp_mode);
2777 match_arguments(&am, block, and_left, and_right, NULL,
2779 match_am | match_8bit_am | match_16bit_am |
2780 match_am_and_immediates | match_immediate |
2781 match_8bit | match_16bit);
2783 /* use 32bit compare mode if possible since the opcode is smaller */
2784 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2785 upper_bits_clean(am.new_op2, cmp_mode)) {
2786 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2789 if (get_mode_size_bits(cmp_mode) == 8) {
2790 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2791 addr->index, addr->mem, am.new_op1,
2792 am.new_op2, am.ins_permuted,
2795 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2796 addr->index, addr->mem, am.new_op1,
2797 am.new_op2, am.ins_permuted,
2801 /* Cmp(left, right) */
2802 match_arguments(&am, block, left, right, NULL,
2803 match_commutative | match_am | match_8bit_am |
2804 match_16bit_am | match_am_and_immediates |
2805 match_immediate | match_8bit | match_16bit);
2806 /* use 32bit compare mode if possible since the opcode is smaller */
2807 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2808 upper_bits_clean(am.new_op2, cmp_mode)) {
2809 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2812 if (get_mode_size_bits(cmp_mode) == 8) {
2813 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2814 addr->index, addr->mem, am.new_op1,
2815 am.new_op2, am.ins_permuted,
2818 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2819 addr->index, addr->mem, am.new_op1,
2820 am.new_op2, am.ins_permuted, cmp_unsigned);
2823 set_am_attributes(new_node, &am);
2824 set_ia32_ls_mode(new_node, cmp_mode);
2826 SET_IA32_ORIG_NODE(new_node, node);
2828 new_node = fix_mem_proj(new_node, &am);
2833 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2836 ir_graph *irg = current_ir_graph;
2837 dbg_info *dbgi = get_irn_dbg_info(node);
2838 ir_node *block = get_nodes_block(node);
2839 ir_node *new_block = be_transform_node(block);
2840 ir_node *val_true = get_Mux_true(node);
2841 ir_node *val_false = get_Mux_false(node);
2843 match_flags_t match_flags;
2844 ia32_address_mode_t am;
2845 ia32_address_t *addr;
2847 assert(ia32_cg_config.use_cmov);
2848 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2852 match_flags = match_commutative | match_am | match_16bit_am |
2855 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2857 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2858 addr->mem, am.new_op1, am.new_op2, new_flags,
2859 am.ins_permuted, pnc);
2860 set_am_attributes(new_node, &am);
2862 SET_IA32_ORIG_NODE(new_node, node);
2864 new_node = fix_mem_proj(new_node, &am);
2870 * Creates a ia32 Setcc instruction.
2872 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2873 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2876 ir_graph *irg = current_ir_graph;
2877 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2878 ir_node *nomem = new_NoMem();
2879 ir_mode *mode = get_irn_mode(orig_node);
2882 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2883 SET_IA32_ORIG_NODE(new_node, orig_node);
2885 /* we might need to conv the result up */
2886 if (get_mode_size_bits(mode) > 8) {
2887 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2888 nomem, new_node, mode_Bu);
2889 SET_IA32_ORIG_NODE(new_node, orig_node);
2896 * Create instruction for an unsigned Difference or Zero.
2898 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2900 ir_graph *irg = current_ir_graph;
2901 ir_mode *mode = get_irn_mode(psi);
2902 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2905 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2906 match_mode_neutral | match_am | match_immediate | match_two_users);
2908 block = get_nodes_block(new_node);
2910 if (is_Proj(new_node)) {
2911 sub = get_Proj_pred(new_node);
2912 assert(is_ia32_Sub(sub));
2915 set_irn_mode(sub, mode_T);
2916 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2918 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2920 dbgi = get_irn_dbg_info(psi);
2921 noreg = ia32_new_NoReg_gp(env_cg);
2922 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2923 nomem = new_NoMem();
2924 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2926 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2927 set_ia32_commutative(new_node);
2932 * Transforms a Mux node into CMov.
2934 * @return The transformed node.
2936 static ir_node *gen_Mux(ir_node *node)
2938 dbg_info *dbgi = get_irn_dbg_info(node);
2939 ir_node *block = get_nodes_block(node);
2940 ir_node *new_block = be_transform_node(block);
2941 ir_node *mux_true = get_Mux_true(node);
2942 ir_node *mux_false = get_Mux_false(node);
2943 ir_node *cond = get_Mux_sel(node);
2944 ir_mode *mode = get_irn_mode(node);
2947 assert(get_irn_mode(cond) == mode_b);
2949 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2950 if (mode_is_float(mode)) {
2951 ir_node *cmp = get_Proj_pred(cond);
2952 ir_node *cmp_left = get_Cmp_left(cmp);
2953 ir_node *cmp_right = get_Cmp_right(cmp);
2954 pn_Cmp pnc = get_Proj_proj(cond);
2956 if (ia32_cg_config.use_sse2) {
2957 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2958 if (cmp_left == mux_true && cmp_right == mux_false) {
2959 /* Mux(a <= b, a, b) => MIN */
2960 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2961 match_commutative | match_am | match_two_users);
2962 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2963 /* Mux(a <= b, b, a) => MAX */
2964 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2965 match_commutative | match_am | match_two_users);
2967 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2968 if (cmp_left == mux_true && cmp_right == mux_false) {
2969 /* Mux(a >= b, a, b) => MAX */
2970 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2971 match_commutative | match_am | match_two_users);
2972 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2973 /* Mux(a >= b, b, a) => MIN */
2974 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2975 match_commutative | match_am | match_two_users);
2979 panic("cannot transform floating point Mux");
2985 assert(ia32_mode_needs_gp_reg(mode));
2987 if (is_Proj(cond)) {
2988 ir_node *cmp = get_Proj_pred(cond);
2990 ir_node *cmp_left = get_Cmp_left(cmp);
2991 ir_node *cmp_right = get_Cmp_right(cmp);
2992 pn_Cmp pnc = get_Proj_proj(cond);
2994 /* check for unsigned Doz first */
2995 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2996 is_Const_0(mux_false) && is_Sub(mux_true) &&
2997 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2998 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2999 return create_Doz(node, cmp_left, cmp_right);
3000 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3001 is_Const_0(mux_true) && is_Sub(mux_false) &&
3002 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3003 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3004 return create_Doz(node, cmp_left, cmp_right);
3009 flags = get_flags_node(cond, &pnc);
3011 if (is_Const(mux_true) && is_Const(mux_false)) {
3012 /* both are const, good */
3013 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3014 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3015 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3016 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3018 /* Not that simple. */
3023 new_node = create_CMov(node, cond, flags, pnc);
3031 * Create a conversion from x87 state register to general purpose.
3033 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3035 ir_node *block = be_transform_node(get_nodes_block(node));
3036 ir_node *op = get_Conv_op(node);
3037 ir_node *new_op = be_transform_node(op);
3038 ia32_code_gen_t *cg = env_cg;
3039 ir_graph *irg = current_ir_graph;
3040 dbg_info *dbgi = get_irn_dbg_info(node);
3041 ir_node *noreg = ia32_new_NoReg_gp(cg);
3042 ir_mode *mode = get_irn_mode(node);
3043 ir_node *fist, *load, *mem;
3045 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3046 set_irn_pinned(fist, op_pin_state_floats);
3047 set_ia32_use_frame(fist);
3048 set_ia32_op_type(fist, ia32_AddrModeD);
3050 assert(get_mode_size_bits(mode) <= 32);
3051 /* exception we can only store signed 32 bit integers, so for unsigned
3052 we store a 64bit (signed) integer and load the lower bits */
3053 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3054 set_ia32_ls_mode(fist, mode_Ls);
3056 set_ia32_ls_mode(fist, mode_Is);
3058 SET_IA32_ORIG_NODE(fist, node);
3061 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3063 set_irn_pinned(load, op_pin_state_floats);
3064 set_ia32_use_frame(load);
3065 set_ia32_op_type(load, ia32_AddrModeS);
3066 set_ia32_ls_mode(load, mode_Is);
3067 if (get_ia32_ls_mode(fist) == mode_Ls) {
3068 ia32_attr_t *attr = get_ia32_attr(load);
3069 attr->data.need_64bit_stackent = 1;
3071 ia32_attr_t *attr = get_ia32_attr(load);
3072 attr->data.need_32bit_stackent = 1;
3074 SET_IA32_ORIG_NODE(load, node);
3076 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3080 * Creates a x87 strict Conv by placing a Store and a Load
3082 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3084 ir_node *block = get_nodes_block(node);
3085 ir_graph *irg = current_ir_graph;
3086 dbg_info *dbgi = get_irn_dbg_info(node);
3087 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3088 ir_node *nomem = new_NoMem();
3089 ir_node *frame = get_irg_frame(irg);
3090 ir_node *store, *load;
3093 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3095 set_ia32_use_frame(store);
3096 set_ia32_op_type(store, ia32_AddrModeD);
3097 SET_IA32_ORIG_NODE(store, node);
3099 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3101 set_ia32_use_frame(load);
3102 set_ia32_op_type(load, ia32_AddrModeS);
3103 SET_IA32_ORIG_NODE(load, node);
3105 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3110 * Create a conversion from general purpose to x87 register
3112 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3114 ir_node *src_block = get_nodes_block(node);
3115 ir_node *block = be_transform_node(src_block);
3116 ir_graph *irg = current_ir_graph;
3117 dbg_info *dbgi = get_irn_dbg_info(node);
3118 ir_node *op = get_Conv_op(node);
3119 ir_node *new_op = NULL;
3123 ir_mode *store_mode;
3129 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3130 if (src_mode == mode_Is || src_mode == mode_Hs) {
3131 ia32_address_mode_t am;
3133 match_arguments(&am, src_block, NULL, op, NULL,
3134 match_am | match_try_am | match_16bit | match_16bit_am);
3135 if (am.op_type == ia32_AddrModeS) {
3136 ia32_address_t *addr = &am.addr;
3138 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3139 addr->index, addr->mem);
3140 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3143 set_am_attributes(fild, &am);
3144 SET_IA32_ORIG_NODE(fild, node);
3146 fix_mem_proj(fild, &am);
3151 if (new_op == NULL) {
3152 new_op = be_transform_node(op);
3155 noreg = ia32_new_NoReg_gp(env_cg);
3156 nomem = new_NoMem();
3157 mode = get_irn_mode(op);
3159 /* first convert to 32 bit signed if necessary */
3160 src_bits = get_mode_size_bits(src_mode);
3161 if (src_bits == 8) {
3162 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3164 SET_IA32_ORIG_NODE(new_op, node);
3166 } else if (src_bits < 32) {
3167 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3169 SET_IA32_ORIG_NODE(new_op, node);
3173 assert(get_mode_size_bits(mode) == 32);
3176 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3179 set_ia32_use_frame(store);
3180 set_ia32_op_type(store, ia32_AddrModeD);
3181 set_ia32_ls_mode(store, mode_Iu);
3183 /* exception for 32bit unsigned, do a 64bit spill+load */
3184 if (!mode_is_signed(mode)) {
3187 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3189 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3190 get_irg_frame(irg), noreg, nomem,
3193 set_ia32_use_frame(zero_store);
3194 set_ia32_op_type(zero_store, ia32_AddrModeD);
3195 add_ia32_am_offs_int(zero_store, 4);
3196 set_ia32_ls_mode(zero_store, mode_Iu);
3201 store = new_rd_Sync(dbgi, irg, block, 2, in);
3202 store_mode = mode_Ls;
3204 store_mode = mode_Is;
3208 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3210 set_ia32_use_frame(fild);
3211 set_ia32_op_type(fild, ia32_AddrModeS);
3212 set_ia32_ls_mode(fild, store_mode);
3214 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3220 * Create a conversion from one integer mode into another one
3222 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3223 dbg_info *dbgi, ir_node *block, ir_node *op,
3226 ir_graph *irg = current_ir_graph;
3227 int src_bits = get_mode_size_bits(src_mode);
3228 int tgt_bits = get_mode_size_bits(tgt_mode);
3229 ir_node *new_block = be_transform_node(block);
3231 ir_mode *smaller_mode;
3233 ia32_address_mode_t am;
3234 ia32_address_t *addr = &am.addr;
3237 if (src_bits < tgt_bits) {
3238 smaller_mode = src_mode;
3239 smaller_bits = src_bits;
3241 smaller_mode = tgt_mode;
3242 smaller_bits = tgt_bits;
3245 #ifdef DEBUG_libfirm
3247 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3252 match_arguments(&am, block, NULL, op, NULL,
3253 match_8bit | match_16bit |
3254 match_am | match_8bit_am | match_16bit_am);
3256 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3257 /* unnecessary conv. in theory it shouldn't have been AM */
3258 assert(is_ia32_NoReg_GP(addr->base));
3259 assert(is_ia32_NoReg_GP(addr->index));
3260 assert(is_NoMem(addr->mem));
3261 assert(am.addr.offset == 0);
3262 assert(am.addr.symconst_ent == NULL);
3266 if (smaller_bits == 8) {
3267 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3268 addr->index, addr->mem, am.new_op2,
3271 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3272 addr->index, addr->mem, am.new_op2,
3275 set_am_attributes(new_node, &am);
3276 /* match_arguments assume that out-mode = in-mode, this isn't true here
3278 set_ia32_ls_mode(new_node, smaller_mode);
3279 SET_IA32_ORIG_NODE(new_node, node);
3280 new_node = fix_mem_proj(new_node, &am);
3285 * Transforms a Conv node.
3287 * @return The created ia32 Conv node
3289 static ir_node *gen_Conv(ir_node *node)
3291 ir_node *block = get_nodes_block(node);
3292 ir_node *new_block = be_transform_node(block);
3293 ir_node *op = get_Conv_op(node);
3294 ir_node *new_op = NULL;
3295 ir_graph *irg = current_ir_graph;
3296 dbg_info *dbgi = get_irn_dbg_info(node);
3297 ir_mode *src_mode = get_irn_mode(op);
3298 ir_mode *tgt_mode = get_irn_mode(node);
3299 int src_bits = get_mode_size_bits(src_mode);
3300 int tgt_bits = get_mode_size_bits(tgt_mode);
3301 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3302 ir_node *nomem = new_rd_NoMem(irg);
3303 ir_node *res = NULL;
3305 if (src_mode == mode_b) {
3306 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3307 /* nothing to do, we already model bools as 0/1 ints */
3308 return be_transform_node(op);
3311 if (src_mode == tgt_mode) {
3312 if (get_Conv_strict(node)) {
3313 if (ia32_cg_config.use_sse2) {
3314 /* when we are in SSE mode, we can kill all strict no-op conversion */
3315 return be_transform_node(op);
3318 /* this should be optimized already, but who knows... */
3319 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3320 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3321 return be_transform_node(op);
3325 if (mode_is_float(src_mode)) {
3326 new_op = be_transform_node(op);
3327 /* we convert from float ... */
3328 if (mode_is_float(tgt_mode)) {
3329 if (src_mode == mode_E && tgt_mode == mode_D
3330 && !get_Conv_strict(node)) {
3331 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3336 if (ia32_cg_config.use_sse2) {
3337 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3338 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3340 set_ia32_ls_mode(res, tgt_mode);
3342 if (get_Conv_strict(node)) {
3343 res = gen_x87_strict_conv(tgt_mode, new_op);
3344 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3347 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3352 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3353 if (ia32_cg_config.use_sse2) {
3354 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3356 set_ia32_ls_mode(res, src_mode);
3358 return gen_x87_fp_to_gp(node);
3362 /* we convert from int ... */
3363 if (mode_is_float(tgt_mode)) {
3365 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3366 if (ia32_cg_config.use_sse2) {
3367 new_op = be_transform_node(op);
3368 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3370 set_ia32_ls_mode(res, tgt_mode);
3372 res = gen_x87_gp_to_fp(node, src_mode);
3373 if (get_Conv_strict(node)) {
3374 /* The strict-Conv is only necessary, if the int mode has more bits
3375 * than the float mantissa */
3376 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3377 size_t float_mantissa;
3378 /* FIXME There is no way to get the mantissa size of a mode */
3379 switch (get_mode_size_bits(tgt_mode)) {
3380 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3381 case 64: float_mantissa = 52 + 1; break;
3383 case 96: float_mantissa = 64; break;
3384 default: float_mantissa = 0; break;
3386 if (float_mantissa < int_mantissa) {
3387 res = gen_x87_strict_conv(tgt_mode, res);
3388 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3393 } else if (tgt_mode == mode_b) {
3394 /* mode_b lowering already took care that we only have 0/1 values */
3395 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3396 src_mode, tgt_mode));
3397 return be_transform_node(op);
3400 if (src_bits == tgt_bits) {
3401 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3402 src_mode, tgt_mode));
3403 return be_transform_node(op);
3406 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3414 static ir_node *create_immediate_or_transform(ir_node *node,
3415 char immediate_constraint_type)
3417 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3418 if (new_node == NULL) {
3419 new_node = be_transform_node(node);
3425 * Transforms a FrameAddr into an ia32 Add.
3427 static ir_node *gen_be_FrameAddr(ir_node *node)
3429 ir_node *block = be_transform_node(get_nodes_block(node));
3430 ir_node *op = be_get_FrameAddr_frame(node);
3431 ir_node *new_op = be_transform_node(op);
3432 ir_graph *irg = current_ir_graph;
3433 dbg_info *dbgi = get_irn_dbg_info(node);
3434 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3437 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3438 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3439 set_ia32_use_frame(new_node);
3441 SET_IA32_ORIG_NODE(new_node, node);
3447 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3449 static ir_node *gen_be_Return(ir_node *node)
3451 ir_graph *irg = current_ir_graph;
3452 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3453 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3454 ir_entity *ent = get_irg_entity(irg);
3455 ir_type *tp = get_entity_type(ent);
3460 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3461 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3464 int pn_ret_val, pn_ret_mem, arity, i;
3466 assert(ret_val != NULL);
3467 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3468 return be_duplicate_node(node);
3471 res_type = get_method_res_type(tp, 0);
3473 if (! is_Primitive_type(res_type)) {
3474 return be_duplicate_node(node);
3477 mode = get_type_mode(res_type);
3478 if (! mode_is_float(mode)) {
3479 return be_duplicate_node(node);
3482 assert(get_method_n_ress(tp) == 1);
3484 pn_ret_val = get_Proj_proj(ret_val);
3485 pn_ret_mem = get_Proj_proj(ret_mem);
3487 /* get the Barrier */
3488 barrier = get_Proj_pred(ret_val);
3490 /* get result input of the Barrier */
3491 ret_val = get_irn_n(barrier, pn_ret_val);
3492 new_ret_val = be_transform_node(ret_val);
3494 /* get memory input of the Barrier */
3495 ret_mem = get_irn_n(barrier, pn_ret_mem);
3496 new_ret_mem = be_transform_node(ret_mem);
3498 frame = get_irg_frame(irg);
3500 dbgi = get_irn_dbg_info(barrier);
3501 block = be_transform_node(get_nodes_block(barrier));
3503 noreg = ia32_new_NoReg_gp(env_cg);
3505 /* store xmm0 onto stack */
3506 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3507 new_ret_mem, new_ret_val);
3508 set_ia32_ls_mode(sse_store, mode);
3509 set_ia32_op_type(sse_store, ia32_AddrModeD);
3510 set_ia32_use_frame(sse_store);
3512 /* load into x87 register */
3513 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3514 set_ia32_op_type(fld, ia32_AddrModeS);
3515 set_ia32_use_frame(fld);
3517 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3518 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3520 /* create a new barrier */
3521 arity = get_irn_arity(barrier);
3522 in = ALLOCAN(ir_node*, arity);
3523 for (i = 0; i < arity; ++i) {
3526 if (i == pn_ret_val) {
3528 } else if (i == pn_ret_mem) {
3531 ir_node *in = get_irn_n(barrier, i);
3532 new_in = be_transform_node(in);
3537 new_barrier = new_ir_node(dbgi, irg, block,
3538 get_irn_op(barrier), get_irn_mode(barrier),
3540 copy_node_attr(barrier, new_barrier);
3541 be_duplicate_deps(barrier, new_barrier);
3542 be_set_transformed_node(barrier, new_barrier);
3544 /* transform normally */
3545 return be_duplicate_node(node);
3549 * Transform a be_AddSP into an ia32_SubSP.
3551 static ir_node *gen_be_AddSP(ir_node *node)
3553 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3554 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3556 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3557 match_am | match_immediate);
3561 * Transform a be_SubSP into an ia32_AddSP
3563 static ir_node *gen_be_SubSP(ir_node *node)
3565 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3566 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3568 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3569 match_am | match_immediate);
3573 * Change some phi modes
3575 static ir_node *gen_Phi(ir_node *node)
3577 ir_node *block = be_transform_node(get_nodes_block(node));
3578 ir_graph *irg = current_ir_graph;
3579 dbg_info *dbgi = get_irn_dbg_info(node);
3580 ir_mode *mode = get_irn_mode(node);
3583 if (ia32_mode_needs_gp_reg(mode)) {
3584 /* we shouldn't have any 64bit stuff around anymore */
3585 assert(get_mode_size_bits(mode) <= 32);
3586 /* all integer operations are on 32bit registers now */
3588 } else if (mode_is_float(mode)) {
3589 if (ia32_cg_config.use_sse2) {
3596 /* phi nodes allow loops, so we use the old arguments for now
3597 * and fix this later */
3598 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3599 get_irn_in(node) + 1);
3600 copy_node_attr(node, phi);
3601 be_duplicate_deps(node, phi);
3603 be_enqueue_preds(node);
3611 static ir_node *gen_IJmp(ir_node *node)
3613 ir_node *block = get_nodes_block(node);
3614 ir_node *new_block = be_transform_node(block);
3615 dbg_info *dbgi = get_irn_dbg_info(node);
3616 ir_node *op = get_IJmp_target(node);
3618 ia32_address_mode_t am;
3619 ia32_address_t *addr = &am.addr;
3621 assert(get_irn_mode(op) == mode_P);
3623 match_arguments(&am, block, NULL, op, NULL,
3624 match_am | match_8bit_am | match_16bit_am |
3625 match_immediate | match_8bit | match_16bit);
3627 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3628 addr->base, addr->index, addr->mem,
3630 set_am_attributes(new_node, &am);
3631 SET_IA32_ORIG_NODE(new_node, node);
3633 new_node = fix_mem_proj(new_node, &am);
3639 * Transform a Bound node.
3641 static ir_node *gen_Bound(ir_node *node)
3644 ir_node *lower = get_Bound_lower(node);
3645 dbg_info *dbgi = get_irn_dbg_info(node);
3647 if (is_Const_0(lower)) {
3648 /* typical case for Java */
3649 ir_node *sub, *res, *flags, *block;
3650 ir_graph *irg = current_ir_graph;
3652 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3653 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3655 block = get_nodes_block(res);
3656 if (! is_Proj(res)) {
3658 set_irn_mode(sub, mode_T);
3659 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3661 sub = get_Proj_pred(res);
3663 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3664 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3665 SET_IA32_ORIG_NODE(new_node, node);
3667 panic("generic Bound not supported in ia32 Backend");
3673 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3675 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3676 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3678 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3679 match_immediate | match_mode_neutral);
3682 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3684 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3685 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3686 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3690 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3692 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3693 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3694 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3698 static ir_node *gen_ia32_l_Add(ir_node *node)
3700 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3701 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3702 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3703 match_commutative | match_am | match_immediate |
3704 match_mode_neutral);
3706 if (is_Proj(lowered)) {
3707 lowered = get_Proj_pred(lowered);
3709 assert(is_ia32_Add(lowered));
3710 set_irn_mode(lowered, mode_T);
3716 static ir_node *gen_ia32_l_Adc(ir_node *node)
3718 return gen_binop_flags(node, new_rd_ia32_Adc,
3719 match_commutative | match_am | match_immediate |
3720 match_mode_neutral);
3724 * Transforms a l_MulS into a "real" MulS node.
3726 * @return the created ia32 Mul node
3728 static ir_node *gen_ia32_l_Mul(ir_node *node)
3730 ir_node *left = get_binop_left(node);
3731 ir_node *right = get_binop_right(node);
3733 return gen_binop(node, left, right, new_rd_ia32_Mul,
3734 match_commutative | match_am | match_mode_neutral);
3738 * Transforms a l_IMulS into a "real" IMul1OPS node.
3740 * @return the created ia32 IMul1OP node
3742 static ir_node *gen_ia32_l_IMul(ir_node *node)
3744 ir_node *left = get_binop_left(node);
3745 ir_node *right = get_binop_right(node);
3747 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3748 match_commutative | match_am | match_mode_neutral);
3751 static ir_node *gen_ia32_l_Sub(ir_node *node)
3753 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3754 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3755 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3756 match_am | match_immediate | match_mode_neutral);
3758 if (is_Proj(lowered)) {
3759 lowered = get_Proj_pred(lowered);
3761 assert(is_ia32_Sub(lowered));
3762 set_irn_mode(lowered, mode_T);
3768 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3770 return gen_binop_flags(node, new_rd_ia32_Sbb,
3771 match_am | match_immediate | match_mode_neutral);
3775 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3776 * op1 - target to be shifted
3777 * op2 - contains bits to be shifted into target
3779 * Only op3 can be an immediate.
3781 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3782 ir_node *low, ir_node *count)
3784 ir_node *block = get_nodes_block(node);
3785 ir_node *new_block = be_transform_node(block);
3786 ir_graph *irg = current_ir_graph;
3787 dbg_info *dbgi = get_irn_dbg_info(node);
3788 ir_node *new_high = be_transform_node(high);
3789 ir_node *new_low = be_transform_node(low);
3793 /* the shift amount can be any mode that is bigger than 5 bits, since all
3794 * other bits are ignored anyway */
3795 while (is_Conv(count) &&
3796 get_irn_n_edges(count) == 1 &&
3797 mode_is_int(get_irn_mode(count))) {
3798 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3799 count = get_Conv_op(count);
3801 new_count = create_immediate_or_transform(count, 0);
3803 if (is_ia32_l_ShlD(node)) {
3804 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3807 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3810 SET_IA32_ORIG_NODE(new_node, node);
3815 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3817 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3818 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3819 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3820 return gen_lowered_64bit_shifts(node, high, low, count);
3823 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3825 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3826 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3827 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3828 return gen_lowered_64bit_shifts(node, high, low, count);
3831 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3833 ir_node *src_block = get_nodes_block(node);
3834 ir_node *block = be_transform_node(src_block);
3835 ir_graph *irg = current_ir_graph;
3836 dbg_info *dbgi = get_irn_dbg_info(node);
3837 ir_node *frame = get_irg_frame(irg);
3838 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3839 ir_node *nomem = new_NoMem();
3840 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3841 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3842 ir_node *new_val_low = be_transform_node(val_low);
3843 ir_node *new_val_high = be_transform_node(val_high);
3848 ir_node *store_high;
3850 if (!mode_is_signed(get_irn_mode(val_high))) {
3851 panic("unsigned long long -> float not supported yet (%+F)", node);
3855 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3857 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3859 SET_IA32_ORIG_NODE(store_low, node);
3860 SET_IA32_ORIG_NODE(store_high, node);
3862 set_ia32_use_frame(store_low);
3863 set_ia32_use_frame(store_high);
3864 set_ia32_op_type(store_low, ia32_AddrModeD);
3865 set_ia32_op_type(store_high, ia32_AddrModeD);
3866 set_ia32_ls_mode(store_low, mode_Iu);
3867 set_ia32_ls_mode(store_high, mode_Is);
3868 add_ia32_am_offs_int(store_high, 4);
3872 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3875 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3877 set_ia32_use_frame(fild);
3878 set_ia32_op_type(fild, ia32_AddrModeS);
3879 set_ia32_ls_mode(fild, mode_Ls);
3881 SET_IA32_ORIG_NODE(fild, node);
3883 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3886 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3888 ir_node *src_block = get_nodes_block(node);
3889 ir_node *block = be_transform_node(src_block);
3890 ir_graph *irg = current_ir_graph;
3891 dbg_info *dbgi = get_irn_dbg_info(node);
3892 ir_node *frame = get_irg_frame(irg);
3893 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3894 ir_node *nomem = new_NoMem();
3895 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3896 ir_node *new_val = be_transform_node(val);
3897 ir_node *fist, *mem;
3899 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3900 SET_IA32_ORIG_NODE(fist, node);
3901 set_ia32_use_frame(fist);
3902 set_ia32_op_type(fist, ia32_AddrModeD);
3903 set_ia32_ls_mode(fist, mode_Ls);
3909 * the BAD transformer.
3911 static ir_node *bad_transform(ir_node *node)
3913 panic("No transform function for %+F available.", node);
3917 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3919 ir_graph *irg = current_ir_graph;
3920 ir_node *block = be_transform_node(get_nodes_block(node));
3921 ir_node *pred = get_Proj_pred(node);
3922 ir_node *new_pred = be_transform_node(pred);
3923 ir_node *frame = get_irg_frame(irg);
3924 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3925 dbg_info *dbgi = get_irn_dbg_info(node);
3926 long pn = get_Proj_proj(node);
3931 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3932 SET_IA32_ORIG_NODE(load, node);
3933 set_ia32_use_frame(load);
3934 set_ia32_op_type(load, ia32_AddrModeS);
3935 set_ia32_ls_mode(load, mode_Iu);
3936 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3937 * 32 bit from it with this particular load */
3938 attr = get_ia32_attr(load);
3939 attr->data.need_64bit_stackent = 1;
3941 if (pn == pn_ia32_l_FloattoLL_res_high) {
3942 add_ia32_am_offs_int(load, 4);
3944 assert(pn == pn_ia32_l_FloattoLL_res_low);
3947 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3953 * Transform the Projs of an AddSP.
3955 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3957 ir_node *block = be_transform_node(get_nodes_block(node));
3958 ir_node *pred = get_Proj_pred(node);
3959 ir_node *new_pred = be_transform_node(pred);
3960 ir_graph *irg = current_ir_graph;
3961 dbg_info *dbgi = get_irn_dbg_info(node);
3962 long proj = get_Proj_proj(node);
3964 if (proj == pn_be_AddSP_sp) {
3965 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3966 pn_ia32_SubSP_stack);
3967 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3969 } else if (proj == pn_be_AddSP_res) {
3970 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3971 pn_ia32_SubSP_addr);
3972 } else if (proj == pn_be_AddSP_M) {
3973 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3976 panic("No idea how to transform proj->AddSP");
3980 * Transform the Projs of a SubSP.
3982 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3984 ir_node *block = be_transform_node(get_nodes_block(node));
3985 ir_node *pred = get_Proj_pred(node);
3986 ir_node *new_pred = be_transform_node(pred);
3987 ir_graph *irg = current_ir_graph;
3988 dbg_info *dbgi = get_irn_dbg_info(node);
3989 long proj = get_Proj_proj(node);
3991 if (proj == pn_be_SubSP_sp) {
3992 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3993 pn_ia32_AddSP_stack);
3994 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3996 } else if (proj == pn_be_SubSP_M) {
3997 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4000 panic("No idea how to transform proj->SubSP");
4004 * Transform and renumber the Projs from a Load.
4006 static ir_node *gen_Proj_Load(ir_node *node)
4009 ir_node *block = be_transform_node(get_nodes_block(node));
4010 ir_node *pred = get_Proj_pred(node);
4011 ir_graph *irg = current_ir_graph;
4012 dbg_info *dbgi = get_irn_dbg_info(node);
4013 long proj = get_Proj_proj(node);
4015 /* loads might be part of source address mode matches, so we don't
4016 * transform the ProjMs yet (with the exception of loads whose result is
4019 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4022 /* this is needed, because sometimes we have loops that are only
4023 reachable through the ProjM */
4024 be_enqueue_preds(node);
4025 /* do it in 2 steps, to silence firm verifier */
4026 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4027 set_Proj_proj(res, pn_ia32_mem);
4031 /* renumber the proj */
4032 new_pred = be_transform_node(pred);
4033 if (is_ia32_Load(new_pred)) {
4036 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4038 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4039 case pn_Load_X_regular:
4040 return new_rd_Jmp(dbgi, irg, block);
4041 case pn_Load_X_except:
4042 /* This Load might raise an exception. Mark it. */
4043 set_ia32_exc_label(new_pred, 1);
4044 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4048 } else if (is_ia32_Conv_I2I(new_pred) ||
4049 is_ia32_Conv_I2I8Bit(new_pred)) {
4050 set_irn_mode(new_pred, mode_T);
4051 if (proj == pn_Load_res) {
4052 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4053 } else if (proj == pn_Load_M) {
4054 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4056 } else if (is_ia32_xLoad(new_pred)) {
4059 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4061 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4062 case pn_Load_X_regular:
4063 return new_rd_Jmp(dbgi, irg, block);
4064 case pn_Load_X_except:
4065 /* This Load might raise an exception. Mark it. */
4066 set_ia32_exc_label(new_pred, 1);
4067 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4071 } else if (is_ia32_vfld(new_pred)) {
4074 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4076 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4077 case pn_Load_X_regular:
4078 return new_rd_Jmp(dbgi, irg, block);
4079 case pn_Load_X_except:
4080 /* This Load might raise an exception. Mark it. */
4081 set_ia32_exc_label(new_pred, 1);
4082 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4087 /* can happen for ProJMs when source address mode happened for the
4090 /* however it should not be the result proj, as that would mean the
4091 load had multiple users and should not have been used for
4093 if (proj != pn_Load_M) {
4094 panic("internal error: transformed node not a Load");
4096 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4099 panic("No idea how to transform proj");
4103 * Transform and renumber the Projs from a DivMod like instruction.
4105 static ir_node *gen_Proj_DivMod(ir_node *node)
4107 ir_node *block = be_transform_node(get_nodes_block(node));
4108 ir_node *pred = get_Proj_pred(node);
4109 ir_node *new_pred = be_transform_node(pred);
4110 ir_graph *irg = current_ir_graph;
4111 dbg_info *dbgi = get_irn_dbg_info(node);
4112 long proj = get_Proj_proj(node);
4114 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4116 switch (get_irn_opcode(pred)) {
4120 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4122 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4123 case pn_Div_X_regular:
4124 return new_rd_Jmp(dbgi, irg, block);
4125 case pn_Div_X_except:
4126 set_ia32_exc_label(new_pred, 1);
4127 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4135 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4137 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4138 case pn_Mod_X_except:
4139 set_ia32_exc_label(new_pred, 1);
4140 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4148 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4149 case pn_DivMod_res_div:
4150 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4151 case pn_DivMod_res_mod:
4152 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4153 case pn_DivMod_X_regular:
4154 return new_rd_Jmp(dbgi, irg, block);
4155 case pn_DivMod_X_except:
4156 set_ia32_exc_label(new_pred, 1);
4157 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4166 panic("No idea how to transform proj->DivMod");
4170 * Transform and renumber the Projs from a CopyB.
4172 static ir_node *gen_Proj_CopyB(ir_node *node)
4174 ir_node *block = be_transform_node(get_nodes_block(node));
4175 ir_node *pred = get_Proj_pred(node);
4176 ir_node *new_pred = be_transform_node(pred);
4177 ir_graph *irg = current_ir_graph;
4178 dbg_info *dbgi = get_irn_dbg_info(node);
4179 long proj = get_Proj_proj(node);
4182 case pn_CopyB_M_regular:
4183 if (is_ia32_CopyB_i(new_pred)) {
4184 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4185 } else if (is_ia32_CopyB(new_pred)) {
4186 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4193 panic("No idea how to transform proj->CopyB");
4197 * Transform and renumber the Projs from a Quot.
4199 static ir_node *gen_Proj_Quot(ir_node *node)
4201 ir_node *block = be_transform_node(get_nodes_block(node));
4202 ir_node *pred = get_Proj_pred(node);
4203 ir_node *new_pred = be_transform_node(pred);
4204 ir_graph *irg = current_ir_graph;
4205 dbg_info *dbgi = get_irn_dbg_info(node);
4206 long proj = get_Proj_proj(node);
4210 if (is_ia32_xDiv(new_pred)) {
4211 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4212 } else if (is_ia32_vfdiv(new_pred)) {
4213 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4217 if (is_ia32_xDiv(new_pred)) {
4218 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4219 } else if (is_ia32_vfdiv(new_pred)) {
4220 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4223 case pn_Quot_X_regular:
4224 case pn_Quot_X_except:
4229 panic("No idea how to transform proj->Quot");
4232 static ir_node *gen_be_Call(ir_node *node)
4234 dbg_info *const dbgi = get_irn_dbg_info(node);
4235 ir_graph *const irg = current_ir_graph;
4236 ir_node *const src_block = get_nodes_block(node);
4237 ir_node *const block = be_transform_node(src_block);
4238 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4239 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4240 ir_node *const sp = be_transform_node(src_sp);
4241 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4242 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4243 ia32_address_mode_t am;
4244 ia32_address_t *const addr = &am.addr;
4249 ir_node * eax = noreg;
4250 ir_node * ecx = noreg;
4251 ir_node * edx = noreg;
4252 unsigned const pop = be_Call_get_pop(node);
4253 ir_type *const call_tp = be_Call_get_type(node);
4255 /* Run the x87 simulator if the call returns a float value */
4256 if (get_method_n_ress(call_tp) > 0) {
4257 ir_type *const res_type = get_method_res_type(call_tp, 0);
4258 ir_mode *const res_mode = get_type_mode(res_type);
4260 if (res_mode != NULL && mode_is_float(res_mode)) {
4261 env_cg->do_x87_sim = 1;
4265 /* We do not want be_Call direct calls */
4266 assert(be_Call_get_entity(node) == NULL);
4268 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4269 match_am | match_immediate);
4271 i = get_irn_arity(node) - 1;
4272 fpcw = be_transform_node(get_irn_n(node, i--));
4273 for (; i >= be_pos_Call_first_arg; --i) {
4274 arch_register_req_t const *const req = arch_get_register_req(node, i);
4275 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4277 assert(req->type == arch_register_req_type_limited);
4278 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4280 switch (*req->limited) {
4281 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4282 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4283 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4284 default: panic("Invalid GP register for register parameter");
4288 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4289 call = new_rd_ia32_Call(dbgi, irg, block, addr->base, addr->index, mem,
4290 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4291 set_am_attributes(call, &am);
4292 call = fix_mem_proj(call, &am);
4294 if (get_irn_pinned(node) == op_pin_state_pinned)
4295 set_irn_pinned(call, op_pin_state_pinned);
4297 SET_IA32_ORIG_NODE(call, node);
4301 static ir_node *gen_be_IncSP(ir_node *node)
4303 ir_node *res = be_duplicate_node(node);
4304 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4310 * Transform the Projs from a be_Call.
4312 static ir_node *gen_Proj_be_Call(ir_node *node)
4314 ir_node *block = be_transform_node(get_nodes_block(node));
4315 ir_node *call = get_Proj_pred(node);
4316 ir_node *new_call = be_transform_node(call);
4317 ir_graph *irg = current_ir_graph;
4318 dbg_info *dbgi = get_irn_dbg_info(node);
4319 ir_type *method_type = be_Call_get_type(call);
4320 int n_res = get_method_n_ress(method_type);
4321 long proj = get_Proj_proj(node);
4322 ir_mode *mode = get_irn_mode(node);
4326 /* The following is kinda tricky: If we're using SSE, then we have to
4327 * move the result value of the call in floating point registers to an
4328 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4329 * after the call, we have to make sure to correctly make the
4330 * MemProj and the result Proj use these 2 nodes
4332 if (proj == pn_be_Call_M_regular) {
4333 // get new node for result, are we doing the sse load/store hack?
4334 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4335 ir_node *call_res_new;
4336 ir_node *call_res_pred = NULL;
4338 if (call_res != NULL) {
4339 call_res_new = be_transform_node(call_res);
4340 call_res_pred = get_Proj_pred(call_res_new);
4343 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4344 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4347 assert(is_ia32_xLoad(call_res_pred));
4348 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4352 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4353 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4355 ir_node *frame = get_irg_frame(irg);
4356 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4358 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4361 /* in case there is no memory output: create one to serialize the copy
4363 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4364 pn_be_Call_M_regular);
4365 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4366 pn_be_Call_first_res);
4368 /* store st(0) onto stack */
4369 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4371 set_ia32_op_type(fstp, ia32_AddrModeD);
4372 set_ia32_use_frame(fstp);
4374 /* load into SSE register */
4375 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4377 set_ia32_op_type(sse_load, ia32_AddrModeS);
4378 set_ia32_use_frame(sse_load);
4380 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4386 /* transform call modes */
4387 if (mode_is_data(mode)) {
4388 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4392 /* Map from be_Call to ia32_Call proj number */
4393 if (proj == pn_be_Call_sp) {
4394 proj = pn_ia32_Call_stack;
4395 } else if (proj == pn_be_Call_M_regular) {
4396 proj = pn_ia32_Call_M;
4398 arch_register_req_t const *const req = arch_get_register_req_out(node);
4399 int const n_outs = arch_irn_get_n_outs(new_call);
4402 assert(proj >= pn_be_Call_first_res);
4403 assert(req->type & arch_register_req_type_limited);
4405 for (i = 0; i < n_outs; ++i) {
4406 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4408 if (!(new_req->type & arch_register_req_type_limited) ||
4409 new_req->cls != req->cls ||
4410 *new_req->limited != *req->limited)
4419 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4421 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4423 case pn_ia32_Call_stack:
4424 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4427 case pn_ia32_Call_fpcw:
4428 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
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 arch_irn_get_n_outs(new_pred) + 1);
4488 * Transform and potentially renumber Proj nodes.
4490 static ir_node *gen_Proj(ir_node *node)
4492 ir_node *pred = get_Proj_pred(node);
4495 switch (get_irn_opcode(pred)) {
4497 proj = get_Proj_proj(node);
4498 if (proj == pn_Store_M) {
4499 return be_transform_node(pred);
4501 panic("No idea how to transform proj->Store");
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);
4528 case pn_Start_X_initial_exec: {
4529 ir_node *block = get_nodes_block(pred);
4530 ir_node *new_block = be_transform_node(block);
4531 dbg_info *dbgi = get_irn_dbg_info(node);
4532 /* we exchange the ProjX with a jump */
4533 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4538 case pn_Start_P_tls:
4539 return gen_Proj_tls(node);
4544 if (is_ia32_l_FloattoLL(pred)) {
4545 return gen_Proj_l_FloattoLL(node);
4547 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4551 ir_mode *mode = get_irn_mode(node);
4552 if (ia32_mode_needs_gp_reg(mode)) {
4553 ir_node *new_pred = be_transform_node(pred);
4554 ir_node *block = be_transform_node(get_nodes_block(node));
4555 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4556 mode_Iu, get_Proj_proj(node));
4557 #ifdef DEBUG_libfirm
4558 new_proj->node_nr = node->node_nr;
4564 return be_duplicate_node(node);
4568 * Enters all transform functions into the generic pointer
4570 static void register_transformers(void)
4574 /* first clear the generic function pointer for all ops */
4575 clear_irp_opcodes_generic_func();
4577 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4578 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4616 /* transform ops from intrinsic lowering */
4628 GEN(ia32_l_LLtoFloat);
4629 GEN(ia32_l_FloattoLL);
4635 /* we should never see these nodes */
4650 /* handle generic backend nodes */
4659 op_Mulh = get_op_Mulh();
4668 * Pre-transform all unknown and noreg nodes.
4670 static void ia32_pretransform_node(void)
4672 ia32_code_gen_t *cg = env_cg;
4674 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4675 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4676 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4677 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4678 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4679 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4684 * Walker, checks if all ia32 nodes producing more than one result have their
4685 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4687 static void add_missing_keep_walker(ir_node *node, void *data)
4690 unsigned found_projs = 0;
4691 const ir_edge_t *edge;
4692 ir_mode *mode = get_irn_mode(node);
4697 if (!is_ia32_irn(node))
4700 n_outs = arch_irn_get_n_outs(node);
4703 if (is_ia32_SwitchJmp(node))
4706 assert(n_outs < (int) sizeof(unsigned) * 8);
4707 foreach_out_edge(node, edge) {
4708 ir_node *proj = get_edge_src_irn(edge);
4711 /* The node could be kept */
4715 if (get_irn_mode(proj) == mode_M)
4718 pn = get_Proj_proj(proj);
4719 assert(pn < n_outs);
4720 found_projs |= 1 << pn;
4724 /* are keeps missing? */
4726 for (i = 0; i < n_outs; ++i) {
4729 const arch_register_req_t *req;
4730 const arch_register_class_t *cls;
4732 if (found_projs & (1 << i)) {
4736 req = get_ia32_out_req(node, i);
4741 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4745 block = get_nodes_block(node);
4746 in[0] = new_r_Proj(current_ir_graph, block, node,
4747 arch_register_class_mode(cls), i);
4748 if (last_keep != NULL) {
4749 be_Keep_add_node(last_keep, cls, in[0]);
4751 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4752 if (sched_is_scheduled(node)) {
4753 sched_add_after(node, last_keep);
4760 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4763 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4765 ir_graph *irg = be_get_birg_irg(cg->birg);
4766 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4769 /* do the transformation */
4770 void ia32_transform_graph(ia32_code_gen_t *cg)
4774 register_transformers();
4776 initial_fpcw = NULL;
4778 BE_TIMER_PUSH(t_heights);
4779 heights = heights_new(cg->irg);
4780 BE_TIMER_POP(t_heights);
4781 ia32_calculate_non_address_mode_nodes(cg->birg);
4783 /* the transform phase is not safe for CSE (yet) because several nodes get
4784 * attributes set after their creation */
4785 cse_last = get_opt_cse();
4788 be_transform_graph(cg->birg, ia32_pretransform_node);
4790 set_opt_cse(cse_last);
4792 ia32_free_non_address_mode_nodes();
4793 heights_free(heights);
4797 void ia32_init_transform(void)
4799 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");