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,
1343 if (ia32_cg_config.use_short_sex_eax) {
1344 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1345 be_dep_on_frame(pval);
1346 return new_rd_ia32_Cltd(dbgi, irg, block, val, pval);
1348 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1349 return new_rd_ia32_Sar(dbgi, irg, block, val, imm31);
1354 * Generates an ia32 DivMod with additional infrastructure for the
1355 * register allocator if needed.
1357 static ir_node *create_Div(ir_node *node)
1359 ir_graph *irg = current_ir_graph;
1360 dbg_info *dbgi = get_irn_dbg_info(node);
1361 ir_node *block = get_nodes_block(node);
1362 ir_node *new_block = be_transform_node(block);
1369 ir_node *sign_extension;
1370 ia32_address_mode_t am;
1371 ia32_address_t *addr = &am.addr;
1373 /* the upper bits have random contents for smaller modes */
1374 switch (get_irn_opcode(node)) {
1376 op1 = get_Div_left(node);
1377 op2 = get_Div_right(node);
1378 mem = get_Div_mem(node);
1379 mode = get_Div_resmode(node);
1382 op1 = get_Mod_left(node);
1383 op2 = get_Mod_right(node);
1384 mem = get_Mod_mem(node);
1385 mode = get_Mod_resmode(node);
1388 op1 = get_DivMod_left(node);
1389 op2 = get_DivMod_right(node);
1390 mem = get_DivMod_mem(node);
1391 mode = get_DivMod_resmode(node);
1394 panic("invalid divmod node %+F", node);
1397 match_arguments(&am, block, op1, op2, NULL, match_am);
1399 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1400 is the memory of the consumed address. We can have only the second op as address
1401 in Div nodes, so check only op2. */
1402 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1404 if (mode_is_signed(mode)) {
1405 sign_extension = create_sex_32_64(dbgi, irg, new_block, am.new_op1);
1406 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1407 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1409 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1410 be_dep_on_frame(sign_extension);
1412 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1413 addr->index, new_mem, am.new_op2,
1414 am.new_op1, sign_extension);
1417 set_irn_pinned(new_node, get_irn_pinned(node));
1419 set_am_attributes(new_node, &am);
1420 SET_IA32_ORIG_NODE(new_node, node);
1422 new_node = fix_mem_proj(new_node, &am);
1428 static ir_node *gen_Mod(ir_node *node)
1430 return create_Div(node);
1433 static ir_node *gen_Div(ir_node *node)
1435 return create_Div(node);
1438 static ir_node *gen_DivMod(ir_node *node)
1440 return create_Div(node);
1446 * Creates an ia32 floating Div.
1448 * @return The created ia32 xDiv node
1450 static ir_node *gen_Quot(ir_node *node)
1452 ir_node *op1 = get_Quot_left(node);
1453 ir_node *op2 = get_Quot_right(node);
1455 if (ia32_cg_config.use_sse2) {
1456 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1458 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv);
1464 * Creates an ia32 Shl.
1466 * @return The created ia32 Shl node
1468 static ir_node *gen_Shl(ir_node *node)
1470 ir_node *left = get_Shl_left(node);
1471 ir_node *right = get_Shl_right(node);
1473 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1474 match_mode_neutral | match_immediate);
1478 * Creates an ia32 Shr.
1480 * @return The created ia32 Shr node
1482 static ir_node *gen_Shr(ir_node *node)
1484 ir_node *left = get_Shr_left(node);
1485 ir_node *right = get_Shr_right(node);
1487 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1493 * Creates an ia32 Sar.
1495 * @return The created ia32 Shrs node
1497 static ir_node *gen_Shrs(ir_node *node)
1499 ir_node *left = get_Shrs_left(node);
1500 ir_node *right = get_Shrs_right(node);
1501 ir_mode *mode = get_irn_mode(node);
1503 if (is_Const(right) && mode == mode_Is) {
1504 tarval *tv = get_Const_tarval(right);
1505 long val = get_tarval_long(tv);
1507 /* this is a sign extension */
1508 dbg_info *dbgi = get_irn_dbg_info(node);
1509 ir_node *block = be_transform_node(get_nodes_block(node));
1510 ir_node *new_op = be_transform_node(left);
1512 return create_sex_32_64(dbgi, current_ir_graph, block, new_op);
1516 /* 8 or 16 bit sign extension? */
1517 if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1518 ir_node *shl_left = get_Shl_left(left);
1519 ir_node *shl_right = get_Shl_right(left);
1520 if (is_Const(shl_right)) {
1521 tarval *tv1 = get_Const_tarval(right);
1522 tarval *tv2 = get_Const_tarval(shl_right);
1523 if (tv1 == tv2 && tarval_is_long(tv1)) {
1524 long val = get_tarval_long(tv1);
1525 if (val == 16 || val == 24) {
1526 dbg_info *dbgi = get_irn_dbg_info(node);
1527 ir_node *block = get_nodes_block(node);
1537 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1546 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1552 * Creates an ia32 Rol.
1554 * @param op1 The first operator
1555 * @param op2 The second operator
1556 * @return The created ia32 RotL node
1558 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1560 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1566 * Creates an ia32 Ror.
1567 * NOTE: There is no RotR with immediate because this would always be a RotL
1568 * "imm-mode_size_bits" which can be pre-calculated.
1570 * @param op1 The first operator
1571 * @param op2 The second operator
1572 * @return The created ia32 RotR node
1574 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1576 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1582 * Creates an ia32 RotR or RotL (depending on the found pattern).
1584 * @return The created ia32 RotL or RotR node
1586 static ir_node *gen_Rotl(ir_node *node)
1588 ir_node *rotate = NULL;
1589 ir_node *op1 = get_Rotl_left(node);
1590 ir_node *op2 = get_Rotl_right(node);
1592 /* Firm has only RotL, so we are looking for a right (op2)
1593 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1594 that means we can create a RotR instead of an Add and a RotL */
1598 ir_node *left = get_Add_left(add);
1599 ir_node *right = get_Add_right(add);
1600 if (is_Const(right)) {
1601 tarval *tv = get_Const_tarval(right);
1602 ir_mode *mode = get_irn_mode(node);
1603 long bits = get_mode_size_bits(mode);
1605 if (is_Minus(left) &&
1606 tarval_is_long(tv) &&
1607 get_tarval_long(tv) == bits &&
1610 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1611 rotate = gen_Ror(node, op1, get_Minus_op(left));
1616 if (rotate == NULL) {
1617 rotate = gen_Rol(node, op1, op2);
1626 * Transforms a Minus node.
1628 * @return The created ia32 Minus node
1630 static ir_node *gen_Minus(ir_node *node)
1632 ir_node *op = get_Minus_op(node);
1633 ir_node *block = be_transform_node(get_nodes_block(node));
1634 ir_graph *irg = current_ir_graph;
1635 dbg_info *dbgi = get_irn_dbg_info(node);
1636 ir_mode *mode = get_irn_mode(node);
1641 if (mode_is_float(mode)) {
1642 ir_node *new_op = be_transform_node(op);
1643 if (ia32_cg_config.use_sse2) {
1644 /* TODO: non-optimal... if we have many xXors, then we should
1645 * rather create a load for the const and use that instead of
1646 * several AM nodes... */
1647 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1648 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1649 ir_node *nomem = new_rd_NoMem(irg);
1651 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1652 nomem, new_op, noreg_xmm);
1654 size = get_mode_size_bits(mode);
1655 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1657 set_ia32_am_sc(new_node, ent);
1658 set_ia32_op_type(new_node, ia32_AddrModeS);
1659 set_ia32_ls_mode(new_node, mode);
1661 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1664 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1667 SET_IA32_ORIG_NODE(new_node, node);
1673 * Transforms a Not node.
1675 * @return The created ia32 Not node
1677 static ir_node *gen_Not(ir_node *node)
1679 ir_node *op = get_Not_op(node);
1681 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1682 assert (! mode_is_float(get_irn_mode(node)));
1684 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1690 * Transforms an Abs node.
1692 * @return The created ia32 Abs node
1694 static ir_node *gen_Abs(ir_node *node)
1696 ir_node *block = get_nodes_block(node);
1697 ir_node *new_block = be_transform_node(block);
1698 ir_node *op = get_Abs_op(node);
1699 ir_graph *irg = current_ir_graph;
1700 dbg_info *dbgi = get_irn_dbg_info(node);
1701 ir_mode *mode = get_irn_mode(node);
1702 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1703 ir_node *nomem = new_NoMem();
1709 if (mode_is_float(mode)) {
1710 new_op = be_transform_node(op);
1712 if (ia32_cg_config.use_sse2) {
1713 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1714 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1715 nomem, new_op, noreg_fp);
1717 size = get_mode_size_bits(mode);
1718 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1720 set_ia32_am_sc(new_node, ent);
1722 SET_IA32_ORIG_NODE(new_node, node);
1724 set_ia32_op_type(new_node, ia32_AddrModeS);
1725 set_ia32_ls_mode(new_node, mode);
1727 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1728 SET_IA32_ORIG_NODE(new_node, node);
1731 ir_node *xor, *sign_extension;
1733 if (get_mode_size_bits(mode) == 32) {
1734 new_op = be_transform_node(op);
1736 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1739 sign_extension = create_sex_32_64(dbgi, irg, new_op, new_op);
1740 SET_IA32_ORIG_NODE(sign_extension, node);
1742 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1743 nomem, new_op, sign_extension);
1744 SET_IA32_ORIG_NODE(xor, node);
1746 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1747 nomem, xor, sign_extension);
1748 SET_IA32_ORIG_NODE(new_node, node);
1755 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1757 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1759 dbg_info *dbgi = get_irn_dbg_info(cmp);
1760 ir_node *block = get_nodes_block(cmp);
1761 ir_node *new_block = be_transform_node(block);
1762 ir_node *op1 = be_transform_node(x);
1763 ir_node *op2 = be_transform_node(n);
1765 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1769 * Transform a node returning a "flag" result.
1771 * @param node the node to transform
1772 * @param pnc_out the compare mode to use
1774 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1783 /* we have a Cmp as input */
1784 if (is_Proj(node)) {
1785 ir_node *pred = get_Proj_pred(node);
1787 pn_Cmp pnc = get_Proj_proj(node);
1788 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1789 ir_node *l = get_Cmp_left(pred);
1790 ir_node *r = get_Cmp_right(pred);
1792 ir_node *la = get_And_left(l);
1793 ir_node *ra = get_And_right(l);
1795 ir_node *c = get_Shl_left(la);
1796 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1797 /* (1 << n) & ra) */
1798 ir_node *n = get_Shl_right(la);
1799 flags = gen_bt(pred, ra, n);
1800 /* we must generate a Jc/Jnc jump */
1801 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1804 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1809 ir_node *c = get_Shl_left(ra);
1810 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1811 /* la & (1 << n)) */
1812 ir_node *n = get_Shl_right(ra);
1813 flags = gen_bt(pred, la, n);
1814 /* we must generate a Jc/Jnc jump */
1815 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1818 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1824 flags = be_transform_node(pred);
1830 /* a mode_b value, we have to compare it against 0 */
1831 dbgi = get_irn_dbg_info(node);
1832 new_block = be_transform_node(get_nodes_block(node));
1833 new_op = be_transform_node(node);
1834 noreg = ia32_new_NoReg_gp(env_cg);
1835 nomem = new_NoMem();
1836 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1837 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1838 *pnc_out = pn_Cmp_Lg;
1843 * Transforms a Load.
1845 * @return the created ia32 Load node
1847 static ir_node *gen_Load(ir_node *node)
1849 ir_node *old_block = get_nodes_block(node);
1850 ir_node *block = be_transform_node(old_block);
1851 ir_node *ptr = get_Load_ptr(node);
1852 ir_node *mem = get_Load_mem(node);
1853 ir_node *new_mem = be_transform_node(mem);
1856 ir_graph *irg = current_ir_graph;
1857 dbg_info *dbgi = get_irn_dbg_info(node);
1858 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1859 ir_mode *mode = get_Load_mode(node);
1862 ia32_address_t addr;
1864 /* construct load address */
1865 memset(&addr, 0, sizeof(addr));
1866 ia32_create_address_mode(&addr, ptr, 0);
1873 base = be_transform_node(base);
1876 if (index == NULL) {
1879 index = be_transform_node(index);
1882 if (mode_is_float(mode)) {
1883 if (ia32_cg_config.use_sse2) {
1884 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1886 res_mode = mode_xmm;
1888 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1890 res_mode = mode_vfp;
1893 assert(mode != mode_b);
1895 /* create a conv node with address mode for smaller modes */
1896 if (get_mode_size_bits(mode) < 32) {
1897 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1898 new_mem, noreg, mode);
1900 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1905 set_irn_pinned(new_node, get_irn_pinned(node));
1906 set_ia32_op_type(new_node, ia32_AddrModeS);
1907 set_ia32_ls_mode(new_node, mode);
1908 set_address(new_node, &addr);
1910 if (get_irn_pinned(node) == op_pin_state_floats) {
1911 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1912 && pn_ia32_vfld_res == pn_ia32_Load_res
1913 && pn_ia32_Load_res == pn_ia32_res);
1914 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1917 SET_IA32_ORIG_NODE(new_node, node);
1919 be_dep_on_frame(new_node);
1923 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1924 ir_node *ptr, ir_node *other)
1931 /* we only use address mode if we're the only user of the load */
1932 if (get_irn_n_edges(node) > 1)
1935 load = get_Proj_pred(node);
1938 if (get_nodes_block(load) != block)
1941 /* store should have the same pointer as the load */
1942 if (get_Load_ptr(load) != ptr)
1945 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1946 if (other != NULL &&
1947 get_nodes_block(other) == block &&
1948 heights_reachable_in_block(heights, other, load)) {
1952 if (prevents_AM(block, load, mem))
1954 /* Store should be attached to the load via mem */
1955 assert(heights_reachable_in_block(heights, mem, load));
1960 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1961 ir_node *mem, ir_node *ptr, ir_mode *mode,
1962 construct_binop_dest_func *func,
1963 construct_binop_dest_func *func8bit,
1964 match_flags_t flags)
1966 ir_node *src_block = get_nodes_block(node);
1968 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1969 ir_graph *irg = current_ir_graph;
1976 ia32_address_mode_t am;
1977 ia32_address_t *addr = &am.addr;
1978 memset(&am, 0, sizeof(am));
1980 assert(flags & match_dest_am);
1981 assert(flags & match_immediate); /* there is no destam node without... */
1982 commutative = (flags & match_commutative) != 0;
1984 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1985 build_address(&am, op1, ia32_create_am_double_use);
1986 new_op = create_immediate_or_transform(op2, 0);
1987 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1988 build_address(&am, op2, ia32_create_am_double_use);
1989 new_op = create_immediate_or_transform(op1, 0);
1994 if (addr->base == NULL)
1995 addr->base = noreg_gp;
1996 if (addr->index == NULL)
1997 addr->index = noreg_gp;
1998 if (addr->mem == NULL)
1999 addr->mem = new_NoMem();
2001 dbgi = get_irn_dbg_info(node);
2002 block = be_transform_node(src_block);
2003 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2005 if (get_mode_size_bits(mode) == 8) {
2006 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2009 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
2012 set_address(new_node, addr);
2013 set_ia32_op_type(new_node, ia32_AddrModeD);
2014 set_ia32_ls_mode(new_node, mode);
2015 SET_IA32_ORIG_NODE(new_node, node);
2017 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2018 mem_proj = be_transform_node(am.mem_proj);
2019 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2024 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2025 ir_node *ptr, ir_mode *mode,
2026 construct_unop_dest_func *func)
2028 ir_graph *irg = current_ir_graph;
2029 ir_node *src_block = get_nodes_block(node);
2035 ia32_address_mode_t am;
2036 ia32_address_t *addr = &am.addr;
2038 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2041 memset(&am, 0, sizeof(am));
2042 build_address(&am, op, ia32_create_am_double_use);
2044 dbgi = get_irn_dbg_info(node);
2045 block = be_transform_node(src_block);
2046 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2047 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2048 set_address(new_node, addr);
2049 set_ia32_op_type(new_node, ia32_AddrModeD);
2050 set_ia32_ls_mode(new_node, mode);
2051 SET_IA32_ORIG_NODE(new_node, node);
2053 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2054 mem_proj = be_transform_node(am.mem_proj);
2055 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2060 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2062 ir_mode *mode = get_irn_mode(node);
2063 ir_node *mux_true = get_Mux_true(node);
2064 ir_node *mux_false = get_Mux_false(node);
2075 ia32_address_t addr;
2077 if (get_mode_size_bits(mode) != 8)
2080 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2082 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2088 build_address_ptr(&addr, ptr, mem);
2090 irg = current_ir_graph;
2091 dbgi = get_irn_dbg_info(node);
2092 block = get_nodes_block(node);
2093 new_block = be_transform_node(block);
2094 cond = get_Mux_sel(node);
2095 flags = get_flags_node(cond, &pnc);
2096 new_mem = be_transform_node(mem);
2097 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2098 addr.index, addr.mem, flags, pnc, negated);
2099 set_address(new_node, &addr);
2100 set_ia32_op_type(new_node, ia32_AddrModeD);
2101 set_ia32_ls_mode(new_node, mode);
2102 SET_IA32_ORIG_NODE(new_node, node);
2107 static ir_node *try_create_dest_am(ir_node *node)
2109 ir_node *val = get_Store_value(node);
2110 ir_node *mem = get_Store_mem(node);
2111 ir_node *ptr = get_Store_ptr(node);
2112 ir_mode *mode = get_irn_mode(val);
2113 unsigned bits = get_mode_size_bits(mode);
2118 /* handle only GP modes for now... */
2119 if (!ia32_mode_needs_gp_reg(mode))
2123 /* store must be the only user of the val node */
2124 if (get_irn_n_edges(val) > 1)
2126 /* skip pointless convs */
2128 ir_node *conv_op = get_Conv_op(val);
2129 ir_mode *pred_mode = get_irn_mode(conv_op);
2130 if (!ia32_mode_needs_gp_reg(pred_mode))
2132 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2140 /* value must be in the same block */
2141 if (get_nodes_block(node) != get_nodes_block(val))
2144 switch (get_irn_opcode(val)) {
2146 op1 = get_Add_left(val);
2147 op2 = get_Add_right(val);
2148 if (ia32_cg_config.use_incdec) {
2149 if (is_Const_1(op2)) {
2150 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_IncMem);
2152 } else if (is_Const_Minus_1(op2)) {
2153 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_DecMem);
2157 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2158 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2159 match_dest_am | match_commutative |
2163 op1 = get_Sub_left(val);
2164 op2 = get_Sub_right(val);
2165 if (is_Const(op2)) {
2166 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2168 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2169 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2170 match_dest_am | match_immediate);
2173 op1 = get_And_left(val);
2174 op2 = get_And_right(val);
2175 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2176 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2177 match_dest_am | match_commutative |
2181 op1 = get_Or_left(val);
2182 op2 = get_Or_right(val);
2183 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2184 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2185 match_dest_am | match_commutative |
2189 op1 = get_Eor_left(val);
2190 op2 = get_Eor_right(val);
2191 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2192 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2193 match_dest_am | match_commutative |
2197 op1 = get_Shl_left(val);
2198 op2 = get_Shl_right(val);
2199 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2200 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2201 match_dest_am | match_immediate);
2204 op1 = get_Shr_left(val);
2205 op2 = get_Shr_right(val);
2206 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2207 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2208 match_dest_am | match_immediate);
2211 op1 = get_Shrs_left(val);
2212 op2 = get_Shrs_right(val);
2213 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2214 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2215 match_dest_am | match_immediate);
2218 op1 = get_Rotl_left(val);
2219 op2 = get_Rotl_right(val);
2220 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2221 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2222 match_dest_am | match_immediate);
2224 /* TODO: match ROR patterns... */
2226 new_node = try_create_SetMem(val, ptr, mem);
2229 op1 = get_Minus_op(val);
2230 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2233 /* should be lowered already */
2234 assert(mode != mode_b);
2235 op1 = get_Not_op(val);
2236 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2242 if (new_node != NULL) {
2243 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2244 get_irn_pinned(node) == op_pin_state_pinned) {
2245 set_irn_pinned(new_node, op_pin_state_pinned);
2252 static int is_float_to_int_conv(const ir_node *node)
2254 ir_mode *mode = get_irn_mode(node);
2258 if (mode != mode_Is && mode != mode_Hs)
2263 conv_op = get_Conv_op(node);
2264 conv_mode = get_irn_mode(conv_op);
2266 if (!mode_is_float(conv_mode))
2273 * Transform a Store(floatConst) into a sequence of
2276 * @return the created ia32 Store node
2278 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2280 ir_mode *mode = get_irn_mode(cns);
2281 unsigned size = get_mode_size_bytes(mode);
2282 tarval *tv = get_Const_tarval(cns);
2283 ir_node *block = get_nodes_block(node);
2284 ir_node *new_block = be_transform_node(block);
2285 ir_node *ptr = get_Store_ptr(node);
2286 ir_node *mem = get_Store_mem(node);
2287 ir_graph *irg = current_ir_graph;
2288 dbg_info *dbgi = get_irn_dbg_info(node);
2292 ia32_address_t addr;
2294 assert(size % 4 == 0);
2297 build_address_ptr(&addr, ptr, mem);
2301 get_tarval_sub_bits(tv, ofs) |
2302 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2303 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2304 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2305 ir_node *imm = create_Immediate(NULL, 0, val);
2307 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2308 addr.index, addr.mem, imm);
2310 set_irn_pinned(new_node, get_irn_pinned(node));
2311 set_ia32_op_type(new_node, ia32_AddrModeD);
2312 set_ia32_ls_mode(new_node, mode_Iu);
2313 set_address(new_node, &addr);
2314 SET_IA32_ORIG_NODE(new_node, node);
2317 ins[i++] = new_node;
2322 } while (size != 0);
2325 return new_rd_Sync(dbgi, irg, new_block, i, ins);
2332 * Generate a vfist or vfisttp instruction.
2334 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2335 ir_node *mem, ir_node *val, ir_node **fist)
2339 if (ia32_cg_config.use_fisttp) {
2340 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2341 if other users exists */
2342 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2343 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2344 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2345 be_new_Keep(reg_class, irg, block, 1, &value);
2347 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2350 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2353 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2359 * Transforms a general (no special case) Store.
2361 * @return the created ia32 Store node
2363 static ir_node *gen_general_Store(ir_node *node)
2365 ir_node *val = get_Store_value(node);
2366 ir_mode *mode = get_irn_mode(val);
2367 ir_node *block = get_nodes_block(node);
2368 ir_node *new_block = be_transform_node(block);
2369 ir_node *ptr = get_Store_ptr(node);
2370 ir_node *mem = get_Store_mem(node);
2371 ir_graph *irg = current_ir_graph;
2372 dbg_info *dbgi = get_irn_dbg_info(node);
2373 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2374 ir_node *new_val, *new_node, *store;
2375 ia32_address_t addr;
2377 /* check for destination address mode */
2378 new_node = try_create_dest_am(node);
2379 if (new_node != NULL)
2382 /* construct store address */
2383 memset(&addr, 0, sizeof(addr));
2384 ia32_create_address_mode(&addr, ptr, 0);
2386 if (addr.base == NULL) {
2389 addr.base = be_transform_node(addr.base);
2392 if (addr.index == NULL) {
2395 addr.index = be_transform_node(addr.index);
2397 addr.mem = be_transform_node(mem);
2399 if (mode_is_float(mode)) {
2400 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2402 while (is_Conv(val) && mode == get_irn_mode(val)) {
2403 ir_node *op = get_Conv_op(val);
2404 if (!mode_is_float(get_irn_mode(op)))
2408 new_val = be_transform_node(val);
2409 if (ia32_cg_config.use_sse2) {
2410 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2411 addr.index, addr.mem, new_val);
2413 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2414 addr.index, addr.mem, new_val, mode);
2417 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2418 val = get_Conv_op(val);
2420 /* TODO: is this optimisation still necessary at all (middleend)? */
2421 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2422 while (is_Conv(val)) {
2423 ir_node *op = get_Conv_op(val);
2424 if (!mode_is_float(get_irn_mode(op)))
2426 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2430 new_val = be_transform_node(val);
2431 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2433 new_val = create_immediate_or_transform(val, 0);
2434 assert(mode != mode_b);
2436 if (get_mode_size_bits(mode) == 8) {
2437 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2438 addr.index, addr.mem, new_val);
2440 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2441 addr.index, addr.mem, new_val);
2446 set_irn_pinned(store, get_irn_pinned(node));
2447 set_ia32_op_type(store, ia32_AddrModeD);
2448 set_ia32_ls_mode(store, mode);
2450 set_address(store, &addr);
2451 SET_IA32_ORIG_NODE(store, node);
2457 * Transforms a Store.
2459 * @return the created ia32 Store node
2461 static ir_node *gen_Store(ir_node *node)
2463 ir_node *val = get_Store_value(node);
2464 ir_mode *mode = get_irn_mode(val);
2466 if (mode_is_float(mode) && is_Const(val)) {
2467 /* We can transform every floating const store
2468 into a sequence of integer stores.
2469 If the constant is already in a register,
2470 it would be better to use it, but we don't
2471 have this information here. */
2472 return gen_float_const_Store(node, val);
2474 return gen_general_Store(node);
2478 * Transforms a Switch.
2480 * @return the created ia32 SwitchJmp node
2482 static ir_node *create_Switch(ir_node *node)
2484 ir_graph *irg = current_ir_graph;
2485 dbg_info *dbgi = get_irn_dbg_info(node);
2486 ir_node *block = be_transform_node(get_nodes_block(node));
2487 ir_node *sel = get_Cond_selector(node);
2488 ir_node *new_sel = be_transform_node(sel);
2489 int switch_min = INT_MAX;
2490 int switch_max = INT_MIN;
2491 long default_pn = get_Cond_defaultProj(node);
2493 const ir_edge_t *edge;
2495 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2497 /* determine the smallest switch case value */
2498 foreach_out_edge(node, edge) {
2499 ir_node *proj = get_edge_src_irn(edge);
2500 long pn = get_Proj_proj(proj);
2501 if (pn == default_pn)
2504 if (pn < switch_min)
2506 if (pn > switch_max)
2510 if ((unsigned) (switch_max - switch_min) > 256000) {
2511 panic("Size of switch %+F bigger than 256000", node);
2514 if (switch_min != 0) {
2515 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2517 /* if smallest switch case is not 0 we need an additional sub */
2518 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2519 add_ia32_am_offs_int(new_sel, -switch_min);
2520 set_ia32_op_type(new_sel, ia32_AddrModeS);
2522 SET_IA32_ORIG_NODE(new_sel, node);
2525 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2526 SET_IA32_ORIG_NODE(new_node, node);
2532 * Transform a Cond node.
2534 static ir_node *gen_Cond(ir_node *node)
2536 ir_node *block = get_nodes_block(node);
2537 ir_node *new_block = be_transform_node(block);
2538 ir_graph *irg = current_ir_graph;
2539 dbg_info *dbgi = get_irn_dbg_info(node);
2540 ir_node *sel = get_Cond_selector(node);
2541 ir_mode *sel_mode = get_irn_mode(sel);
2542 ir_node *flags = NULL;
2546 if (sel_mode != mode_b) {
2547 return create_Switch(node);
2550 /* we get flags from a Cmp */
2551 flags = get_flags_node(sel, &pnc);
2553 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2554 SET_IA32_ORIG_NODE(new_node, node);
2559 static ir_node *gen_be_Copy(ir_node *node)
2561 ir_node *new_node = be_duplicate_node(node);
2562 ir_mode *mode = get_irn_mode(new_node);
2564 if (ia32_mode_needs_gp_reg(mode)) {
2565 set_irn_mode(new_node, mode_Iu);
2571 static ir_node *create_Fucom(ir_node *node)
2573 ir_graph *irg = current_ir_graph;
2574 dbg_info *dbgi = get_irn_dbg_info(node);
2575 ir_node *block = get_nodes_block(node);
2576 ir_node *new_block = be_transform_node(block);
2577 ir_node *left = get_Cmp_left(node);
2578 ir_node *new_left = be_transform_node(left);
2579 ir_node *right = get_Cmp_right(node);
2583 if (ia32_cg_config.use_fucomi) {
2584 new_right = be_transform_node(right);
2585 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2587 set_ia32_commutative(new_node);
2588 SET_IA32_ORIG_NODE(new_node, node);
2590 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2591 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2594 new_right = be_transform_node(right);
2595 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2599 set_ia32_commutative(new_node);
2601 SET_IA32_ORIG_NODE(new_node, node);
2603 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2604 SET_IA32_ORIG_NODE(new_node, node);
2610 static ir_node *create_Ucomi(ir_node *node)
2612 ir_graph *irg = current_ir_graph;
2613 dbg_info *dbgi = get_irn_dbg_info(node);
2614 ir_node *src_block = get_nodes_block(node);
2615 ir_node *new_block = be_transform_node(src_block);
2616 ir_node *left = get_Cmp_left(node);
2617 ir_node *right = get_Cmp_right(node);
2619 ia32_address_mode_t am;
2620 ia32_address_t *addr = &am.addr;
2622 match_arguments(&am, src_block, left, right, NULL,
2623 match_commutative | match_am);
2625 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2626 addr->mem, am.new_op1, am.new_op2,
2628 set_am_attributes(new_node, &am);
2630 SET_IA32_ORIG_NODE(new_node, node);
2632 new_node = fix_mem_proj(new_node, &am);
2638 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2639 * to fold an and into a test node
2641 static bool can_fold_test_and(ir_node *node)
2643 const ir_edge_t *edge;
2645 /** we can only have eq and lg projs */
2646 foreach_out_edge(node, edge) {
2647 ir_node *proj = get_edge_src_irn(edge);
2648 pn_Cmp pnc = get_Proj_proj(proj);
2649 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2657 * returns true if it is assured, that the upper bits of a node are "clean"
2658 * which means for a 16 or 8 bit value, that the upper bits in the register
2659 * are 0 for unsigned and a copy of the last significant bit for signed
2662 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2664 assert(ia32_mode_needs_gp_reg(mode));
2665 if (get_mode_size_bits(mode) >= 32)
2668 if (is_Proj(transformed_node))
2669 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2671 if (is_ia32_Conv_I2I(transformed_node)
2672 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2673 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2674 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2676 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2682 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2683 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2684 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2685 const ia32_immediate_attr_t *attr
2686 = get_ia32_immediate_attr_const(right);
2687 if (attr->symconst == 0
2688 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2692 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2695 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2696 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2697 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2698 const ia32_immediate_attr_t *attr
2699 = get_ia32_immediate_attr_const(right);
2700 if (attr->symconst == 0
2701 && (unsigned) attr->offset
2702 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2709 /* TODO recurse on Or, Xor, ... if appropriate? */
2711 if (is_ia32_Immediate(transformed_node)
2712 || is_ia32_Const(transformed_node)) {
2713 const ia32_immediate_attr_t *attr
2714 = get_ia32_immediate_attr_const(transformed_node);
2715 if (mode_is_signed(mode)) {
2716 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2717 if (shifted == 0 || shifted == -1)
2720 unsigned long shifted = (unsigned long) attr->offset;
2721 shifted >>= get_mode_size_bits(mode);
2731 * Generate code for a Cmp.
2733 static ir_node *gen_Cmp(ir_node *node)
2735 ir_graph *irg = current_ir_graph;
2736 dbg_info *dbgi = get_irn_dbg_info(node);
2737 ir_node *block = get_nodes_block(node);
2738 ir_node *new_block = be_transform_node(block);
2739 ir_node *left = get_Cmp_left(node);
2740 ir_node *right = get_Cmp_right(node);
2741 ir_mode *cmp_mode = get_irn_mode(left);
2743 ia32_address_mode_t am;
2744 ia32_address_t *addr = &am.addr;
2747 if (mode_is_float(cmp_mode)) {
2748 if (ia32_cg_config.use_sse2) {
2749 return create_Ucomi(node);
2751 return create_Fucom(node);
2755 assert(ia32_mode_needs_gp_reg(cmp_mode));
2757 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2758 cmp_unsigned = !mode_is_signed(cmp_mode);
2759 if (is_Const_0(right) &&
2761 get_irn_n_edges(left) == 1 &&
2762 can_fold_test_and(node)) {
2763 /* Test(and_left, and_right) */
2764 ir_node *and_left = get_And_left(left);
2765 ir_node *and_right = get_And_right(left);
2767 /* matze: code here used mode instead of cmd_mode, I think it is always
2768 * the same as cmp_mode, but I leave this here to see if this is really
2771 assert(get_irn_mode(and_left) == cmp_mode);
2773 match_arguments(&am, block, and_left, and_right, NULL,
2775 match_am | match_8bit_am | match_16bit_am |
2776 match_am_and_immediates | match_immediate |
2777 match_8bit | match_16bit);
2779 /* use 32bit compare mode if possible since the opcode is smaller */
2780 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2781 upper_bits_clean(am.new_op2, cmp_mode)) {
2782 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2785 if (get_mode_size_bits(cmp_mode) == 8) {
2786 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2787 addr->index, addr->mem, am.new_op1,
2788 am.new_op2, am.ins_permuted,
2791 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2792 addr->index, addr->mem, am.new_op1,
2793 am.new_op2, am.ins_permuted,
2797 /* Cmp(left, right) */
2798 match_arguments(&am, block, left, right, NULL,
2799 match_commutative | match_am | match_8bit_am |
2800 match_16bit_am | match_am_and_immediates |
2801 match_immediate | match_8bit | match_16bit);
2802 /* use 32bit compare mode if possible since the opcode is smaller */
2803 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2804 upper_bits_clean(am.new_op2, cmp_mode)) {
2805 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2808 if (get_mode_size_bits(cmp_mode) == 8) {
2809 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2810 addr->index, addr->mem, am.new_op1,
2811 am.new_op2, am.ins_permuted,
2814 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2815 addr->index, addr->mem, am.new_op1,
2816 am.new_op2, am.ins_permuted, cmp_unsigned);
2819 set_am_attributes(new_node, &am);
2820 set_ia32_ls_mode(new_node, cmp_mode);
2822 SET_IA32_ORIG_NODE(new_node, node);
2824 new_node = fix_mem_proj(new_node, &am);
2829 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2832 ir_graph *irg = current_ir_graph;
2833 dbg_info *dbgi = get_irn_dbg_info(node);
2834 ir_node *block = get_nodes_block(node);
2835 ir_node *new_block = be_transform_node(block);
2836 ir_node *val_true = get_Mux_true(node);
2837 ir_node *val_false = get_Mux_false(node);
2839 match_flags_t match_flags;
2840 ia32_address_mode_t am;
2841 ia32_address_t *addr;
2843 assert(ia32_cg_config.use_cmov);
2844 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2848 match_flags = match_commutative | match_am | match_16bit_am |
2851 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2853 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2854 addr->mem, am.new_op1, am.new_op2, new_flags,
2855 am.ins_permuted, pnc);
2856 set_am_attributes(new_node, &am);
2858 SET_IA32_ORIG_NODE(new_node, node);
2860 new_node = fix_mem_proj(new_node, &am);
2866 * Creates a ia32 Setcc instruction.
2868 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2869 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2872 ir_graph *irg = current_ir_graph;
2873 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2874 ir_node *nomem = new_NoMem();
2875 ir_mode *mode = get_irn_mode(orig_node);
2878 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2879 SET_IA32_ORIG_NODE(new_node, orig_node);
2881 /* we might need to conv the result up */
2882 if (get_mode_size_bits(mode) > 8) {
2883 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2884 nomem, new_node, mode_Bu);
2885 SET_IA32_ORIG_NODE(new_node, orig_node);
2892 * Create instruction for an unsigned Difference or Zero.
2894 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2896 ir_graph *irg = current_ir_graph;
2897 ir_mode *mode = get_irn_mode(psi);
2898 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2901 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2902 match_mode_neutral | match_am | match_immediate | match_two_users);
2904 block = get_nodes_block(new_node);
2906 if (is_Proj(new_node)) {
2907 sub = get_Proj_pred(new_node);
2908 assert(is_ia32_Sub(sub));
2911 set_irn_mode(sub, mode_T);
2912 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2914 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2916 dbgi = get_irn_dbg_info(psi);
2917 noreg = ia32_new_NoReg_gp(env_cg);
2918 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2919 nomem = new_NoMem();
2920 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2922 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2923 set_ia32_commutative(new_node);
2928 * Transforms a Mux node into CMov.
2930 * @return The transformed node.
2932 static ir_node *gen_Mux(ir_node *node)
2934 dbg_info *dbgi = get_irn_dbg_info(node);
2935 ir_node *block = get_nodes_block(node);
2936 ir_node *new_block = be_transform_node(block);
2937 ir_node *mux_true = get_Mux_true(node);
2938 ir_node *mux_false = get_Mux_false(node);
2939 ir_node *cond = get_Mux_sel(node);
2940 ir_mode *mode = get_irn_mode(node);
2943 assert(get_irn_mode(cond) == mode_b);
2945 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2946 if (mode_is_float(mode)) {
2947 ir_node *cmp = get_Proj_pred(cond);
2948 ir_node *cmp_left = get_Cmp_left(cmp);
2949 ir_node *cmp_right = get_Cmp_right(cmp);
2950 pn_Cmp pnc = get_Proj_proj(cond);
2952 if (ia32_cg_config.use_sse2) {
2953 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2954 if (cmp_left == mux_true && cmp_right == mux_false) {
2955 /* Mux(a <= b, a, b) => MIN */
2956 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2957 match_commutative | match_am | match_two_users);
2958 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2959 /* Mux(a <= b, b, a) => MAX */
2960 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2961 match_commutative | match_am | match_two_users);
2963 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2964 if (cmp_left == mux_true && cmp_right == mux_false) {
2965 /* Mux(a >= b, a, b) => MAX */
2966 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2967 match_commutative | match_am | match_two_users);
2968 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2969 /* Mux(a >= b, b, a) => MIN */
2970 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2971 match_commutative | match_am | match_two_users);
2975 panic("cannot transform floating point Mux");
2981 assert(ia32_mode_needs_gp_reg(mode));
2983 if (is_Proj(cond)) {
2984 ir_node *cmp = get_Proj_pred(cond);
2986 ir_node *cmp_left = get_Cmp_left(cmp);
2987 ir_node *cmp_right = get_Cmp_right(cmp);
2988 pn_Cmp pnc = get_Proj_proj(cond);
2990 /* check for unsigned Doz first */
2991 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2992 is_Const_0(mux_false) && is_Sub(mux_true) &&
2993 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2994 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2995 return create_Doz(node, cmp_left, cmp_right);
2996 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2997 is_Const_0(mux_true) && is_Sub(mux_false) &&
2998 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2999 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3000 return create_Doz(node, cmp_left, cmp_right);
3005 flags = get_flags_node(cond, &pnc);
3007 if (is_Const(mux_true) && is_Const(mux_false)) {
3008 /* both are const, good */
3009 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3010 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3011 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3012 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3014 /* Not that simple. */
3019 new_node = create_CMov(node, cond, flags, pnc);
3027 * Create a conversion from x87 state register to general purpose.
3029 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3031 ir_node *block = be_transform_node(get_nodes_block(node));
3032 ir_node *op = get_Conv_op(node);
3033 ir_node *new_op = be_transform_node(op);
3034 ia32_code_gen_t *cg = env_cg;
3035 ir_graph *irg = current_ir_graph;
3036 dbg_info *dbgi = get_irn_dbg_info(node);
3037 ir_node *noreg = ia32_new_NoReg_gp(cg);
3038 ir_mode *mode = get_irn_mode(node);
3039 ir_node *fist, *load, *mem;
3041 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3042 set_irn_pinned(fist, op_pin_state_floats);
3043 set_ia32_use_frame(fist);
3044 set_ia32_op_type(fist, ia32_AddrModeD);
3046 assert(get_mode_size_bits(mode) <= 32);
3047 /* exception we can only store signed 32 bit integers, so for unsigned
3048 we store a 64bit (signed) integer and load the lower bits */
3049 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3050 set_ia32_ls_mode(fist, mode_Ls);
3052 set_ia32_ls_mode(fist, mode_Is);
3054 SET_IA32_ORIG_NODE(fist, node);
3057 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3059 set_irn_pinned(load, op_pin_state_floats);
3060 set_ia32_use_frame(load);
3061 set_ia32_op_type(load, ia32_AddrModeS);
3062 set_ia32_ls_mode(load, mode_Is);
3063 if (get_ia32_ls_mode(fist) == mode_Ls) {
3064 ia32_attr_t *attr = get_ia32_attr(load);
3065 attr->data.need_64bit_stackent = 1;
3067 ia32_attr_t *attr = get_ia32_attr(load);
3068 attr->data.need_32bit_stackent = 1;
3070 SET_IA32_ORIG_NODE(load, node);
3072 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3076 * Creates a x87 strict Conv by placing a Store and a Load
3078 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3080 ir_node *block = get_nodes_block(node);
3081 ir_graph *irg = current_ir_graph;
3082 dbg_info *dbgi = get_irn_dbg_info(node);
3083 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3084 ir_node *nomem = new_NoMem();
3085 ir_node *frame = get_irg_frame(irg);
3086 ir_node *store, *load;
3089 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3091 set_ia32_use_frame(store);
3092 set_ia32_op_type(store, ia32_AddrModeD);
3093 SET_IA32_ORIG_NODE(store, node);
3095 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3097 set_ia32_use_frame(load);
3098 set_ia32_op_type(load, ia32_AddrModeS);
3099 SET_IA32_ORIG_NODE(load, node);
3101 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3106 * Create a conversion from general purpose to x87 register
3108 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3110 ir_node *src_block = get_nodes_block(node);
3111 ir_node *block = be_transform_node(src_block);
3112 ir_graph *irg = current_ir_graph;
3113 dbg_info *dbgi = get_irn_dbg_info(node);
3114 ir_node *op = get_Conv_op(node);
3115 ir_node *new_op = NULL;
3119 ir_mode *store_mode;
3125 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3126 if (src_mode == mode_Is || src_mode == mode_Hs) {
3127 ia32_address_mode_t am;
3129 match_arguments(&am, src_block, NULL, op, NULL,
3130 match_am | match_try_am | match_16bit | match_16bit_am);
3131 if (am.op_type == ia32_AddrModeS) {
3132 ia32_address_t *addr = &am.addr;
3134 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3135 addr->index, addr->mem);
3136 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3139 set_am_attributes(fild, &am);
3140 SET_IA32_ORIG_NODE(fild, node);
3142 fix_mem_proj(fild, &am);
3147 if (new_op == NULL) {
3148 new_op = be_transform_node(op);
3151 noreg = ia32_new_NoReg_gp(env_cg);
3152 nomem = new_NoMem();
3153 mode = get_irn_mode(op);
3155 /* first convert to 32 bit signed if necessary */
3156 src_bits = get_mode_size_bits(src_mode);
3157 if (src_bits == 8) {
3158 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3160 SET_IA32_ORIG_NODE(new_op, node);
3162 } else if (src_bits < 32) {
3163 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3165 SET_IA32_ORIG_NODE(new_op, node);
3169 assert(get_mode_size_bits(mode) == 32);
3172 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3175 set_ia32_use_frame(store);
3176 set_ia32_op_type(store, ia32_AddrModeD);
3177 set_ia32_ls_mode(store, mode_Iu);
3179 /* exception for 32bit unsigned, do a 64bit spill+load */
3180 if (!mode_is_signed(mode)) {
3183 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3185 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3186 get_irg_frame(irg), noreg, nomem,
3189 set_ia32_use_frame(zero_store);
3190 set_ia32_op_type(zero_store, ia32_AddrModeD);
3191 add_ia32_am_offs_int(zero_store, 4);
3192 set_ia32_ls_mode(zero_store, mode_Iu);
3197 store = new_rd_Sync(dbgi, irg, block, 2, in);
3198 store_mode = mode_Ls;
3200 store_mode = mode_Is;
3204 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3206 set_ia32_use_frame(fild);
3207 set_ia32_op_type(fild, ia32_AddrModeS);
3208 set_ia32_ls_mode(fild, store_mode);
3210 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3216 * Create a conversion from one integer mode into another one
3218 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3219 dbg_info *dbgi, ir_node *block, ir_node *op,
3222 ir_graph *irg = current_ir_graph;
3223 int src_bits = get_mode_size_bits(src_mode);
3224 int tgt_bits = get_mode_size_bits(tgt_mode);
3225 ir_node *new_block = be_transform_node(block);
3227 ir_mode *smaller_mode;
3229 ia32_address_mode_t am;
3230 ia32_address_t *addr = &am.addr;
3233 if (src_bits < tgt_bits) {
3234 smaller_mode = src_mode;
3235 smaller_bits = src_bits;
3237 smaller_mode = tgt_mode;
3238 smaller_bits = tgt_bits;
3241 #ifdef DEBUG_libfirm
3243 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3248 match_arguments(&am, block, NULL, op, NULL,
3249 match_8bit | match_16bit |
3250 match_am | match_8bit_am | match_16bit_am);
3252 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3253 /* unnecessary conv. in theory it shouldn't have been AM */
3254 assert(is_ia32_NoReg_GP(addr->base));
3255 assert(is_ia32_NoReg_GP(addr->index));
3256 assert(is_NoMem(addr->mem));
3257 assert(am.addr.offset == 0);
3258 assert(am.addr.symconst_ent == NULL);
3262 if (smaller_bits == 8) {
3263 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3264 addr->index, addr->mem, am.new_op2,
3267 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3268 addr->index, addr->mem, am.new_op2,
3271 set_am_attributes(new_node, &am);
3272 /* match_arguments assume that out-mode = in-mode, this isn't true here
3274 set_ia32_ls_mode(new_node, smaller_mode);
3275 SET_IA32_ORIG_NODE(new_node, node);
3276 new_node = fix_mem_proj(new_node, &am);
3281 * Transforms a Conv node.
3283 * @return The created ia32 Conv node
3285 static ir_node *gen_Conv(ir_node *node)
3287 ir_node *block = get_nodes_block(node);
3288 ir_node *new_block = be_transform_node(block);
3289 ir_node *op = get_Conv_op(node);
3290 ir_node *new_op = NULL;
3291 ir_graph *irg = current_ir_graph;
3292 dbg_info *dbgi = get_irn_dbg_info(node);
3293 ir_mode *src_mode = get_irn_mode(op);
3294 ir_mode *tgt_mode = get_irn_mode(node);
3295 int src_bits = get_mode_size_bits(src_mode);
3296 int tgt_bits = get_mode_size_bits(tgt_mode);
3297 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3298 ir_node *nomem = new_rd_NoMem(irg);
3299 ir_node *res = NULL;
3301 if (src_mode == mode_b) {
3302 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3303 /* nothing to do, we already model bools as 0/1 ints */
3304 return be_transform_node(op);
3307 if (src_mode == tgt_mode) {
3308 if (get_Conv_strict(node)) {
3309 if (ia32_cg_config.use_sse2) {
3310 /* when we are in SSE mode, we can kill all strict no-op conversion */
3311 return be_transform_node(op);
3314 /* this should be optimized already, but who knows... */
3315 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3316 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3317 return be_transform_node(op);
3321 if (mode_is_float(src_mode)) {
3322 new_op = be_transform_node(op);
3323 /* we convert from float ... */
3324 if (mode_is_float(tgt_mode)) {
3325 if (src_mode == mode_E && tgt_mode == mode_D
3326 && !get_Conv_strict(node)) {
3327 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3332 if (ia32_cg_config.use_sse2) {
3333 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3334 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3336 set_ia32_ls_mode(res, tgt_mode);
3338 if (get_Conv_strict(node)) {
3339 res = gen_x87_strict_conv(tgt_mode, new_op);
3340 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3343 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3348 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3349 if (ia32_cg_config.use_sse2) {
3350 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3352 set_ia32_ls_mode(res, src_mode);
3354 return gen_x87_fp_to_gp(node);
3358 /* we convert from int ... */
3359 if (mode_is_float(tgt_mode)) {
3361 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3362 if (ia32_cg_config.use_sse2) {
3363 new_op = be_transform_node(op);
3364 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3366 set_ia32_ls_mode(res, tgt_mode);
3368 res = gen_x87_gp_to_fp(node, src_mode);
3369 if (get_Conv_strict(node)) {
3370 /* The strict-Conv is only necessary, if the int mode has more bits
3371 * than the float mantissa */
3372 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3373 size_t float_mantissa;
3374 /* FIXME There is no way to get the mantissa size of a mode */
3375 switch (get_mode_size_bits(tgt_mode)) {
3376 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3377 case 64: float_mantissa = 52 + 1; break;
3379 case 96: float_mantissa = 64; break;
3380 default: float_mantissa = 0; break;
3382 if (float_mantissa < int_mantissa) {
3383 res = gen_x87_strict_conv(tgt_mode, res);
3384 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3389 } else if (tgt_mode == mode_b) {
3390 /* mode_b lowering already took care that we only have 0/1 values */
3391 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3392 src_mode, tgt_mode));
3393 return be_transform_node(op);
3396 if (src_bits == tgt_bits) {
3397 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3398 src_mode, tgt_mode));
3399 return be_transform_node(op);
3402 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3410 static ir_node *create_immediate_or_transform(ir_node *node,
3411 char immediate_constraint_type)
3413 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3414 if (new_node == NULL) {
3415 new_node = be_transform_node(node);
3421 * Transforms a FrameAddr into an ia32 Add.
3423 static ir_node *gen_be_FrameAddr(ir_node *node)
3425 ir_node *block = be_transform_node(get_nodes_block(node));
3426 ir_node *op = be_get_FrameAddr_frame(node);
3427 ir_node *new_op = be_transform_node(op);
3428 ir_graph *irg = current_ir_graph;
3429 dbg_info *dbgi = get_irn_dbg_info(node);
3430 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3433 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3434 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3435 set_ia32_use_frame(new_node);
3437 SET_IA32_ORIG_NODE(new_node, node);
3443 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3445 static ir_node *gen_be_Return(ir_node *node)
3447 ir_graph *irg = current_ir_graph;
3448 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3449 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3450 ir_entity *ent = get_irg_entity(irg);
3451 ir_type *tp = get_entity_type(ent);
3456 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3457 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3460 int pn_ret_val, pn_ret_mem, arity, i;
3462 assert(ret_val != NULL);
3463 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3464 return be_duplicate_node(node);
3467 res_type = get_method_res_type(tp, 0);
3469 if (! is_Primitive_type(res_type)) {
3470 return be_duplicate_node(node);
3473 mode = get_type_mode(res_type);
3474 if (! mode_is_float(mode)) {
3475 return be_duplicate_node(node);
3478 assert(get_method_n_ress(tp) == 1);
3480 pn_ret_val = get_Proj_proj(ret_val);
3481 pn_ret_mem = get_Proj_proj(ret_mem);
3483 /* get the Barrier */
3484 barrier = get_Proj_pred(ret_val);
3486 /* get result input of the Barrier */
3487 ret_val = get_irn_n(barrier, pn_ret_val);
3488 new_ret_val = be_transform_node(ret_val);
3490 /* get memory input of the Barrier */
3491 ret_mem = get_irn_n(barrier, pn_ret_mem);
3492 new_ret_mem = be_transform_node(ret_mem);
3494 frame = get_irg_frame(irg);
3496 dbgi = get_irn_dbg_info(barrier);
3497 block = be_transform_node(get_nodes_block(barrier));
3499 noreg = ia32_new_NoReg_gp(env_cg);
3501 /* store xmm0 onto stack */
3502 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3503 new_ret_mem, new_ret_val);
3504 set_ia32_ls_mode(sse_store, mode);
3505 set_ia32_op_type(sse_store, ia32_AddrModeD);
3506 set_ia32_use_frame(sse_store);
3508 /* load into x87 register */
3509 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3510 set_ia32_op_type(fld, ia32_AddrModeS);
3511 set_ia32_use_frame(fld);
3513 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3514 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3516 /* create a new barrier */
3517 arity = get_irn_arity(barrier);
3518 in = ALLOCAN(ir_node*, arity);
3519 for (i = 0; i < arity; ++i) {
3522 if (i == pn_ret_val) {
3524 } else if (i == pn_ret_mem) {
3527 ir_node *in = get_irn_n(barrier, i);
3528 new_in = be_transform_node(in);
3533 new_barrier = new_ir_node(dbgi, irg, block,
3534 get_irn_op(barrier), get_irn_mode(barrier),
3536 copy_node_attr(barrier, new_barrier);
3537 be_duplicate_deps(barrier, new_barrier);
3538 be_set_transformed_node(barrier, new_barrier);
3540 /* transform normally */
3541 return be_duplicate_node(node);
3545 * Transform a be_AddSP into an ia32_SubSP.
3547 static ir_node *gen_be_AddSP(ir_node *node)
3549 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3550 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3552 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3553 match_am | match_immediate);
3557 * Transform a be_SubSP into an ia32_AddSP
3559 static ir_node *gen_be_SubSP(ir_node *node)
3561 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3562 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3564 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3565 match_am | match_immediate);
3569 * Change some phi modes
3571 static ir_node *gen_Phi(ir_node *node)
3573 ir_node *block = be_transform_node(get_nodes_block(node));
3574 ir_graph *irg = current_ir_graph;
3575 dbg_info *dbgi = get_irn_dbg_info(node);
3576 ir_mode *mode = get_irn_mode(node);
3579 if (ia32_mode_needs_gp_reg(mode)) {
3580 /* we shouldn't have any 64bit stuff around anymore */
3581 assert(get_mode_size_bits(mode) <= 32);
3582 /* all integer operations are on 32bit registers now */
3584 } else if (mode_is_float(mode)) {
3585 if (ia32_cg_config.use_sse2) {
3592 /* phi nodes allow loops, so we use the old arguments for now
3593 * and fix this later */
3594 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3595 get_irn_in(node) + 1);
3596 copy_node_attr(node, phi);
3597 be_duplicate_deps(node, phi);
3599 be_enqueue_preds(node);
3607 static ir_node *gen_IJmp(ir_node *node)
3609 ir_node *block = get_nodes_block(node);
3610 ir_node *new_block = be_transform_node(block);
3611 dbg_info *dbgi = get_irn_dbg_info(node);
3612 ir_node *op = get_IJmp_target(node);
3614 ia32_address_mode_t am;
3615 ia32_address_t *addr = &am.addr;
3617 assert(get_irn_mode(op) == mode_P);
3619 match_arguments(&am, block, NULL, op, NULL,
3620 match_am | match_8bit_am | match_16bit_am |
3621 match_immediate | match_8bit | match_16bit);
3623 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3624 addr->base, addr->index, addr->mem,
3626 set_am_attributes(new_node, &am);
3627 SET_IA32_ORIG_NODE(new_node, node);
3629 new_node = fix_mem_proj(new_node, &am);
3635 * Transform a Bound node.
3637 static ir_node *gen_Bound(ir_node *node)
3640 ir_node *lower = get_Bound_lower(node);
3641 dbg_info *dbgi = get_irn_dbg_info(node);
3643 if (is_Const_0(lower)) {
3644 /* typical case for Java */
3645 ir_node *sub, *res, *flags, *block;
3646 ir_graph *irg = current_ir_graph;
3648 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3649 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3651 block = get_nodes_block(res);
3652 if (! is_Proj(res)) {
3654 set_irn_mode(sub, mode_T);
3655 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3657 sub = get_Proj_pred(res);
3659 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3660 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3661 SET_IA32_ORIG_NODE(new_node, node);
3663 panic("generic Bound not supported in ia32 Backend");
3669 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3671 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3672 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3674 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3675 match_immediate | match_mode_neutral);
3678 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3680 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3681 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3682 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3686 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3688 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3689 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3690 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3694 static ir_node *gen_ia32_l_Add(ir_node *node)
3696 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3697 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3698 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3699 match_commutative | match_am | match_immediate |
3700 match_mode_neutral);
3702 if (is_Proj(lowered)) {
3703 lowered = get_Proj_pred(lowered);
3705 assert(is_ia32_Add(lowered));
3706 set_irn_mode(lowered, mode_T);
3712 static ir_node *gen_ia32_l_Adc(ir_node *node)
3714 return gen_binop_flags(node, new_rd_ia32_Adc,
3715 match_commutative | match_am | match_immediate |
3716 match_mode_neutral);
3720 * Transforms a l_MulS into a "real" MulS node.
3722 * @return the created ia32 Mul node
3724 static ir_node *gen_ia32_l_Mul(ir_node *node)
3726 ir_node *left = get_binop_left(node);
3727 ir_node *right = get_binop_right(node);
3729 return gen_binop(node, left, right, new_rd_ia32_Mul,
3730 match_commutative | match_am | match_mode_neutral);
3734 * Transforms a l_IMulS into a "real" IMul1OPS node.
3736 * @return the created ia32 IMul1OP node
3738 static ir_node *gen_ia32_l_IMul(ir_node *node)
3740 ir_node *left = get_binop_left(node);
3741 ir_node *right = get_binop_right(node);
3743 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3744 match_commutative | match_am | match_mode_neutral);
3747 static ir_node *gen_ia32_l_Sub(ir_node *node)
3749 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3750 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3751 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3752 match_am | match_immediate | match_mode_neutral);
3754 if (is_Proj(lowered)) {
3755 lowered = get_Proj_pred(lowered);
3757 assert(is_ia32_Sub(lowered));
3758 set_irn_mode(lowered, mode_T);
3764 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3766 return gen_binop_flags(node, new_rd_ia32_Sbb,
3767 match_am | match_immediate | match_mode_neutral);
3771 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3772 * op1 - target to be shifted
3773 * op2 - contains bits to be shifted into target
3775 * Only op3 can be an immediate.
3777 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3778 ir_node *low, ir_node *count)
3780 ir_node *block = get_nodes_block(node);
3781 ir_node *new_block = be_transform_node(block);
3782 ir_graph *irg = current_ir_graph;
3783 dbg_info *dbgi = get_irn_dbg_info(node);
3784 ir_node *new_high = be_transform_node(high);
3785 ir_node *new_low = be_transform_node(low);
3789 /* the shift amount can be any mode that is bigger than 5 bits, since all
3790 * other bits are ignored anyway */
3791 while (is_Conv(count) &&
3792 get_irn_n_edges(count) == 1 &&
3793 mode_is_int(get_irn_mode(count))) {
3794 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3795 count = get_Conv_op(count);
3797 new_count = create_immediate_or_transform(count, 0);
3799 if (is_ia32_l_ShlD(node)) {
3800 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3803 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3806 SET_IA32_ORIG_NODE(new_node, node);
3811 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3813 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3814 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3815 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3816 return gen_lowered_64bit_shifts(node, high, low, count);
3819 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3821 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3822 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3823 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3824 return gen_lowered_64bit_shifts(node, high, low, count);
3827 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3829 ir_node *src_block = get_nodes_block(node);
3830 ir_node *block = be_transform_node(src_block);
3831 ir_graph *irg = current_ir_graph;
3832 dbg_info *dbgi = get_irn_dbg_info(node);
3833 ir_node *frame = get_irg_frame(irg);
3834 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3835 ir_node *nomem = new_NoMem();
3836 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3837 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3838 ir_node *new_val_low = be_transform_node(val_low);
3839 ir_node *new_val_high = be_transform_node(val_high);
3844 ir_node *store_high;
3846 if (!mode_is_signed(get_irn_mode(val_high))) {
3847 panic("unsigned long long -> float not supported yet (%+F)", node);
3851 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3853 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3855 SET_IA32_ORIG_NODE(store_low, node);
3856 SET_IA32_ORIG_NODE(store_high, node);
3858 set_ia32_use_frame(store_low);
3859 set_ia32_use_frame(store_high);
3860 set_ia32_op_type(store_low, ia32_AddrModeD);
3861 set_ia32_op_type(store_high, ia32_AddrModeD);
3862 set_ia32_ls_mode(store_low, mode_Iu);
3863 set_ia32_ls_mode(store_high, mode_Is);
3864 add_ia32_am_offs_int(store_high, 4);
3868 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3871 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3873 set_ia32_use_frame(fild);
3874 set_ia32_op_type(fild, ia32_AddrModeS);
3875 set_ia32_ls_mode(fild, mode_Ls);
3877 SET_IA32_ORIG_NODE(fild, node);
3879 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3882 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3884 ir_node *src_block = get_nodes_block(node);
3885 ir_node *block = be_transform_node(src_block);
3886 ir_graph *irg = current_ir_graph;
3887 dbg_info *dbgi = get_irn_dbg_info(node);
3888 ir_node *frame = get_irg_frame(irg);
3889 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3890 ir_node *nomem = new_NoMem();
3891 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3892 ir_node *new_val = be_transform_node(val);
3893 ir_node *fist, *mem;
3895 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3896 SET_IA32_ORIG_NODE(fist, node);
3897 set_ia32_use_frame(fist);
3898 set_ia32_op_type(fist, ia32_AddrModeD);
3899 set_ia32_ls_mode(fist, mode_Ls);
3905 * the BAD transformer.
3907 static ir_node *bad_transform(ir_node *node)
3909 panic("No transform function for %+F available.", node);
3913 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3915 ir_graph *irg = current_ir_graph;
3916 ir_node *block = be_transform_node(get_nodes_block(node));
3917 ir_node *pred = get_Proj_pred(node);
3918 ir_node *new_pred = be_transform_node(pred);
3919 ir_node *frame = get_irg_frame(irg);
3920 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3921 dbg_info *dbgi = get_irn_dbg_info(node);
3922 long pn = get_Proj_proj(node);
3927 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3928 SET_IA32_ORIG_NODE(load, node);
3929 set_ia32_use_frame(load);
3930 set_ia32_op_type(load, ia32_AddrModeS);
3931 set_ia32_ls_mode(load, mode_Iu);
3932 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3933 * 32 bit from it with this particular load */
3934 attr = get_ia32_attr(load);
3935 attr->data.need_64bit_stackent = 1;
3937 if (pn == pn_ia32_l_FloattoLL_res_high) {
3938 add_ia32_am_offs_int(load, 4);
3940 assert(pn == pn_ia32_l_FloattoLL_res_low);
3943 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3949 * Transform the Projs of an AddSP.
3951 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3953 ir_node *block = be_transform_node(get_nodes_block(node));
3954 ir_node *pred = get_Proj_pred(node);
3955 ir_node *new_pred = be_transform_node(pred);
3956 ir_graph *irg = current_ir_graph;
3957 dbg_info *dbgi = get_irn_dbg_info(node);
3958 long proj = get_Proj_proj(node);
3960 if (proj == pn_be_AddSP_sp) {
3961 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3962 pn_ia32_SubSP_stack);
3963 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3965 } else if (proj == pn_be_AddSP_res) {
3966 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3967 pn_ia32_SubSP_addr);
3968 } else if (proj == pn_be_AddSP_M) {
3969 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3972 panic("No idea how to transform proj->AddSP");
3976 * Transform the Projs of a SubSP.
3978 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3980 ir_node *block = be_transform_node(get_nodes_block(node));
3981 ir_node *pred = get_Proj_pred(node);
3982 ir_node *new_pred = be_transform_node(pred);
3983 ir_graph *irg = current_ir_graph;
3984 dbg_info *dbgi = get_irn_dbg_info(node);
3985 long proj = get_Proj_proj(node);
3987 if (proj == pn_be_SubSP_sp) {
3988 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3989 pn_ia32_AddSP_stack);
3990 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3992 } else if (proj == pn_be_SubSP_M) {
3993 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3996 panic("No idea how to transform proj->SubSP");
4000 * Transform and renumber the Projs from a Load.
4002 static ir_node *gen_Proj_Load(ir_node *node)
4005 ir_node *block = be_transform_node(get_nodes_block(node));
4006 ir_node *pred = get_Proj_pred(node);
4007 ir_graph *irg = current_ir_graph;
4008 dbg_info *dbgi = get_irn_dbg_info(node);
4009 long proj = get_Proj_proj(node);
4011 /* loads might be part of source address mode matches, so we don't
4012 * transform the ProjMs yet (with the exception of loads whose result is
4015 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4018 /* this is needed, because sometimes we have loops that are only
4019 reachable through the ProjM */
4020 be_enqueue_preds(node);
4021 /* do it in 2 steps, to silence firm verifier */
4022 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4023 set_Proj_proj(res, pn_ia32_mem);
4027 /* renumber the proj */
4028 new_pred = be_transform_node(pred);
4029 if (is_ia32_Load(new_pred)) {
4032 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4034 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4035 case pn_Load_X_regular:
4036 return new_rd_Jmp(dbgi, irg, block);
4037 case pn_Load_X_except:
4038 /* This Load might raise an exception. Mark it. */
4039 set_ia32_exc_label(new_pred, 1);
4040 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4044 } else if (is_ia32_Conv_I2I(new_pred) ||
4045 is_ia32_Conv_I2I8Bit(new_pred)) {
4046 set_irn_mode(new_pred, mode_T);
4047 if (proj == pn_Load_res) {
4048 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4049 } else if (proj == pn_Load_M) {
4050 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4052 } else if (is_ia32_xLoad(new_pred)) {
4055 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4057 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4058 case pn_Load_X_regular:
4059 return new_rd_Jmp(dbgi, irg, block);
4060 case pn_Load_X_except:
4061 /* This Load might raise an exception. Mark it. */
4062 set_ia32_exc_label(new_pred, 1);
4063 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4067 } else if (is_ia32_vfld(new_pred)) {
4070 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4072 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4073 case pn_Load_X_regular:
4074 return new_rd_Jmp(dbgi, irg, block);
4075 case pn_Load_X_except:
4076 /* This Load might raise an exception. Mark it. */
4077 set_ia32_exc_label(new_pred, 1);
4078 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4083 /* can happen for ProJMs when source address mode happened for the
4086 /* however it should not be the result proj, as that would mean the
4087 load had multiple users and should not have been used for
4089 if (proj != pn_Load_M) {
4090 panic("internal error: transformed node not a Load");
4092 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4095 panic("No idea how to transform proj");
4099 * Transform and renumber the Projs from a DivMod like instruction.
4101 static ir_node *gen_Proj_DivMod(ir_node *node)
4103 ir_node *block = be_transform_node(get_nodes_block(node));
4104 ir_node *pred = get_Proj_pred(node);
4105 ir_node *new_pred = be_transform_node(pred);
4106 ir_graph *irg = current_ir_graph;
4107 dbg_info *dbgi = get_irn_dbg_info(node);
4108 long proj = get_Proj_proj(node);
4110 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4112 switch (get_irn_opcode(pred)) {
4116 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4118 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4119 case pn_Div_X_regular:
4120 return new_rd_Jmp(dbgi, irg, block);
4121 case pn_Div_X_except:
4122 set_ia32_exc_label(new_pred, 1);
4123 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4131 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4133 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4134 case pn_Mod_X_except:
4135 set_ia32_exc_label(new_pred, 1);
4136 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4144 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4145 case pn_DivMod_res_div:
4146 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4147 case pn_DivMod_res_mod:
4148 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4149 case pn_DivMod_X_regular:
4150 return new_rd_Jmp(dbgi, irg, block);
4151 case pn_DivMod_X_except:
4152 set_ia32_exc_label(new_pred, 1);
4153 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4162 panic("No idea how to transform proj->DivMod");
4166 * Transform and renumber the Projs from a CopyB.
4168 static ir_node *gen_Proj_CopyB(ir_node *node)
4170 ir_node *block = be_transform_node(get_nodes_block(node));
4171 ir_node *pred = get_Proj_pred(node);
4172 ir_node *new_pred = be_transform_node(pred);
4173 ir_graph *irg = current_ir_graph;
4174 dbg_info *dbgi = get_irn_dbg_info(node);
4175 long proj = get_Proj_proj(node);
4178 case pn_CopyB_M_regular:
4179 if (is_ia32_CopyB_i(new_pred)) {
4180 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4181 } else if (is_ia32_CopyB(new_pred)) {
4182 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4189 panic("No idea how to transform proj->CopyB");
4193 * Transform and renumber the Projs from a Quot.
4195 static ir_node *gen_Proj_Quot(ir_node *node)
4197 ir_node *block = be_transform_node(get_nodes_block(node));
4198 ir_node *pred = get_Proj_pred(node);
4199 ir_node *new_pred = be_transform_node(pred);
4200 ir_graph *irg = current_ir_graph;
4201 dbg_info *dbgi = get_irn_dbg_info(node);
4202 long proj = get_Proj_proj(node);
4206 if (is_ia32_xDiv(new_pred)) {
4207 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4208 } else if (is_ia32_vfdiv(new_pred)) {
4209 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4213 if (is_ia32_xDiv(new_pred)) {
4214 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4215 } else if (is_ia32_vfdiv(new_pred)) {
4216 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4219 case pn_Quot_X_regular:
4220 case pn_Quot_X_except:
4225 panic("No idea how to transform proj->Quot");
4228 static ir_node *gen_be_Call(ir_node *node)
4230 dbg_info *const dbgi = get_irn_dbg_info(node);
4231 ir_graph *const irg = current_ir_graph;
4232 ir_node *const src_block = get_nodes_block(node);
4233 ir_node *const block = be_transform_node(src_block);
4234 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4235 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4236 ir_node *const sp = be_transform_node(src_sp);
4237 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4238 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4239 ia32_address_mode_t am;
4240 ia32_address_t *const addr = &am.addr;
4245 ir_node * eax = noreg;
4246 ir_node * ecx = noreg;
4247 ir_node * edx = noreg;
4248 unsigned const pop = be_Call_get_pop(node);
4249 ir_type *const call_tp = be_Call_get_type(node);
4251 /* Run the x87 simulator if the call returns a float value */
4252 if (get_method_n_ress(call_tp) > 0) {
4253 ir_type *const res_type = get_method_res_type(call_tp, 0);
4254 ir_mode *const res_mode = get_type_mode(res_type);
4256 if (res_mode != NULL && mode_is_float(res_mode)) {
4257 env_cg->do_x87_sim = 1;
4261 /* We do not want be_Call direct calls */
4262 assert(be_Call_get_entity(node) == NULL);
4264 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4265 match_am | match_immediate);
4267 i = get_irn_arity(node) - 1;
4268 fpcw = be_transform_node(get_irn_n(node, i--));
4269 for (; i >= be_pos_Call_first_arg; --i) {
4270 arch_register_req_t const *const req = arch_get_register_req(node, i);
4271 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4273 assert(req->type == arch_register_req_type_limited);
4274 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4276 switch (*req->limited) {
4277 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4278 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4279 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4280 default: panic("Invalid GP register for register parameter");
4284 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4285 call = new_rd_ia32_Call(dbgi, irg, block, addr->base, addr->index, mem,
4286 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4287 set_am_attributes(call, &am);
4288 call = fix_mem_proj(call, &am);
4290 if (get_irn_pinned(node) == op_pin_state_pinned)
4291 set_irn_pinned(call, op_pin_state_pinned);
4293 SET_IA32_ORIG_NODE(call, node);
4297 static ir_node *gen_be_IncSP(ir_node *node)
4299 ir_node *res = be_duplicate_node(node);
4300 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4306 * Transform the Projs from a be_Call.
4308 static ir_node *gen_Proj_be_Call(ir_node *node)
4310 ir_node *block = be_transform_node(get_nodes_block(node));
4311 ir_node *call = get_Proj_pred(node);
4312 ir_node *new_call = be_transform_node(call);
4313 ir_graph *irg = current_ir_graph;
4314 dbg_info *dbgi = get_irn_dbg_info(node);
4315 ir_type *method_type = be_Call_get_type(call);
4316 int n_res = get_method_n_ress(method_type);
4317 long proj = get_Proj_proj(node);
4318 ir_mode *mode = get_irn_mode(node);
4322 /* The following is kinda tricky: If we're using SSE, then we have to
4323 * move the result value of the call in floating point registers to an
4324 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4325 * after the call, we have to make sure to correctly make the
4326 * MemProj and the result Proj use these 2 nodes
4328 if (proj == pn_be_Call_M_regular) {
4329 // get new node for result, are we doing the sse load/store hack?
4330 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4331 ir_node *call_res_new;
4332 ir_node *call_res_pred = NULL;
4334 if (call_res != NULL) {
4335 call_res_new = be_transform_node(call_res);
4336 call_res_pred = get_Proj_pred(call_res_new);
4339 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4340 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4343 assert(is_ia32_xLoad(call_res_pred));
4344 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4348 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4349 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4351 ir_node *frame = get_irg_frame(irg);
4352 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4354 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4357 /* in case there is no memory output: create one to serialize the copy
4359 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4360 pn_be_Call_M_regular);
4361 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4362 pn_be_Call_first_res);
4364 /* store st(0) onto stack */
4365 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4367 set_ia32_op_type(fstp, ia32_AddrModeD);
4368 set_ia32_use_frame(fstp);
4370 /* load into SSE register */
4371 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4373 set_ia32_op_type(sse_load, ia32_AddrModeS);
4374 set_ia32_use_frame(sse_load);
4376 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4382 /* transform call modes */
4383 if (mode_is_data(mode)) {
4384 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4388 /* Map from be_Call to ia32_Call proj number */
4389 if (proj == pn_be_Call_sp) {
4390 proj = pn_ia32_Call_stack;
4391 } else if (proj == pn_be_Call_M_regular) {
4392 proj = pn_ia32_Call_M;
4394 arch_register_req_t const *const req = arch_get_register_req_out(node);
4395 int const n_outs = arch_irn_get_n_outs(new_call);
4398 assert(proj >= pn_be_Call_first_res);
4399 assert(req->type & arch_register_req_type_limited);
4401 for (i = 0; i < n_outs; ++i) {
4402 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4404 if (!(new_req->type & arch_register_req_type_limited) ||
4405 new_req->cls != req->cls ||
4406 *new_req->limited != *req->limited)
4415 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4417 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4419 case pn_ia32_Call_stack:
4420 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4423 case pn_ia32_Call_fpcw:
4424 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4432 * Transform the Projs from a Cmp.
4434 static ir_node *gen_Proj_Cmp(ir_node *node)
4436 /* this probably means not all mode_b nodes were lowered... */
4437 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4442 * Transform the Projs from a Bound.
4444 static ir_node *gen_Proj_Bound(ir_node *node)
4446 ir_node *new_node, *block;
4447 ir_node *pred = get_Proj_pred(node);
4449 switch (get_Proj_proj(node)) {
4451 return be_transform_node(get_Bound_mem(pred));
4452 case pn_Bound_X_regular:
4453 new_node = be_transform_node(pred);
4454 block = get_nodes_block(new_node);
4455 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4456 case pn_Bound_X_except:
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_false);
4461 return be_transform_node(get_Bound_index(pred));
4463 panic("unsupported Proj from Bound");
4467 static ir_node *gen_Proj_ASM(ir_node *node)
4473 if (get_irn_mode(node) != mode_M)
4474 return be_duplicate_node(node);
4476 pred = get_Proj_pred(node);
4477 new_pred = be_transform_node(pred);
4478 block = get_nodes_block(new_pred);
4479 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4480 arch_irn_get_n_outs(new_pred) + 1);
4484 * Transform and potentially renumber Proj nodes.
4486 static ir_node *gen_Proj(ir_node *node)
4488 ir_node *pred = get_Proj_pred(node);
4491 switch (get_irn_opcode(pred)) {
4493 proj = get_Proj_proj(node);
4494 if (proj == pn_Store_M) {
4495 return be_transform_node(pred);
4497 panic("No idea how to transform proj->Store");
4500 return gen_Proj_Load(node);
4502 return gen_Proj_ASM(node);
4506 return gen_Proj_DivMod(node);
4508 return gen_Proj_CopyB(node);
4510 return gen_Proj_Quot(node);
4512 return gen_Proj_be_SubSP(node);
4514 return gen_Proj_be_AddSP(node);
4516 return gen_Proj_be_Call(node);
4518 return gen_Proj_Cmp(node);
4520 return gen_Proj_Bound(node);
4522 proj = get_Proj_proj(node);
4524 case pn_Start_X_initial_exec: {
4525 ir_node *block = get_nodes_block(pred);
4526 ir_node *new_block = be_transform_node(block);
4527 dbg_info *dbgi = get_irn_dbg_info(node);
4528 /* we exchange the ProjX with a jump */
4529 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4534 case pn_Start_P_tls:
4535 return gen_Proj_tls(node);
4540 if (is_ia32_l_FloattoLL(pred)) {
4541 return gen_Proj_l_FloattoLL(node);
4543 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4547 ir_mode *mode = get_irn_mode(node);
4548 if (ia32_mode_needs_gp_reg(mode)) {
4549 ir_node *new_pred = be_transform_node(pred);
4550 ir_node *block = be_transform_node(get_nodes_block(node));
4551 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4552 mode_Iu, get_Proj_proj(node));
4553 #ifdef DEBUG_libfirm
4554 new_proj->node_nr = node->node_nr;
4560 return be_duplicate_node(node);
4564 * Enters all transform functions into the generic pointer
4566 static void register_transformers(void)
4570 /* first clear the generic function pointer for all ops */
4571 clear_irp_opcodes_generic_func();
4573 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4574 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4612 /* transform ops from intrinsic lowering */
4624 GEN(ia32_l_LLtoFloat);
4625 GEN(ia32_l_FloattoLL);
4631 /* we should never see these nodes */
4646 /* handle generic backend nodes */
4655 op_Mulh = get_op_Mulh();
4664 * Pre-transform all unknown and noreg nodes.
4666 static void ia32_pretransform_node(void)
4668 ia32_code_gen_t *cg = env_cg;
4670 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4671 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4672 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4673 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4674 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4675 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4680 * Walker, checks if all ia32 nodes producing more than one result have their
4681 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4683 static void add_missing_keep_walker(ir_node *node, void *data)
4686 unsigned found_projs = 0;
4687 const ir_edge_t *edge;
4688 ir_mode *mode = get_irn_mode(node);
4693 if (!is_ia32_irn(node))
4696 n_outs = arch_irn_get_n_outs(node);
4699 if (is_ia32_SwitchJmp(node))
4702 assert(n_outs < (int) sizeof(unsigned) * 8);
4703 foreach_out_edge(node, edge) {
4704 ir_node *proj = get_edge_src_irn(edge);
4707 /* The node could be kept */
4711 if (get_irn_mode(proj) == mode_M)
4714 pn = get_Proj_proj(proj);
4715 assert(pn < n_outs);
4716 found_projs |= 1 << pn;
4720 /* are keeps missing? */
4722 for (i = 0; i < n_outs; ++i) {
4725 const arch_register_req_t *req;
4726 const arch_register_class_t *cls;
4728 if (found_projs & (1 << i)) {
4732 req = get_ia32_out_req(node, i);
4737 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4741 block = get_nodes_block(node);
4742 in[0] = new_r_Proj(current_ir_graph, block, node,
4743 arch_register_class_mode(cls), i);
4744 if (last_keep != NULL) {
4745 be_Keep_add_node(last_keep, cls, in[0]);
4747 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4748 if (sched_is_scheduled(node)) {
4749 sched_add_after(node, last_keep);
4756 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4759 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4761 ir_graph *irg = be_get_birg_irg(cg->birg);
4762 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4765 /* do the transformation */
4766 void ia32_transform_graph(ia32_code_gen_t *cg)
4770 register_transformers();
4772 initial_fpcw = NULL;
4774 BE_TIMER_PUSH(t_heights);
4775 heights = heights_new(cg->irg);
4776 BE_TIMER_POP(t_heights);
4777 ia32_calculate_non_address_mode_nodes(cg->birg);
4779 /* the transform phase is not safe for CSE (yet) because several nodes get
4780 * attributes set after their creation */
4781 cse_last = get_opt_cse();
4784 be_transform_graph(cg->birg, ia32_pretransform_node);
4786 set_opt_cse(cse_last);
4788 ia32_free_non_address_mode_nodes();
4789 heights_free(heights);
4793 void ia32_init_transform(void)
4795 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");