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 set_ia32_flags(load, get_ia32_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 set_ia32_flags(load, get_ia32_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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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, ia32_get_old_node_name(env_cg, 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 for (i = arity - 1; i >= 0; --i) {
1316 ir_node *const pred = get_Sync_pred(src_mem, i);
1318 /* avoid memory loop */
1319 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1322 ins[n++] = be_transform_node(pred);
1327 return new_r_Sync(irg, block, n, ins);
1331 ins[0] = be_transform_node(src_mem);
1333 return new_r_Sync(irg, block, 2, ins);
1338 * Generates an ia32 DivMod with additional infrastructure for the
1339 * register allocator if needed.
1341 static ir_node *create_Div(ir_node *node)
1343 ir_graph *irg = current_ir_graph;
1344 dbg_info *dbgi = get_irn_dbg_info(node);
1345 ir_node *block = get_nodes_block(node);
1346 ir_node *new_block = be_transform_node(block);
1353 ir_node *sign_extension;
1354 ia32_address_mode_t am;
1355 ia32_address_t *addr = &am.addr;
1357 /* the upper bits have random contents for smaller modes */
1358 switch (get_irn_opcode(node)) {
1360 op1 = get_Div_left(node);
1361 op2 = get_Div_right(node);
1362 mem = get_Div_mem(node);
1363 mode = get_Div_resmode(node);
1366 op1 = get_Mod_left(node);
1367 op2 = get_Mod_right(node);
1368 mem = get_Mod_mem(node);
1369 mode = get_Mod_resmode(node);
1372 op1 = get_DivMod_left(node);
1373 op2 = get_DivMod_right(node);
1374 mem = get_DivMod_mem(node);
1375 mode = get_DivMod_resmode(node);
1378 panic("invalid divmod node %+F", node);
1381 match_arguments(&am, block, op1, op2, NULL, match_am);
1383 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1384 is the memory of the consumed address. We can have only the second op as address
1385 in Div nodes, so check only op2. */
1386 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1388 if (mode_is_signed(mode)) {
1389 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1390 be_dep_on_frame(produceval);
1391 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1394 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1395 addr->index, new_mem, am.new_op2,
1396 am.new_op1, sign_extension);
1398 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1399 be_dep_on_frame(sign_extension);
1401 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1402 addr->index, new_mem, am.new_op2,
1403 am.new_op1, sign_extension);
1406 set_irn_pinned(new_node, get_irn_pinned(node));
1408 set_am_attributes(new_node, &am);
1409 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1411 new_node = fix_mem_proj(new_node, &am);
1417 static ir_node *gen_Mod(ir_node *node)
1419 return create_Div(node);
1422 static ir_node *gen_Div(ir_node *node)
1424 return create_Div(node);
1427 static ir_node *gen_DivMod(ir_node *node)
1429 return create_Div(node);
1435 * Creates an ia32 floating Div.
1437 * @return The created ia32 xDiv node
1439 static ir_node *gen_Quot(ir_node *node)
1441 ir_node *op1 = get_Quot_left(node);
1442 ir_node *op2 = get_Quot_right(node);
1444 if (ia32_cg_config.use_sse2) {
1445 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1447 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv);
1453 * Creates an ia32 Shl.
1455 * @return The created ia32 Shl node
1457 static ir_node *gen_Shl(ir_node *node)
1459 ir_node *left = get_Shl_left(node);
1460 ir_node *right = get_Shl_right(node);
1462 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1463 match_mode_neutral | match_immediate);
1467 * Creates an ia32 Shr.
1469 * @return The created ia32 Shr node
1471 static ir_node *gen_Shr(ir_node *node)
1473 ir_node *left = get_Shr_left(node);
1474 ir_node *right = get_Shr_right(node);
1476 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1482 * Creates an ia32 Sar.
1484 * @return The created ia32 Shrs node
1486 static ir_node *gen_Shrs(ir_node *node)
1488 ir_node *left = get_Shrs_left(node);
1489 ir_node *right = get_Shrs_right(node);
1490 ir_mode *mode = get_irn_mode(node);
1492 if (is_Const(right) && mode == mode_Is) {
1493 tarval *tv = get_Const_tarval(right);
1494 long val = get_tarval_long(tv);
1496 /* this is a sign extension */
1497 ir_graph *irg = current_ir_graph;
1498 dbg_info *dbgi = get_irn_dbg_info(node);
1499 ir_node *block = be_transform_node(get_nodes_block(node));
1501 ir_node *new_op = be_transform_node(op);
1502 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1504 be_dep_on_frame(pval);
1505 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1509 /* 8 or 16 bit sign extension? */
1510 if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1511 ir_node *shl_left = get_Shl_left(left);
1512 ir_node *shl_right = get_Shl_right(left);
1513 if (is_Const(shl_right)) {
1514 tarval *tv1 = get_Const_tarval(right);
1515 tarval *tv2 = get_Const_tarval(shl_right);
1516 if (tv1 == tv2 && tarval_is_long(tv1)) {
1517 long val = get_tarval_long(tv1);
1518 if (val == 16 || val == 24) {
1519 dbg_info *dbgi = get_irn_dbg_info(node);
1520 ir_node *block = get_nodes_block(node);
1530 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1539 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1545 * Creates an ia32 Rol.
1547 * @param op1 The first operator
1548 * @param op2 The second operator
1549 * @return The created ia32 RotL node
1551 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1553 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1559 * Creates an ia32 Ror.
1560 * NOTE: There is no RotR with immediate because this would always be a RotL
1561 * "imm-mode_size_bits" which can be pre-calculated.
1563 * @param op1 The first operator
1564 * @param op2 The second operator
1565 * @return The created ia32 RotR node
1567 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1569 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1575 * Creates an ia32 RotR or RotL (depending on the found pattern).
1577 * @return The created ia32 RotL or RotR node
1579 static ir_node *gen_Rotl(ir_node *node)
1581 ir_node *rotate = NULL;
1582 ir_node *op1 = get_Rotl_left(node);
1583 ir_node *op2 = get_Rotl_right(node);
1585 /* Firm has only RotL, so we are looking for a right (op2)
1586 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1587 that means we can create a RotR instead of an Add and a RotL */
1591 ir_node *left = get_Add_left(add);
1592 ir_node *right = get_Add_right(add);
1593 if (is_Const(right)) {
1594 tarval *tv = get_Const_tarval(right);
1595 ir_mode *mode = get_irn_mode(node);
1596 long bits = get_mode_size_bits(mode);
1598 if (is_Minus(left) &&
1599 tarval_is_long(tv) &&
1600 get_tarval_long(tv) == bits &&
1603 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1604 rotate = gen_Ror(node, op1, get_Minus_op(left));
1609 if (rotate == NULL) {
1610 rotate = gen_Rol(node, op1, op2);
1619 * Transforms a Minus node.
1621 * @return The created ia32 Minus node
1623 static ir_node *gen_Minus(ir_node *node)
1625 ir_node *op = get_Minus_op(node);
1626 ir_node *block = be_transform_node(get_nodes_block(node));
1627 ir_graph *irg = current_ir_graph;
1628 dbg_info *dbgi = get_irn_dbg_info(node);
1629 ir_mode *mode = get_irn_mode(node);
1634 if (mode_is_float(mode)) {
1635 ir_node *new_op = be_transform_node(op);
1636 if (ia32_cg_config.use_sse2) {
1637 /* TODO: non-optimal... if we have many xXors, then we should
1638 * rather create a load for the const and use that instead of
1639 * several AM nodes... */
1640 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1641 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1642 ir_node *nomem = new_rd_NoMem(irg);
1644 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1645 nomem, new_op, noreg_xmm);
1647 size = get_mode_size_bits(mode);
1648 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1650 set_ia32_am_sc(new_node, ent);
1651 set_ia32_op_type(new_node, ia32_AddrModeS);
1652 set_ia32_ls_mode(new_node, mode);
1654 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1657 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1660 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1666 * Transforms a Not node.
1668 * @return The created ia32 Not node
1670 static ir_node *gen_Not(ir_node *node)
1672 ir_node *op = get_Not_op(node);
1674 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1675 assert (! mode_is_float(get_irn_mode(node)));
1677 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1683 * Transforms an Abs node.
1685 * @return The created ia32 Abs node
1687 static ir_node *gen_Abs(ir_node *node)
1689 ir_node *block = get_nodes_block(node);
1690 ir_node *new_block = be_transform_node(block);
1691 ir_node *op = get_Abs_op(node);
1692 ir_graph *irg = current_ir_graph;
1693 dbg_info *dbgi = get_irn_dbg_info(node);
1694 ir_mode *mode = get_irn_mode(node);
1695 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1696 ir_node *nomem = new_NoMem();
1702 if (mode_is_float(mode)) {
1703 new_op = be_transform_node(op);
1705 if (ia32_cg_config.use_sse2) {
1706 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1707 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1708 nomem, new_op, noreg_fp);
1710 size = get_mode_size_bits(mode);
1711 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1713 set_ia32_am_sc(new_node, ent);
1715 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1717 set_ia32_op_type(new_node, ia32_AddrModeS);
1718 set_ia32_ls_mode(new_node, mode);
1720 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1721 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1724 ir_node *xor, *pval, *sign_extension;
1726 if (get_mode_size_bits(mode) == 32) {
1727 new_op = be_transform_node(op);
1729 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1732 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1733 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1736 be_dep_on_frame(pval);
1737 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1739 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1740 nomem, new_op, sign_extension);
1741 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1743 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1744 nomem, xor, sign_extension);
1745 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1752 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1754 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1756 dbg_info *dbgi = get_irn_dbg_info(cmp);
1757 ir_node *block = get_nodes_block(cmp);
1758 ir_node *new_block = be_transform_node(block);
1759 ir_node *op1 = be_transform_node(x);
1760 ir_node *op2 = be_transform_node(n);
1762 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1766 * Transform a node returning a "flag" result.
1768 * @param node the node to transform
1769 * @param pnc_out the compare mode to use
1771 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1780 /* we have a Cmp as input */
1781 if (is_Proj(node)) {
1782 ir_node *pred = get_Proj_pred(node);
1784 pn_Cmp pnc = get_Proj_proj(node);
1785 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1786 ir_node *l = get_Cmp_left(pred);
1787 ir_node *r = get_Cmp_right(pred);
1789 ir_node *la = get_And_left(l);
1790 ir_node *ra = get_And_right(l);
1792 ir_node *c = get_Shl_left(la);
1793 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1794 /* (1 << n) & ra) */
1795 ir_node *n = get_Shl_right(la);
1796 flags = gen_bt(pred, ra, n);
1797 /* we must generate a Jc/Jnc jump */
1798 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1801 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1806 ir_node *c = get_Shl_left(ra);
1807 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1808 /* la & (1 << n)) */
1809 ir_node *n = get_Shl_right(ra);
1810 flags = gen_bt(pred, la, n);
1811 /* we must generate a Jc/Jnc jump */
1812 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1815 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1821 flags = be_transform_node(pred);
1827 /* a mode_b value, we have to compare it against 0 */
1828 dbgi = get_irn_dbg_info(node);
1829 new_block = be_transform_node(get_nodes_block(node));
1830 new_op = be_transform_node(node);
1831 noreg = ia32_new_NoReg_gp(env_cg);
1832 nomem = new_NoMem();
1833 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1834 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1835 *pnc_out = pn_Cmp_Lg;
1840 * Transforms a Load.
1842 * @return the created ia32 Load node
1844 static ir_node *gen_Load(ir_node *node)
1846 ir_node *old_block = get_nodes_block(node);
1847 ir_node *block = be_transform_node(old_block);
1848 ir_node *ptr = get_Load_ptr(node);
1849 ir_node *mem = get_Load_mem(node);
1850 ir_node *new_mem = be_transform_node(mem);
1853 ir_graph *irg = current_ir_graph;
1854 dbg_info *dbgi = get_irn_dbg_info(node);
1855 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1856 ir_mode *mode = get_Load_mode(node);
1859 ia32_address_t addr;
1861 /* construct load address */
1862 memset(&addr, 0, sizeof(addr));
1863 ia32_create_address_mode(&addr, ptr, 0);
1870 base = be_transform_node(base);
1873 if (index == NULL) {
1876 index = be_transform_node(index);
1879 if (mode_is_float(mode)) {
1880 if (ia32_cg_config.use_sse2) {
1881 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1883 res_mode = mode_xmm;
1885 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1887 res_mode = mode_vfp;
1890 assert(mode != mode_b);
1892 /* create a conv node with address mode for smaller modes */
1893 if (get_mode_size_bits(mode) < 32) {
1894 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1895 new_mem, noreg, mode);
1897 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1902 set_irn_pinned(new_node, get_irn_pinned(node));
1903 set_ia32_op_type(new_node, ia32_AddrModeS);
1904 set_ia32_ls_mode(new_node, mode);
1905 set_address(new_node, &addr);
1907 if (get_irn_pinned(node) == op_pin_state_floats) {
1908 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1911 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1913 be_dep_on_frame(new_node);
1917 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1918 ir_node *ptr, ir_node *other)
1925 /* we only use address mode if we're the only user of the load */
1926 if (get_irn_n_edges(node) > 1)
1929 load = get_Proj_pred(node);
1932 if (get_nodes_block(load) != block)
1935 /* store should have the same pointer as the load */
1936 if (get_Load_ptr(load) != ptr)
1939 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1940 if (other != NULL &&
1941 get_nodes_block(other) == block &&
1942 heights_reachable_in_block(heights, other, load)) {
1946 if (prevents_AM(block, load, mem))
1948 /* Store should be attached to the load via mem */
1949 assert(heights_reachable_in_block(heights, mem, load));
1954 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1955 ir_node *mem, ir_node *ptr, ir_mode *mode,
1956 construct_binop_dest_func *func,
1957 construct_binop_dest_func *func8bit,
1958 match_flags_t flags)
1960 ir_node *src_block = get_nodes_block(node);
1962 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1963 ir_graph *irg = current_ir_graph;
1970 ia32_address_mode_t am;
1971 ia32_address_t *addr = &am.addr;
1972 memset(&am, 0, sizeof(am));
1974 assert(flags & match_dest_am);
1975 assert(flags & match_immediate); /* there is no destam node without... */
1976 commutative = (flags & match_commutative) != 0;
1978 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1979 build_address(&am, op1, ia32_create_am_double_use);
1980 new_op = create_immediate_or_transform(op2, 0);
1981 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1982 build_address(&am, op2, ia32_create_am_double_use);
1983 new_op = create_immediate_or_transform(op1, 0);
1988 if (addr->base == NULL)
1989 addr->base = noreg_gp;
1990 if (addr->index == NULL)
1991 addr->index = noreg_gp;
1992 if (addr->mem == NULL)
1993 addr->mem = new_NoMem();
1995 dbgi = get_irn_dbg_info(node);
1996 block = be_transform_node(src_block);
1997 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
1999 if (get_mode_size_bits(mode) == 8) {
2000 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2003 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
2006 set_address(new_node, addr);
2007 set_ia32_op_type(new_node, ia32_AddrModeD);
2008 set_ia32_ls_mode(new_node, mode);
2009 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2011 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2012 mem_proj = be_transform_node(am.mem_proj);
2013 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2018 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2019 ir_node *ptr, ir_mode *mode,
2020 construct_unop_dest_func *func)
2022 ir_graph *irg = current_ir_graph;
2023 ir_node *src_block = get_nodes_block(node);
2029 ia32_address_mode_t am;
2030 ia32_address_t *addr = &am.addr;
2032 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2035 memset(&am, 0, sizeof(am));
2036 build_address(&am, op, ia32_create_am_double_use);
2038 dbgi = get_irn_dbg_info(node);
2039 block = be_transform_node(src_block);
2040 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2041 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2042 set_address(new_node, addr);
2043 set_ia32_op_type(new_node, ia32_AddrModeD);
2044 set_ia32_ls_mode(new_node, mode);
2045 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2047 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2048 mem_proj = be_transform_node(am.mem_proj);
2049 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2054 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2056 ir_mode *mode = get_irn_mode(node);
2057 ir_node *mux_true = get_Mux_true(node);
2058 ir_node *mux_false = get_Mux_false(node);
2069 ia32_address_t addr;
2071 if (get_mode_size_bits(mode) != 8)
2074 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2076 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2082 build_address_ptr(&addr, ptr, mem);
2084 irg = current_ir_graph;
2085 dbgi = get_irn_dbg_info(node);
2086 block = get_nodes_block(node);
2087 new_block = be_transform_node(block);
2088 cond = get_Mux_sel(node);
2089 flags = get_flags_node(cond, &pnc);
2090 new_mem = be_transform_node(mem);
2091 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2092 addr.index, addr.mem, flags, pnc, negated);
2093 set_address(new_node, &addr);
2094 set_ia32_op_type(new_node, ia32_AddrModeD);
2095 set_ia32_ls_mode(new_node, mode);
2096 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2101 static ir_node *try_create_dest_am(ir_node *node)
2103 ir_node *val = get_Store_value(node);
2104 ir_node *mem = get_Store_mem(node);
2105 ir_node *ptr = get_Store_ptr(node);
2106 ir_mode *mode = get_irn_mode(val);
2107 unsigned bits = get_mode_size_bits(mode);
2112 /* handle only GP modes for now... */
2113 if (!ia32_mode_needs_gp_reg(mode))
2117 /* store must be the only user of the val node */
2118 if (get_irn_n_edges(val) > 1)
2120 /* skip pointless convs */
2122 ir_node *conv_op = get_Conv_op(val);
2123 ir_mode *pred_mode = get_irn_mode(conv_op);
2124 if (!ia32_mode_needs_gp_reg(pred_mode))
2126 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2134 /* value must be in the same block */
2135 if (get_nodes_block(node) != get_nodes_block(val))
2138 switch (get_irn_opcode(val)) {
2140 op1 = get_Add_left(val);
2141 op2 = get_Add_right(val);
2142 if (ia32_cg_config.use_incdec) {
2143 if (is_Const_1(op2)) {
2144 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_IncMem);
2146 } else if (is_Const_Minus_1(op2)) {
2147 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_DecMem);
2151 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2152 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2153 match_dest_am | match_commutative |
2157 op1 = get_Sub_left(val);
2158 op2 = get_Sub_right(val);
2159 if (is_Const(op2)) {
2160 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2162 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2163 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2164 match_dest_am | match_immediate);
2167 op1 = get_And_left(val);
2168 op2 = get_And_right(val);
2169 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2170 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2171 match_dest_am | match_commutative |
2175 op1 = get_Or_left(val);
2176 op2 = get_Or_right(val);
2177 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2178 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2179 match_dest_am | match_commutative |
2183 op1 = get_Eor_left(val);
2184 op2 = get_Eor_right(val);
2185 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2186 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2187 match_dest_am | match_commutative |
2191 op1 = get_Shl_left(val);
2192 op2 = get_Shl_right(val);
2193 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2194 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2195 match_dest_am | match_immediate);
2198 op1 = get_Shr_left(val);
2199 op2 = get_Shr_right(val);
2200 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2201 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2202 match_dest_am | match_immediate);
2205 op1 = get_Shrs_left(val);
2206 op2 = get_Shrs_right(val);
2207 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2208 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2209 match_dest_am | match_immediate);
2212 op1 = get_Rotl_left(val);
2213 op2 = get_Rotl_right(val);
2214 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2215 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2216 match_dest_am | match_immediate);
2218 /* TODO: match ROR patterns... */
2220 new_node = try_create_SetMem(val, ptr, mem);
2223 op1 = get_Minus_op(val);
2224 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2227 /* should be lowered already */
2228 assert(mode != mode_b);
2229 op1 = get_Not_op(val);
2230 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2236 if (new_node != NULL) {
2237 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2238 get_irn_pinned(node) == op_pin_state_pinned) {
2239 set_irn_pinned(new_node, op_pin_state_pinned);
2246 static int is_float_to_int_conv(const ir_node *node)
2248 ir_mode *mode = get_irn_mode(node);
2252 if (mode != mode_Is && mode != mode_Hs)
2257 conv_op = get_Conv_op(node);
2258 conv_mode = get_irn_mode(conv_op);
2260 if (!mode_is_float(conv_mode))
2267 * Transform a Store(floatConst) into a sequence of
2270 * @return the created ia32 Store node
2272 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2274 ir_mode *mode = get_irn_mode(cns);
2275 unsigned size = get_mode_size_bytes(mode);
2276 tarval *tv = get_Const_tarval(cns);
2277 ir_node *block = get_nodes_block(node);
2278 ir_node *new_block = be_transform_node(block);
2279 ir_node *ptr = get_Store_ptr(node);
2280 ir_node *mem = get_Store_mem(node);
2281 ir_graph *irg = current_ir_graph;
2282 dbg_info *dbgi = get_irn_dbg_info(node);
2286 ia32_address_t addr;
2288 assert(size % 4 == 0);
2291 build_address_ptr(&addr, ptr, mem);
2295 get_tarval_sub_bits(tv, ofs) |
2296 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2297 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2298 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2299 ir_node *imm = create_Immediate(NULL, 0, val);
2301 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2302 addr.index, addr.mem, imm);
2304 set_irn_pinned(new_node, get_irn_pinned(node));
2305 set_ia32_op_type(new_node, ia32_AddrModeD);
2306 set_ia32_ls_mode(new_node, mode_Iu);
2307 set_address(new_node, &addr);
2308 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2310 ins[i++] = new_node;
2315 } while (size != 0);
2317 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2321 * Generate a vfist or vfisttp instruction.
2323 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2324 ir_node *mem, ir_node *val, ir_node **fist)
2328 if (ia32_cg_config.use_fisttp) {
2329 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2330 if other users exists */
2331 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2332 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2333 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2334 be_new_Keep(reg_class, irg, block, 1, &value);
2336 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2339 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2342 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2348 * Transforms a general (no special case) Store.
2350 * @return the created ia32 Store node
2352 static ir_node *gen_general_Store(ir_node *node)
2354 ir_node *val = get_Store_value(node);
2355 ir_mode *mode = get_irn_mode(val);
2356 ir_node *block = get_nodes_block(node);
2357 ir_node *new_block = be_transform_node(block);
2358 ir_node *ptr = get_Store_ptr(node);
2359 ir_node *mem = get_Store_mem(node);
2360 ir_graph *irg = current_ir_graph;
2361 dbg_info *dbgi = get_irn_dbg_info(node);
2362 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2363 ir_node *new_val, *new_node, *store;
2364 ia32_address_t addr;
2366 /* check for destination address mode */
2367 new_node = try_create_dest_am(node);
2368 if (new_node != NULL)
2371 /* construct store address */
2372 memset(&addr, 0, sizeof(addr));
2373 ia32_create_address_mode(&addr, ptr, 0);
2375 if (addr.base == NULL) {
2378 addr.base = be_transform_node(addr.base);
2381 if (addr.index == NULL) {
2384 addr.index = be_transform_node(addr.index);
2386 addr.mem = be_transform_node(mem);
2388 if (mode_is_float(mode)) {
2389 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2391 while (is_Conv(val) && mode == get_irn_mode(val)) {
2392 ir_node *op = get_Conv_op(val);
2393 if (!mode_is_float(get_irn_mode(op)))
2397 new_val = be_transform_node(val);
2398 if (ia32_cg_config.use_sse2) {
2399 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2400 addr.index, addr.mem, new_val);
2402 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2403 addr.index, addr.mem, new_val, mode);
2406 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2407 val = get_Conv_op(val);
2409 /* TODO: is this optimisation still necessary at all (middleend)? */
2410 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2411 while (is_Conv(val)) {
2412 ir_node *op = get_Conv_op(val);
2413 if (!mode_is_float(get_irn_mode(op)))
2415 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2419 new_val = be_transform_node(val);
2420 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2422 new_val = create_immediate_or_transform(val, 0);
2423 assert(mode != mode_b);
2425 if (get_mode_size_bits(mode) == 8) {
2426 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2427 addr.index, addr.mem, new_val);
2429 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2430 addr.index, addr.mem, new_val);
2435 set_irn_pinned(store, get_irn_pinned(node));
2436 set_ia32_op_type(store, ia32_AddrModeD);
2437 set_ia32_ls_mode(store, mode);
2439 set_address(store, &addr);
2440 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2446 * Transforms a Store.
2448 * @return the created ia32 Store node
2450 static ir_node *gen_Store(ir_node *node)
2452 ir_node *val = get_Store_value(node);
2453 ir_mode *mode = get_irn_mode(val);
2455 if (mode_is_float(mode) && is_Const(val)) {
2456 /* We can transform every floating const store
2457 into a sequence of integer stores.
2458 If the constant is already in a register,
2459 it would be better to use it, but we don't
2460 have this information here. */
2461 return gen_float_const_Store(node, val);
2463 return gen_general_Store(node);
2467 * Transforms a Switch.
2469 * @return the created ia32 SwitchJmp node
2471 static ir_node *create_Switch(ir_node *node)
2473 ir_graph *irg = current_ir_graph;
2474 dbg_info *dbgi = get_irn_dbg_info(node);
2475 ir_node *block = be_transform_node(get_nodes_block(node));
2476 ir_node *sel = get_Cond_selector(node);
2477 ir_node *new_sel = be_transform_node(sel);
2478 int switch_min = INT_MAX;
2479 int switch_max = INT_MIN;
2480 long default_pn = get_Cond_defaultProj(node);
2482 const ir_edge_t *edge;
2484 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2486 /* determine the smallest switch case value */
2487 foreach_out_edge(node, edge) {
2488 ir_node *proj = get_edge_src_irn(edge);
2489 long pn = get_Proj_proj(proj);
2490 if (pn == default_pn)
2493 if (pn < switch_min)
2495 if (pn > switch_max)
2499 if ((unsigned) (switch_max - switch_min) > 256000) {
2500 panic("Size of switch %+F bigger than 256000", node);
2503 if (switch_min != 0) {
2504 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2506 /* if smallest switch case is not 0 we need an additional sub */
2507 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2508 add_ia32_am_offs_int(new_sel, -switch_min);
2509 set_ia32_op_type(new_sel, ia32_AddrModeS);
2511 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2514 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2515 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2521 * Transform a Cond node.
2523 static ir_node *gen_Cond(ir_node *node)
2525 ir_node *block = get_nodes_block(node);
2526 ir_node *new_block = be_transform_node(block);
2527 ir_graph *irg = current_ir_graph;
2528 dbg_info *dbgi = get_irn_dbg_info(node);
2529 ir_node *sel = get_Cond_selector(node);
2530 ir_mode *sel_mode = get_irn_mode(sel);
2531 ir_node *flags = NULL;
2535 if (sel_mode != mode_b) {
2536 return create_Switch(node);
2539 /* we get flags from a Cmp */
2540 flags = get_flags_node(sel, &pnc);
2542 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2543 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2548 static ir_node *gen_be_Copy(ir_node *node)
2550 ir_node *new_node = be_duplicate_node(node);
2551 ir_mode *mode = get_irn_mode(new_node);
2553 if (ia32_mode_needs_gp_reg(mode)) {
2554 set_irn_mode(new_node, mode_Iu);
2560 static ir_node *create_Fucom(ir_node *node)
2562 ir_graph *irg = current_ir_graph;
2563 dbg_info *dbgi = get_irn_dbg_info(node);
2564 ir_node *block = get_nodes_block(node);
2565 ir_node *new_block = be_transform_node(block);
2566 ir_node *left = get_Cmp_left(node);
2567 ir_node *new_left = be_transform_node(left);
2568 ir_node *right = get_Cmp_right(node);
2572 if (ia32_cg_config.use_fucomi) {
2573 new_right = be_transform_node(right);
2574 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2576 set_ia32_commutative(new_node);
2577 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2579 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2580 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2583 new_right = be_transform_node(right);
2584 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2588 set_ia32_commutative(new_node);
2590 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2592 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2593 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2599 static ir_node *create_Ucomi(ir_node *node)
2601 ir_graph *irg = current_ir_graph;
2602 dbg_info *dbgi = get_irn_dbg_info(node);
2603 ir_node *src_block = get_nodes_block(node);
2604 ir_node *new_block = be_transform_node(src_block);
2605 ir_node *left = get_Cmp_left(node);
2606 ir_node *right = get_Cmp_right(node);
2608 ia32_address_mode_t am;
2609 ia32_address_t *addr = &am.addr;
2611 match_arguments(&am, src_block, left, right, NULL,
2612 match_commutative | match_am);
2614 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2615 addr->mem, am.new_op1, am.new_op2,
2617 set_am_attributes(new_node, &am);
2619 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2621 new_node = fix_mem_proj(new_node, &am);
2627 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2628 * to fold an and into a test node
2630 static bool can_fold_test_and(ir_node *node)
2632 const ir_edge_t *edge;
2634 /** we can only have eq and lg projs */
2635 foreach_out_edge(node, edge) {
2636 ir_node *proj = get_edge_src_irn(edge);
2637 pn_Cmp pnc = get_Proj_proj(proj);
2638 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2646 * returns true if it is assured, that the upper bits of a node are "clean"
2647 * which means for a 16 or 8 bit value, that the upper bits in the register
2648 * are 0 for unsigned and a copy of the last significant bit for signed
2651 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2653 assert(ia32_mode_needs_gp_reg(mode));
2654 if (get_mode_size_bits(mode) >= 32)
2657 if (is_Proj(transformed_node))
2658 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2660 if (is_ia32_Conv_I2I(transformed_node)
2661 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2662 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2663 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2665 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2671 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2672 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2673 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2674 const ia32_immediate_attr_t *attr
2675 = get_ia32_immediate_attr_const(right);
2676 if (attr->symconst == 0
2677 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2681 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2684 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2685 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2686 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2687 const ia32_immediate_attr_t *attr
2688 = get_ia32_immediate_attr_const(right);
2689 if (attr->symconst == 0
2690 && (unsigned) attr->offset
2691 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2698 /* TODO recurse on Or, Xor, ... if appropriate? */
2700 if (is_ia32_Immediate(transformed_node)
2701 || is_ia32_Const(transformed_node)) {
2702 const ia32_immediate_attr_t *attr
2703 = get_ia32_immediate_attr_const(transformed_node);
2704 if (mode_is_signed(mode)) {
2705 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2706 if (shifted == 0 || shifted == -1)
2709 unsigned long shifted = (unsigned long) attr->offset;
2710 shifted >>= get_mode_size_bits(mode);
2720 * Generate code for a Cmp.
2722 static ir_node *gen_Cmp(ir_node *node)
2724 ir_graph *irg = current_ir_graph;
2725 dbg_info *dbgi = get_irn_dbg_info(node);
2726 ir_node *block = get_nodes_block(node);
2727 ir_node *new_block = be_transform_node(block);
2728 ir_node *left = get_Cmp_left(node);
2729 ir_node *right = get_Cmp_right(node);
2730 ir_mode *cmp_mode = get_irn_mode(left);
2732 ia32_address_mode_t am;
2733 ia32_address_t *addr = &am.addr;
2736 if (mode_is_float(cmp_mode)) {
2737 if (ia32_cg_config.use_sse2) {
2738 return create_Ucomi(node);
2740 return create_Fucom(node);
2744 assert(ia32_mode_needs_gp_reg(cmp_mode));
2746 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2747 cmp_unsigned = !mode_is_signed(cmp_mode);
2748 if (is_Const_0(right) &&
2750 get_irn_n_edges(left) == 1 &&
2751 can_fold_test_and(node)) {
2752 /* Test(and_left, and_right) */
2753 ir_node *and_left = get_And_left(left);
2754 ir_node *and_right = get_And_right(left);
2756 /* matze: code here used mode instead of cmd_mode, I think it is always
2757 * the same as cmp_mode, but I leave this here to see if this is really
2760 assert(get_irn_mode(and_left) == cmp_mode);
2762 match_arguments(&am, block, and_left, and_right, NULL,
2764 match_am | match_8bit_am | match_16bit_am |
2765 match_am_and_immediates | match_immediate |
2766 match_8bit | match_16bit);
2768 /* use 32bit compare mode if possible since the opcode is smaller */
2769 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2770 upper_bits_clean(am.new_op2, cmp_mode)) {
2771 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2774 if (get_mode_size_bits(cmp_mode) == 8) {
2775 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2776 addr->index, addr->mem, am.new_op1,
2777 am.new_op2, am.ins_permuted,
2780 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2781 addr->index, addr->mem, am.new_op1,
2782 am.new_op2, am.ins_permuted,
2786 /* Cmp(left, right) */
2787 match_arguments(&am, block, left, right, NULL,
2788 match_commutative | match_am | match_8bit_am |
2789 match_16bit_am | match_am_and_immediates |
2790 match_immediate | match_8bit | match_16bit);
2791 /* use 32bit compare mode if possible since the opcode is smaller */
2792 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2793 upper_bits_clean(am.new_op2, cmp_mode)) {
2794 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2797 if (get_mode_size_bits(cmp_mode) == 8) {
2798 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2799 addr->index, addr->mem, am.new_op1,
2800 am.new_op2, am.ins_permuted,
2803 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2804 addr->index, addr->mem, am.new_op1,
2805 am.new_op2, am.ins_permuted, cmp_unsigned);
2808 set_am_attributes(new_node, &am);
2809 set_ia32_ls_mode(new_node, cmp_mode);
2811 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2813 new_node = fix_mem_proj(new_node, &am);
2818 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2821 ir_graph *irg = current_ir_graph;
2822 dbg_info *dbgi = get_irn_dbg_info(node);
2823 ir_node *block = get_nodes_block(node);
2824 ir_node *new_block = be_transform_node(block);
2825 ir_node *val_true = get_Mux_true(node);
2826 ir_node *val_false = get_Mux_false(node);
2828 match_flags_t match_flags;
2829 ia32_address_mode_t am;
2830 ia32_address_t *addr;
2832 assert(ia32_cg_config.use_cmov);
2833 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2837 match_flags = match_commutative | match_am | match_16bit_am |
2840 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2842 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2843 addr->mem, am.new_op1, am.new_op2, new_flags,
2844 am.ins_permuted, pnc);
2845 set_am_attributes(new_node, &am);
2847 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2849 new_node = fix_mem_proj(new_node, &am);
2855 * Creates a ia32 Setcc instruction.
2857 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2858 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2861 ir_graph *irg = current_ir_graph;
2862 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2863 ir_node *nomem = new_NoMem();
2864 ir_mode *mode = get_irn_mode(orig_node);
2867 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2868 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2870 /* we might need to conv the result up */
2871 if (get_mode_size_bits(mode) > 8) {
2872 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2873 nomem, new_node, mode_Bu);
2874 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2881 * Create instruction for an unsigned Difference or Zero.
2883 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2885 ir_graph *irg = current_ir_graph;
2886 ir_mode *mode = get_irn_mode(psi);
2887 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2890 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2891 match_mode_neutral | match_am | match_immediate | match_two_users);
2893 block = get_nodes_block(new_node);
2895 if (is_Proj(new_node)) {
2896 sub = get_Proj_pred(new_node);
2897 assert(is_ia32_Sub(sub));
2900 set_irn_mode(sub, mode_T);
2901 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2903 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2905 dbgi = get_irn_dbg_info(psi);
2906 noreg = ia32_new_NoReg_gp(env_cg);
2907 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2908 nomem = new_NoMem();
2909 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2911 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2912 set_ia32_commutative(new_node);
2917 * Transforms a Mux node into CMov.
2919 * @return The transformed node.
2921 static ir_node *gen_Mux(ir_node *node)
2923 dbg_info *dbgi = get_irn_dbg_info(node);
2924 ir_node *block = get_nodes_block(node);
2925 ir_node *new_block = be_transform_node(block);
2926 ir_node *mux_true = get_Mux_true(node);
2927 ir_node *mux_false = get_Mux_false(node);
2928 ir_node *cond = get_Mux_sel(node);
2929 ir_mode *mode = get_irn_mode(node);
2932 assert(get_irn_mode(cond) == mode_b);
2934 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2935 if (mode_is_float(mode)) {
2936 ir_node *cmp = get_Proj_pred(cond);
2937 ir_node *cmp_left = get_Cmp_left(cmp);
2938 ir_node *cmp_right = get_Cmp_right(cmp);
2939 pn_Cmp pnc = get_Proj_proj(cond);
2941 if (ia32_cg_config.use_sse2) {
2942 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2943 if (cmp_left == mux_true && cmp_right == mux_false) {
2944 /* Mux(a <= b, a, b) => MIN */
2945 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2946 match_commutative | match_am | match_two_users);
2947 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2948 /* Mux(a <= b, b, a) => MAX */
2949 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2950 match_commutative | match_am | match_two_users);
2952 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2953 if (cmp_left == mux_true && cmp_right == mux_false) {
2954 /* Mux(a >= b, a, b) => MAX */
2955 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2956 match_commutative | match_am | match_two_users);
2957 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2958 /* Mux(a >= b, b, a) => MIN */
2959 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2960 match_commutative | match_am | match_two_users);
2964 panic("cannot transform floating point Mux");
2970 assert(ia32_mode_needs_gp_reg(mode));
2972 if (is_Proj(cond)) {
2973 ir_node *cmp = get_Proj_pred(cond);
2975 ir_node *cmp_left = get_Cmp_left(cmp);
2976 ir_node *cmp_right = get_Cmp_right(cmp);
2977 pn_Cmp pnc = get_Proj_proj(cond);
2979 /* check for unsigned Doz first */
2980 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2981 is_Const_0(mux_false) && is_Sub(mux_true) &&
2982 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2983 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2984 return create_Doz(node, cmp_left, cmp_right);
2985 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2986 is_Const_0(mux_true) && is_Sub(mux_false) &&
2987 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2988 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2989 return create_Doz(node, cmp_left, cmp_right);
2994 flags = get_flags_node(cond, &pnc);
2996 if (is_Const(mux_true) && is_Const(mux_false)) {
2997 /* both are const, good */
2998 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2999 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3000 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3001 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3003 /* Not that simple. */
3008 new_node = create_CMov(node, cond, flags, pnc);
3016 * Create a conversion from x87 state register to general purpose.
3018 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3020 ir_node *block = be_transform_node(get_nodes_block(node));
3021 ir_node *op = get_Conv_op(node);
3022 ir_node *new_op = be_transform_node(op);
3023 ia32_code_gen_t *cg = env_cg;
3024 ir_graph *irg = current_ir_graph;
3025 dbg_info *dbgi = get_irn_dbg_info(node);
3026 ir_node *noreg = ia32_new_NoReg_gp(cg);
3027 ir_mode *mode = get_irn_mode(node);
3028 ir_node *fist, *load, *mem;
3030 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3031 set_irn_pinned(fist, op_pin_state_floats);
3032 set_ia32_use_frame(fist);
3033 set_ia32_op_type(fist, ia32_AddrModeD);
3035 assert(get_mode_size_bits(mode) <= 32);
3036 /* exception we can only store signed 32 bit integers, so for unsigned
3037 we store a 64bit (signed) integer and load the lower bits */
3038 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3039 set_ia32_ls_mode(fist, mode_Ls);
3041 set_ia32_ls_mode(fist, mode_Is);
3043 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3046 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3048 set_irn_pinned(load, op_pin_state_floats);
3049 set_ia32_use_frame(load);
3050 set_ia32_op_type(load, ia32_AddrModeS);
3051 set_ia32_ls_mode(load, mode_Is);
3052 if (get_ia32_ls_mode(fist) == mode_Ls) {
3053 ia32_attr_t *attr = get_ia32_attr(load);
3054 attr->data.need_64bit_stackent = 1;
3056 ia32_attr_t *attr = get_ia32_attr(load);
3057 attr->data.need_32bit_stackent = 1;
3059 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3061 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3065 * Creates a x87 strict Conv by placing a Store and a Load
3067 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3069 ir_node *block = get_nodes_block(node);
3070 ir_graph *irg = current_ir_graph;
3071 dbg_info *dbgi = get_irn_dbg_info(node);
3072 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3073 ir_node *nomem = new_NoMem();
3074 ir_node *frame = get_irg_frame(irg);
3075 ir_node *store, *load;
3078 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3080 set_ia32_use_frame(store);
3081 set_ia32_op_type(store, ia32_AddrModeD);
3082 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3084 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3086 set_ia32_use_frame(load);
3087 set_ia32_op_type(load, ia32_AddrModeS);
3088 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3090 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3095 * Create a conversion from general purpose to x87 register
3097 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3099 ir_node *src_block = get_nodes_block(node);
3100 ir_node *block = be_transform_node(src_block);
3101 ir_graph *irg = current_ir_graph;
3102 dbg_info *dbgi = get_irn_dbg_info(node);
3103 ir_node *op = get_Conv_op(node);
3104 ir_node *new_op = NULL;
3108 ir_mode *store_mode;
3114 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3115 if (src_mode == mode_Is || src_mode == mode_Hs) {
3116 ia32_address_mode_t am;
3118 match_arguments(&am, src_block, NULL, op, NULL,
3119 match_am | match_try_am | match_16bit | match_16bit_am);
3120 if (am.op_type == ia32_AddrModeS) {
3121 ia32_address_t *addr = &am.addr;
3123 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3124 addr->index, addr->mem);
3125 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3128 set_am_attributes(fild, &am);
3129 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3131 fix_mem_proj(fild, &am);
3136 if (new_op == NULL) {
3137 new_op = be_transform_node(op);
3140 noreg = ia32_new_NoReg_gp(env_cg);
3141 nomem = new_NoMem();
3142 mode = get_irn_mode(op);
3144 /* first convert to 32 bit signed if necessary */
3145 src_bits = get_mode_size_bits(src_mode);
3146 if (src_bits == 8) {
3147 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3149 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3151 } else if (src_bits < 32) {
3152 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3154 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3158 assert(get_mode_size_bits(mode) == 32);
3161 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3164 set_ia32_use_frame(store);
3165 set_ia32_op_type(store, ia32_AddrModeD);
3166 set_ia32_ls_mode(store, mode_Iu);
3168 /* exception for 32bit unsigned, do a 64bit spill+load */
3169 if (!mode_is_signed(mode)) {
3172 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3174 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3175 get_irg_frame(irg), noreg, nomem,
3178 set_ia32_use_frame(zero_store);
3179 set_ia32_op_type(zero_store, ia32_AddrModeD);
3180 add_ia32_am_offs_int(zero_store, 4);
3181 set_ia32_ls_mode(zero_store, mode_Iu);
3186 store = new_rd_Sync(dbgi, irg, block, 2, in);
3187 store_mode = mode_Ls;
3189 store_mode = mode_Is;
3193 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3195 set_ia32_use_frame(fild);
3196 set_ia32_op_type(fild, ia32_AddrModeS);
3197 set_ia32_ls_mode(fild, store_mode);
3199 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3205 * Create a conversion from one integer mode into another one
3207 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3208 dbg_info *dbgi, ir_node *block, ir_node *op,
3211 ir_graph *irg = current_ir_graph;
3212 int src_bits = get_mode_size_bits(src_mode);
3213 int tgt_bits = get_mode_size_bits(tgt_mode);
3214 ir_node *new_block = be_transform_node(block);
3216 ir_mode *smaller_mode;
3218 ia32_address_mode_t am;
3219 ia32_address_t *addr = &am.addr;
3222 if (src_bits < tgt_bits) {
3223 smaller_mode = src_mode;
3224 smaller_bits = src_bits;
3226 smaller_mode = tgt_mode;
3227 smaller_bits = tgt_bits;
3230 #ifdef DEBUG_libfirm
3232 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3237 match_arguments(&am, block, NULL, op, NULL,
3238 match_8bit | match_16bit |
3239 match_am | match_8bit_am | match_16bit_am);
3241 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3242 /* unnecessary conv. in theory it shouldn't have been AM */
3243 assert(is_ia32_NoReg_GP(addr->base));
3244 assert(is_ia32_NoReg_GP(addr->index));
3245 assert(is_NoMem(addr->mem));
3246 assert(am.addr.offset == 0);
3247 assert(am.addr.symconst_ent == NULL);
3251 if (smaller_bits == 8) {
3252 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3253 addr->index, addr->mem, am.new_op2,
3256 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3257 addr->index, addr->mem, am.new_op2,
3260 set_am_attributes(new_node, &am);
3261 /* match_arguments assume that out-mode = in-mode, this isn't true here
3263 set_ia32_ls_mode(new_node, smaller_mode);
3264 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3265 new_node = fix_mem_proj(new_node, &am);
3270 * Transforms a Conv node.
3272 * @return The created ia32 Conv node
3274 static ir_node *gen_Conv(ir_node *node)
3276 ir_node *block = get_nodes_block(node);
3277 ir_node *new_block = be_transform_node(block);
3278 ir_node *op = get_Conv_op(node);
3279 ir_node *new_op = NULL;
3280 ir_graph *irg = current_ir_graph;
3281 dbg_info *dbgi = get_irn_dbg_info(node);
3282 ir_mode *src_mode = get_irn_mode(op);
3283 ir_mode *tgt_mode = get_irn_mode(node);
3284 int src_bits = get_mode_size_bits(src_mode);
3285 int tgt_bits = get_mode_size_bits(tgt_mode);
3286 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3287 ir_node *nomem = new_rd_NoMem(irg);
3288 ir_node *res = NULL;
3290 if (src_mode == mode_b) {
3291 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3292 /* nothing to do, we already model bools as 0/1 ints */
3293 return be_transform_node(op);
3296 if (src_mode == tgt_mode) {
3297 if (get_Conv_strict(node)) {
3298 if (ia32_cg_config.use_sse2) {
3299 /* when we are in SSE mode, we can kill all strict no-op conversion */
3300 return be_transform_node(op);
3303 /* this should be optimized already, but who knows... */
3304 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3305 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3306 return be_transform_node(op);
3310 if (mode_is_float(src_mode)) {
3311 new_op = be_transform_node(op);
3312 /* we convert from float ... */
3313 if (mode_is_float(tgt_mode)) {
3314 if (src_mode == mode_E && tgt_mode == mode_D
3315 && !get_Conv_strict(node)) {
3316 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3321 if (ia32_cg_config.use_sse2) {
3322 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3323 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3325 set_ia32_ls_mode(res, tgt_mode);
3327 if (get_Conv_strict(node)) {
3328 res = gen_x87_strict_conv(tgt_mode, new_op);
3329 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3332 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3337 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3338 if (ia32_cg_config.use_sse2) {
3339 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3341 set_ia32_ls_mode(res, src_mode);
3343 return gen_x87_fp_to_gp(node);
3347 /* we convert from int ... */
3348 if (mode_is_float(tgt_mode)) {
3350 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3351 if (ia32_cg_config.use_sse2) {
3352 new_op = be_transform_node(op);
3353 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3355 set_ia32_ls_mode(res, tgt_mode);
3357 res = gen_x87_gp_to_fp(node, src_mode);
3358 if (get_Conv_strict(node)) {
3359 /* The strict-Conv is only necessary, if the int mode has more bits
3360 * than the float mantissa */
3361 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3362 size_t float_mantissa;
3363 /* FIXME There is no way to get the mantissa size of a mode */
3364 switch (get_mode_size_bits(tgt_mode)) {
3365 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3366 case 64: float_mantissa = 52 + 1; break;
3368 case 96: float_mantissa = 64; break;
3369 default: float_mantissa = 0; break;
3371 if (float_mantissa < int_mantissa) {
3372 res = gen_x87_strict_conv(tgt_mode, res);
3373 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3378 } else if (tgt_mode == mode_b) {
3379 /* mode_b lowering already took care that we only have 0/1 values */
3380 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3381 src_mode, tgt_mode));
3382 return be_transform_node(op);
3385 if (src_bits == tgt_bits) {
3386 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3387 src_mode, tgt_mode));
3388 return be_transform_node(op);
3391 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3399 static ir_node *create_immediate_or_transform(ir_node *node,
3400 char immediate_constraint_type)
3402 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3403 if (new_node == NULL) {
3404 new_node = be_transform_node(node);
3410 * Transforms a FrameAddr into an ia32 Add.
3412 static ir_node *gen_be_FrameAddr(ir_node *node)
3414 ir_node *block = be_transform_node(get_nodes_block(node));
3415 ir_node *op = be_get_FrameAddr_frame(node);
3416 ir_node *new_op = be_transform_node(op);
3417 ir_graph *irg = current_ir_graph;
3418 dbg_info *dbgi = get_irn_dbg_info(node);
3419 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3422 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3423 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3424 set_ia32_use_frame(new_node);
3426 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3432 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3434 static ir_node *gen_be_Return(ir_node *node)
3436 ir_graph *irg = current_ir_graph;
3437 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3438 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3439 ir_entity *ent = get_irg_entity(irg);
3440 ir_type *tp = get_entity_type(ent);
3445 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3446 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3449 int pn_ret_val, pn_ret_mem, arity, i;
3451 assert(ret_val != NULL);
3452 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3453 return be_duplicate_node(node);
3456 res_type = get_method_res_type(tp, 0);
3458 if (! is_Primitive_type(res_type)) {
3459 return be_duplicate_node(node);
3462 mode = get_type_mode(res_type);
3463 if (! mode_is_float(mode)) {
3464 return be_duplicate_node(node);
3467 assert(get_method_n_ress(tp) == 1);
3469 pn_ret_val = get_Proj_proj(ret_val);
3470 pn_ret_mem = get_Proj_proj(ret_mem);
3472 /* get the Barrier */
3473 barrier = get_Proj_pred(ret_val);
3475 /* get result input of the Barrier */
3476 ret_val = get_irn_n(barrier, pn_ret_val);
3477 new_ret_val = be_transform_node(ret_val);
3479 /* get memory input of the Barrier */
3480 ret_mem = get_irn_n(barrier, pn_ret_mem);
3481 new_ret_mem = be_transform_node(ret_mem);
3483 frame = get_irg_frame(irg);
3485 dbgi = get_irn_dbg_info(barrier);
3486 block = be_transform_node(get_nodes_block(barrier));
3488 noreg = ia32_new_NoReg_gp(env_cg);
3490 /* store xmm0 onto stack */
3491 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3492 new_ret_mem, new_ret_val);
3493 set_ia32_ls_mode(sse_store, mode);
3494 set_ia32_op_type(sse_store, ia32_AddrModeD);
3495 set_ia32_use_frame(sse_store);
3497 /* load into x87 register */
3498 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3499 set_ia32_op_type(fld, ia32_AddrModeS);
3500 set_ia32_use_frame(fld);
3502 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3503 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3505 /* create a new barrier */
3506 arity = get_irn_arity(barrier);
3507 in = alloca(arity * sizeof(in[0]));
3508 for (i = 0; i < arity; ++i) {
3511 if (i == pn_ret_val) {
3513 } else if (i == pn_ret_mem) {
3516 ir_node *in = get_irn_n(barrier, i);
3517 new_in = be_transform_node(in);
3522 new_barrier = new_ir_node(dbgi, irg, block,
3523 get_irn_op(barrier), get_irn_mode(barrier),
3525 copy_node_attr(barrier, new_barrier);
3526 be_duplicate_deps(barrier, new_barrier);
3527 be_set_transformed_node(barrier, new_barrier);
3529 /* transform normally */
3530 return be_duplicate_node(node);
3534 * Transform a be_AddSP into an ia32_SubSP.
3536 static ir_node *gen_be_AddSP(ir_node *node)
3538 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3539 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3541 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3542 match_am | match_immediate);
3546 * Transform a be_SubSP into an ia32_AddSP
3548 static ir_node *gen_be_SubSP(ir_node *node)
3550 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3551 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3553 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3554 match_am | match_immediate);
3558 * Change some phi modes
3560 static ir_node *gen_Phi(ir_node *node)
3562 ir_node *block = be_transform_node(get_nodes_block(node));
3563 ir_graph *irg = current_ir_graph;
3564 dbg_info *dbgi = get_irn_dbg_info(node);
3565 ir_mode *mode = get_irn_mode(node);
3568 if (ia32_mode_needs_gp_reg(mode)) {
3569 /* we shouldn't have any 64bit stuff around anymore */
3570 assert(get_mode_size_bits(mode) <= 32);
3571 /* all integer operations are on 32bit registers now */
3573 } else if (mode_is_float(mode)) {
3574 if (ia32_cg_config.use_sse2) {
3581 /* phi nodes allow loops, so we use the old arguments for now
3582 * and fix this later */
3583 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3584 get_irn_in(node) + 1);
3585 copy_node_attr(node, phi);
3586 be_duplicate_deps(node, phi);
3588 be_enqueue_preds(node);
3596 static ir_node *gen_IJmp(ir_node *node)
3598 ir_node *block = get_nodes_block(node);
3599 ir_node *new_block = be_transform_node(block);
3600 dbg_info *dbgi = get_irn_dbg_info(node);
3601 ir_node *op = get_IJmp_target(node);
3603 ia32_address_mode_t am;
3604 ia32_address_t *addr = &am.addr;
3606 assert(get_irn_mode(op) == mode_P);
3608 match_arguments(&am, block, NULL, op, NULL,
3609 match_am | match_8bit_am | match_16bit_am |
3610 match_immediate | match_8bit | match_16bit);
3612 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3613 addr->base, addr->index, addr->mem,
3615 set_am_attributes(new_node, &am);
3616 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3618 new_node = fix_mem_proj(new_node, &am);
3624 * Transform a Bound node.
3626 static ir_node *gen_Bound(ir_node *node)
3629 ir_node *lower = get_Bound_lower(node);
3630 dbg_info *dbgi = get_irn_dbg_info(node);
3632 if (is_Const_0(lower)) {
3633 /* typical case for Java */
3634 ir_node *sub, *res, *flags, *block;
3635 ir_graph *irg = current_ir_graph;
3637 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3638 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3640 block = get_nodes_block(res);
3641 if (! is_Proj(res)) {
3643 set_irn_mode(sub, mode_T);
3644 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3646 sub = get_Proj_pred(res);
3648 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3649 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3650 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3652 panic("generic Bound not supported in ia32 Backend");
3658 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3660 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3661 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3663 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3664 match_immediate | match_mode_neutral);
3667 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3669 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3670 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3671 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3675 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3677 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3678 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3679 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3683 static ir_node *gen_ia32_l_Add(ir_node *node)
3685 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3686 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3687 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3688 match_commutative | match_am | match_immediate |
3689 match_mode_neutral);
3691 if (is_Proj(lowered)) {
3692 lowered = get_Proj_pred(lowered);
3694 assert(is_ia32_Add(lowered));
3695 set_irn_mode(lowered, mode_T);
3701 static ir_node *gen_ia32_l_Adc(ir_node *node)
3703 return gen_binop_flags(node, new_rd_ia32_Adc,
3704 match_commutative | match_am | match_immediate |
3705 match_mode_neutral);
3709 * Transforms a l_MulS into a "real" MulS node.
3711 * @return the created ia32 Mul node
3713 static ir_node *gen_ia32_l_Mul(ir_node *node)
3715 ir_node *left = get_binop_left(node);
3716 ir_node *right = get_binop_right(node);
3718 return gen_binop(node, left, right, new_rd_ia32_Mul,
3719 match_commutative | match_am | match_mode_neutral);
3723 * Transforms a l_IMulS into a "real" IMul1OPS node.
3725 * @return the created ia32 IMul1OP node
3727 static ir_node *gen_ia32_l_IMul(ir_node *node)
3729 ir_node *left = get_binop_left(node);
3730 ir_node *right = get_binop_right(node);
3732 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3733 match_commutative | match_am | match_mode_neutral);
3736 static ir_node *gen_ia32_l_Sub(ir_node *node)
3738 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3739 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3740 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3741 match_am | match_immediate | match_mode_neutral);
3743 if (is_Proj(lowered)) {
3744 lowered = get_Proj_pred(lowered);
3746 assert(is_ia32_Sub(lowered));
3747 set_irn_mode(lowered, mode_T);
3753 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3755 return gen_binop_flags(node, new_rd_ia32_Sbb,
3756 match_am | match_immediate | match_mode_neutral);
3760 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3761 * op1 - target to be shifted
3762 * op2 - contains bits to be shifted into target
3764 * Only op3 can be an immediate.
3766 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3767 ir_node *low, ir_node *count)
3769 ir_node *block = get_nodes_block(node);
3770 ir_node *new_block = be_transform_node(block);
3771 ir_graph *irg = current_ir_graph;
3772 dbg_info *dbgi = get_irn_dbg_info(node);
3773 ir_node *new_high = be_transform_node(high);
3774 ir_node *new_low = be_transform_node(low);
3778 /* the shift amount can be any mode that is bigger than 5 bits, since all
3779 * other bits are ignored anyway */
3780 while (is_Conv(count) &&
3781 get_irn_n_edges(count) == 1 &&
3782 mode_is_int(get_irn_mode(count))) {
3783 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3784 count = get_Conv_op(count);
3786 new_count = create_immediate_or_transform(count, 0);
3788 if (is_ia32_l_ShlD(node)) {
3789 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3792 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3795 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3800 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3802 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3803 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3804 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3805 return gen_lowered_64bit_shifts(node, high, low, count);
3808 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3810 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3811 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3812 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3813 return gen_lowered_64bit_shifts(node, high, low, count);
3816 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3818 ir_node *src_block = get_nodes_block(node);
3819 ir_node *block = be_transform_node(src_block);
3820 ir_graph *irg = current_ir_graph;
3821 dbg_info *dbgi = get_irn_dbg_info(node);
3822 ir_node *frame = get_irg_frame(irg);
3823 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3824 ir_node *nomem = new_NoMem();
3825 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3826 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3827 ir_node *new_val_low = be_transform_node(val_low);
3828 ir_node *new_val_high = be_transform_node(val_high);
3833 ir_node *store_high;
3835 if (!mode_is_signed(get_irn_mode(val_high))) {
3836 panic("unsigned long long -> float not supported yet (%+F)", node);
3840 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3842 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3844 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3845 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3847 set_ia32_use_frame(store_low);
3848 set_ia32_use_frame(store_high);
3849 set_ia32_op_type(store_low, ia32_AddrModeD);
3850 set_ia32_op_type(store_high, ia32_AddrModeD);
3851 set_ia32_ls_mode(store_low, mode_Iu);
3852 set_ia32_ls_mode(store_high, mode_Is);
3853 add_ia32_am_offs_int(store_high, 4);
3857 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3860 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3862 set_ia32_use_frame(fild);
3863 set_ia32_op_type(fild, ia32_AddrModeS);
3864 set_ia32_ls_mode(fild, mode_Ls);
3866 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3868 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3871 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3873 ir_node *src_block = get_nodes_block(node);
3874 ir_node *block = be_transform_node(src_block);
3875 ir_graph *irg = current_ir_graph;
3876 dbg_info *dbgi = get_irn_dbg_info(node);
3877 ir_node *frame = get_irg_frame(irg);
3878 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3879 ir_node *nomem = new_NoMem();
3880 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3881 ir_node *new_val = be_transform_node(val);
3882 ir_node *fist, *mem;
3884 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3885 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3886 set_ia32_use_frame(fist);
3887 set_ia32_op_type(fist, ia32_AddrModeD);
3888 set_ia32_ls_mode(fist, mode_Ls);
3894 * the BAD transformer.
3896 static ir_node *bad_transform(ir_node *node)
3898 panic("No transform function for %+F available.", node);
3902 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3904 ir_graph *irg = current_ir_graph;
3905 ir_node *block = be_transform_node(get_nodes_block(node));
3906 ir_node *pred = get_Proj_pred(node);
3907 ir_node *new_pred = be_transform_node(pred);
3908 ir_node *frame = get_irg_frame(irg);
3909 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3910 dbg_info *dbgi = get_irn_dbg_info(node);
3911 long pn = get_Proj_proj(node);
3916 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3917 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3918 set_ia32_use_frame(load);
3919 set_ia32_op_type(load, ia32_AddrModeS);
3920 set_ia32_ls_mode(load, mode_Iu);
3921 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3922 * 32 bit from it with this particular load */
3923 attr = get_ia32_attr(load);
3924 attr->data.need_64bit_stackent = 1;
3926 if (pn == pn_ia32_l_FloattoLL_res_high) {
3927 add_ia32_am_offs_int(load, 4);
3929 assert(pn == pn_ia32_l_FloattoLL_res_low);
3932 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3938 * Transform the Projs of an AddSP.
3940 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3942 ir_node *block = be_transform_node(get_nodes_block(node));
3943 ir_node *pred = get_Proj_pred(node);
3944 ir_node *new_pred = be_transform_node(pred);
3945 ir_graph *irg = current_ir_graph;
3946 dbg_info *dbgi = get_irn_dbg_info(node);
3947 long proj = get_Proj_proj(node);
3949 if (proj == pn_be_AddSP_sp) {
3950 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3951 pn_ia32_SubSP_stack);
3952 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3954 } else if (proj == pn_be_AddSP_res) {
3955 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3956 pn_ia32_SubSP_addr);
3957 } else if (proj == pn_be_AddSP_M) {
3958 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3961 panic("No idea how to transform proj->AddSP");
3965 * Transform the Projs of a SubSP.
3967 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3969 ir_node *block = be_transform_node(get_nodes_block(node));
3970 ir_node *pred = get_Proj_pred(node);
3971 ir_node *new_pred = be_transform_node(pred);
3972 ir_graph *irg = current_ir_graph;
3973 dbg_info *dbgi = get_irn_dbg_info(node);
3974 long proj = get_Proj_proj(node);
3976 if (proj == pn_be_SubSP_sp) {
3977 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3978 pn_ia32_AddSP_stack);
3979 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3981 } else if (proj == pn_be_SubSP_M) {
3982 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3985 panic("No idea how to transform proj->SubSP");
3989 * Transform and renumber the Projs from a Load.
3991 static ir_node *gen_Proj_Load(ir_node *node)
3994 ir_node *block = be_transform_node(get_nodes_block(node));
3995 ir_node *pred = get_Proj_pred(node);
3996 ir_graph *irg = current_ir_graph;
3997 dbg_info *dbgi = get_irn_dbg_info(node);
3998 long proj = get_Proj_proj(node);
4000 /* loads might be part of source address mode matches, so we don't
4001 * transform the ProjMs yet (with the exception of loads whose result is
4004 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4007 /* this is needed, because sometimes we have loops that are only
4008 reachable through the ProjM */
4009 be_enqueue_preds(node);
4010 /* do it in 2 steps, to silence firm verifier */
4011 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4012 set_Proj_proj(res, pn_ia32_mem);
4016 /* renumber the proj */
4017 new_pred = be_transform_node(pred);
4018 if (is_ia32_Load(new_pred)) {
4021 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4023 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4024 case pn_Load_X_regular:
4025 return new_rd_Jmp(dbgi, irg, block);
4026 case pn_Load_X_except:
4027 /* This Load might raise an exception. Mark it. */
4028 set_ia32_exc_label(new_pred, 1);
4029 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4033 } else if (is_ia32_Conv_I2I(new_pred) ||
4034 is_ia32_Conv_I2I8Bit(new_pred)) {
4035 set_irn_mode(new_pred, mode_T);
4036 if (proj == pn_Load_res) {
4037 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4038 } else if (proj == pn_Load_M) {
4039 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4041 } else if (is_ia32_xLoad(new_pred)) {
4044 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4046 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4047 case pn_Load_X_regular:
4048 return new_rd_Jmp(dbgi, irg, block);
4049 case pn_Load_X_except:
4050 /* This Load might raise an exception. Mark it. */
4051 set_ia32_exc_label(new_pred, 1);
4052 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4056 } else if (is_ia32_vfld(new_pred)) {
4059 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4061 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4062 case pn_Load_X_regular:
4063 return new_rd_Jmp(dbgi, irg, block);
4064 case pn_Load_X_except:
4065 /* This Load might raise an exception. Mark it. */
4066 set_ia32_exc_label(new_pred, 1);
4067 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4072 /* can happen for ProJMs when source address mode happened for the
4075 /* however it should not be the result proj, as that would mean the
4076 load had multiple users and should not have been used for
4078 if (proj != pn_Load_M) {
4079 panic("internal error: transformed node not a Load");
4081 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4084 panic("No idea how to transform proj");
4088 * Transform and renumber the Projs from a DivMod like instruction.
4090 static ir_node *gen_Proj_DivMod(ir_node *node)
4092 ir_node *block = be_transform_node(get_nodes_block(node));
4093 ir_node *pred = get_Proj_pred(node);
4094 ir_node *new_pred = be_transform_node(pred);
4095 ir_graph *irg = current_ir_graph;
4096 dbg_info *dbgi = get_irn_dbg_info(node);
4097 long proj = get_Proj_proj(node);
4099 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4101 switch (get_irn_opcode(pred)) {
4105 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4107 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4108 case pn_Div_X_regular:
4109 return new_rd_Jmp(dbgi, irg, block);
4110 case pn_Div_X_except:
4111 set_ia32_exc_label(new_pred, 1);
4112 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4120 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4122 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4123 case pn_Mod_X_except:
4124 set_ia32_exc_label(new_pred, 1);
4125 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4133 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4134 case pn_DivMod_res_div:
4135 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4136 case pn_DivMod_res_mod:
4137 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4138 case pn_DivMod_X_regular:
4139 return new_rd_Jmp(dbgi, irg, block);
4140 case pn_DivMod_X_except:
4141 set_ia32_exc_label(new_pred, 1);
4142 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4151 panic("No idea how to transform proj->DivMod");
4155 * Transform and renumber the Projs from a CopyB.
4157 static ir_node *gen_Proj_CopyB(ir_node *node)
4159 ir_node *block = be_transform_node(get_nodes_block(node));
4160 ir_node *pred = get_Proj_pred(node);
4161 ir_node *new_pred = be_transform_node(pred);
4162 ir_graph *irg = current_ir_graph;
4163 dbg_info *dbgi = get_irn_dbg_info(node);
4164 long proj = get_Proj_proj(node);
4167 case pn_CopyB_M_regular:
4168 if (is_ia32_CopyB_i(new_pred)) {
4169 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4170 } else if (is_ia32_CopyB(new_pred)) {
4171 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4178 panic("No idea how to transform proj->CopyB");
4182 * Transform and renumber the Projs from a Quot.
4184 static ir_node *gen_Proj_Quot(ir_node *node)
4186 ir_node *block = be_transform_node(get_nodes_block(node));
4187 ir_node *pred = get_Proj_pred(node);
4188 ir_node *new_pred = be_transform_node(pred);
4189 ir_graph *irg = current_ir_graph;
4190 dbg_info *dbgi = get_irn_dbg_info(node);
4191 long proj = get_Proj_proj(node);
4195 if (is_ia32_xDiv(new_pred)) {
4196 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4197 } else if (is_ia32_vfdiv(new_pred)) {
4198 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4202 if (is_ia32_xDiv(new_pred)) {
4203 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4204 } else if (is_ia32_vfdiv(new_pred)) {
4205 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4208 case pn_Quot_X_regular:
4209 case pn_Quot_X_except:
4214 panic("No idea how to transform proj->Quot");
4217 static ir_node *gen_be_Call(ir_node *node)
4219 dbg_info *const dbgi = get_irn_dbg_info(node);
4220 ir_graph *const irg = current_ir_graph;
4221 ir_node *const src_block = get_nodes_block(node);
4222 ir_node *const block = be_transform_node(src_block);
4223 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4224 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4225 ir_node *const sp = be_transform_node(src_sp);
4226 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4227 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4228 ia32_address_mode_t am;
4229 ia32_address_t *const addr = &am.addr;
4234 ir_node * eax = noreg;
4235 ir_node * ecx = noreg;
4236 ir_node * edx = noreg;
4237 unsigned const pop = be_Call_get_pop(node);
4238 ir_type *const call_tp = be_Call_get_type(node);
4240 /* Run the x87 simulator if the call returns a float value */
4241 if (get_method_n_ress(call_tp) > 0) {
4242 ir_type *const res_type = get_method_res_type(call_tp, 0);
4243 ir_mode *const res_mode = get_type_mode(res_type);
4245 if (res_mode != NULL && mode_is_float(res_mode)) {
4246 env_cg->do_x87_sim = 1;
4250 /* We do not want be_Call direct calls */
4251 assert(be_Call_get_entity(node) == NULL);
4253 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4254 match_am | match_immediate);
4256 i = get_irn_arity(node) - 1;
4257 fpcw = be_transform_node(get_irn_n(node, i--));
4258 for (; i >= be_pos_Call_first_arg; --i) {
4259 arch_register_req_t const *const req = arch_get_register_req(node, i);
4260 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4262 assert(req->type == arch_register_req_type_limited);
4263 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4265 switch (*req->limited) {
4266 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4267 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4268 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4269 default: panic("Invalid GP register for register parameter");
4273 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4274 call = new_rd_ia32_Call(dbgi, irg, block, addr->base, addr->index, mem,
4275 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4276 set_am_attributes(call, &am);
4277 call = fix_mem_proj(call, &am);
4279 if (get_irn_pinned(node) == op_pin_state_pinned)
4280 set_irn_pinned(call, op_pin_state_pinned);
4282 SET_IA32_ORIG_NODE(call, ia32_get_old_node_name(env_cg, node));
4286 static ir_node *gen_be_IncSP(ir_node *node)
4288 ir_node *res = be_duplicate_node(node);
4289 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4295 * Transform the Projs from a be_Call.
4297 static ir_node *gen_Proj_be_Call(ir_node *node)
4299 ir_node *block = be_transform_node(get_nodes_block(node));
4300 ir_node *call = get_Proj_pred(node);
4301 ir_node *new_call = be_transform_node(call);
4302 ir_graph *irg = current_ir_graph;
4303 dbg_info *dbgi = get_irn_dbg_info(node);
4304 ir_type *method_type = be_Call_get_type(call);
4305 int n_res = get_method_n_ress(method_type);
4306 long proj = get_Proj_proj(node);
4307 ir_mode *mode = get_irn_mode(node);
4311 /* The following is kinda tricky: If we're using SSE, then we have to
4312 * move the result value of the call in floating point registers to an
4313 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4314 * after the call, we have to make sure to correctly make the
4315 * MemProj and the result Proj use these 2 nodes
4317 if (proj == pn_be_Call_M_regular) {
4318 // get new node for result, are we doing the sse load/store hack?
4319 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4320 ir_node *call_res_new;
4321 ir_node *call_res_pred = NULL;
4323 if (call_res != NULL) {
4324 call_res_new = be_transform_node(call_res);
4325 call_res_pred = get_Proj_pred(call_res_new);
4328 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4329 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4332 assert(is_ia32_xLoad(call_res_pred));
4333 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4337 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4338 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4340 ir_node *frame = get_irg_frame(irg);
4341 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4343 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4346 /* in case there is no memory output: create one to serialize the copy
4348 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4349 pn_be_Call_M_regular);
4350 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4351 pn_be_Call_first_res);
4353 /* store st(0) onto stack */
4354 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4356 set_ia32_op_type(fstp, ia32_AddrModeD);
4357 set_ia32_use_frame(fstp);
4359 /* load into SSE register */
4360 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4362 set_ia32_op_type(sse_load, ia32_AddrModeS);
4363 set_ia32_use_frame(sse_load);
4365 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4371 /* transform call modes */
4372 if (mode_is_data(mode)) {
4373 const arch_register_class_t *cls = arch_get_irn_reg_class(node, -1);
4377 /* Map from be_Call to ia32_Call proj number */
4378 if (proj == pn_be_Call_sp) {
4379 proj = pn_ia32_Call_stack;
4380 } else if (proj == pn_be_Call_M_regular) {
4381 proj = pn_ia32_Call_M;
4383 arch_register_req_t const *const req = arch_get_register_req(node, BE_OUT_POS(proj));
4384 int const n_outs = get_ia32_n_res(new_call);
4387 assert(proj >= pn_be_Call_first_res);
4388 assert(req->type == arch_register_req_type_limited);
4390 for (i = 0; i < n_outs; ++i) {
4391 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4393 if (new_req->type != arch_register_req_type_limited ||
4394 new_req->cls != req->cls ||
4395 *new_req->limited != *req->limited)
4404 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4406 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4408 case pn_ia32_Call_stack:
4409 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4412 case pn_ia32_Call_fpcw:
4413 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4421 * Transform the Projs from a Cmp.
4423 static ir_node *gen_Proj_Cmp(ir_node *node)
4425 /* this probably means not all mode_b nodes were lowered... */
4426 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4431 * Transform the Projs from a Bound.
4433 static ir_node *gen_Proj_Bound(ir_node *node)
4435 ir_node *new_node, *block;
4436 ir_node *pred = get_Proj_pred(node);
4438 switch (get_Proj_proj(node)) {
4440 return be_transform_node(get_Bound_mem(pred));
4441 case pn_Bound_X_regular:
4442 new_node = be_transform_node(pred);
4443 block = get_nodes_block(new_node);
4444 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4445 case pn_Bound_X_except:
4446 new_node = be_transform_node(pred);
4447 block = get_nodes_block(new_node);
4448 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4450 return be_transform_node(get_Bound_index(pred));
4452 panic("unsupported Proj from Bound");
4456 static ir_node *gen_Proj_ASM(ir_node *node)
4462 if (get_irn_mode(node) != mode_M)
4463 return be_duplicate_node(node);
4465 pred = get_Proj_pred(node);
4466 new_pred = be_transform_node(pred);
4467 block = get_nodes_block(new_pred);
4468 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4469 get_ia32_n_res(new_pred) + 1);
4473 * Transform and potentially renumber Proj nodes.
4475 static ir_node *gen_Proj(ir_node *node)
4477 ir_node *pred = get_Proj_pred(node);
4480 switch (get_irn_opcode(pred)) {
4482 proj = get_Proj_proj(node);
4483 if (proj == pn_Store_M) {
4484 return be_transform_node(pred);
4486 panic("No idea how to transform proj->Store");
4489 return gen_Proj_Load(node);
4491 return gen_Proj_ASM(node);
4495 return gen_Proj_DivMod(node);
4497 return gen_Proj_CopyB(node);
4499 return gen_Proj_Quot(node);
4501 return gen_Proj_be_SubSP(node);
4503 return gen_Proj_be_AddSP(node);
4505 return gen_Proj_be_Call(node);
4507 return gen_Proj_Cmp(node);
4509 return gen_Proj_Bound(node);
4511 proj = get_Proj_proj(node);
4513 case pn_Start_X_initial_exec: {
4514 ir_node *block = get_nodes_block(pred);
4515 ir_node *new_block = be_transform_node(block);
4516 dbg_info *dbgi = get_irn_dbg_info(node);
4517 /* we exchange the ProjX with a jump */
4518 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4523 case pn_Start_P_tls:
4524 return gen_Proj_tls(node);
4529 if (is_ia32_l_FloattoLL(pred)) {
4530 return gen_Proj_l_FloattoLL(node);
4532 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4536 ir_mode *mode = get_irn_mode(node);
4537 if (ia32_mode_needs_gp_reg(mode)) {
4538 ir_node *new_pred = be_transform_node(pred);
4539 ir_node *block = be_transform_node(get_nodes_block(node));
4540 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4541 mode_Iu, get_Proj_proj(node));
4542 #ifdef DEBUG_libfirm
4543 new_proj->node_nr = node->node_nr;
4549 return be_duplicate_node(node);
4553 * Enters all transform functions into the generic pointer
4555 static void register_transformers(void)
4559 /* first clear the generic function pointer for all ops */
4560 clear_irp_opcodes_generic_func();
4562 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4563 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4601 /* transform ops from intrinsic lowering */
4613 GEN(ia32_l_LLtoFloat);
4614 GEN(ia32_l_FloattoLL);
4620 /* we should never see these nodes */
4635 /* handle generic backend nodes */
4644 op_Mulh = get_op_Mulh();
4653 * Pre-transform all unknown and noreg nodes.
4655 static void ia32_pretransform_node(void)
4657 ia32_code_gen_t *cg = env_cg;
4659 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4660 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4661 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4662 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4663 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4664 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4669 * Walker, checks if all ia32 nodes producing more than one result have their
4670 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4672 static void add_missing_keep_walker(ir_node *node, void *data)
4675 unsigned found_projs = 0;
4676 const ir_edge_t *edge;
4677 ir_mode *mode = get_irn_mode(node);
4682 if (!is_ia32_irn(node))
4685 n_outs = get_ia32_n_res(node);
4688 if (is_ia32_SwitchJmp(node))
4691 assert(n_outs < (int) sizeof(unsigned) * 8);
4692 foreach_out_edge(node, edge) {
4693 ir_node *proj = get_edge_src_irn(edge);
4696 /* The node could be kept */
4700 if (get_irn_mode(proj) == mode_M)
4703 pn = get_Proj_proj(proj);
4704 assert(pn < n_outs);
4705 found_projs |= 1 << pn;
4709 /* are keeps missing? */
4711 for (i = 0; i < n_outs; ++i) {
4714 const arch_register_req_t *req;
4715 const arch_register_class_t *cls;
4717 if (found_projs & (1 << i)) {
4721 req = get_ia32_out_req(node, i);
4726 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4730 block = get_nodes_block(node);
4731 in[0] = new_r_Proj(current_ir_graph, block, node,
4732 arch_register_class_mode(cls), i);
4733 if (last_keep != NULL) {
4734 be_Keep_add_node(last_keep, cls, in[0]);
4736 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4737 if (sched_is_scheduled(node)) {
4738 sched_add_after(node, last_keep);
4745 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4748 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4750 ir_graph *irg = be_get_birg_irg(cg->birg);
4751 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4754 /* do the transformation */
4755 void ia32_transform_graph(ia32_code_gen_t *cg)
4759 register_transformers();
4761 initial_fpcw = NULL;
4763 BE_TIMER_PUSH(t_heights);
4764 heights = heights_new(cg->irg);
4765 BE_TIMER_POP(t_heights);
4766 ia32_calculate_non_address_mode_nodes(cg->birg);
4768 /* the transform phase is not safe for CSE (yet) because several nodes get
4769 * attributes set after their creation */
4770 cse_last = get_opt_cse();
4773 be_transform_graph(cg->birg, ia32_pretransform_node);
4775 set_opt_cse(cse_last);
4777 ia32_free_non_address_mode_nodes();
4778 heights_free(heights);
4782 void ia32_init_transform(void)
4784 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");