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
36 #include "irgraph_t.h"
41 #include "iredges_t.h"
54 #include "../benode_t.h"
55 #include "../besched.h"
57 #include "../beutil.h"
58 #include "../beirg_t.h"
59 #include "../betranshlp.h"
62 #include "bearch_ia32_t.h"
63 #include "ia32_common_transform.h"
64 #include "ia32_nodes_attr.h"
65 #include "ia32_transform.h"
66 #include "ia32_new_nodes.h"
67 #include "ia32_map_regs.h"
68 #include "ia32_dbg_stat.h"
69 #include "ia32_optimize.h"
70 #include "ia32_util.h"
71 #include "ia32_address_mode.h"
72 #include "ia32_architecture.h"
74 #include "gen_ia32_regalloc_if.h"
76 #define SFP_SIGN "0x80000000"
77 #define DFP_SIGN "0x8000000000000000"
78 #define SFP_ABS "0x7FFFFFFF"
79 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
80 #define DFP_INTMAX "9223372036854775807"
82 #define TP_SFP_SIGN "ia32_sfp_sign"
83 #define TP_DFP_SIGN "ia32_dfp_sign"
84 #define TP_SFP_ABS "ia32_sfp_abs"
85 #define TP_DFP_ABS "ia32_dfp_abs"
86 #define TP_INT_MAX "ia32_int_max"
88 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
89 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
90 #define ENT_SFP_ABS "IA32_SFP_ABS"
91 #define ENT_DFP_ABS "IA32_DFP_ABS"
92 #define ENT_INT_MAX "IA32_INT_MAX"
94 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
95 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
97 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
99 static ir_node *initial_fpcw = NULL;
101 extern ir_op *get_op_Mulh(void);
103 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
104 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
105 ir_node *op1, ir_node *op2);
107 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
108 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
109 ir_node *op1, ir_node *op2, ir_node *flags);
111 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
112 ir_node *block, ir_node *op1, ir_node *op2);
114 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
115 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
118 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
119 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
121 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
122 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
123 ir_node *op1, ir_node *op2, ir_node *fpcw);
125 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
126 ir_node *block, ir_node *op);
128 static ir_node *create_immediate_or_transform(ir_node *node,
129 char immediate_constraint_type);
131 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
132 dbg_info *dbgi, ir_node *block,
133 ir_node *op, ir_node *orig_node);
135 /** Return non-zero is a node represents the 0 constant. */
136 static bool is_Const_0(ir_node *node) {
137 return is_Const(node) && is_Const_null(node);
140 /** Return non-zero is a node represents the 1 constant. */
141 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) {
147 return is_Const(node) && is_Const_all_one(node);
151 * returns true if constant can be created with a simple float command
153 static bool is_simple_x87_Const(ir_node *node)
155 tarval *tv = get_Const_tarval(node);
156 if (tarval_is_null(tv) || tarval_is_one(tv))
159 /* TODO: match all the other float constants */
164 * returns true if constant can be created with a simple float command
166 static bool is_simple_sse_Const(ir_node *node)
168 tarval *tv = get_Const_tarval(node);
169 ir_mode *mode = get_tarval_mode(tv);
174 if (tarval_is_null(tv) || tarval_is_one(tv))
177 if (mode == mode_D) {
178 unsigned val = get_tarval_sub_bits(tv, 0) |
179 (get_tarval_sub_bits(tv, 1) << 8) |
180 (get_tarval_sub_bits(tv, 2) << 16) |
181 (get_tarval_sub_bits(tv, 3) << 24);
183 /* lower 32bit are zero, really a 32bit constant */
187 /* TODO: match all the other float constants */
192 * Transforms a Const.
194 static ir_node *gen_Const(ir_node *node) {
195 ir_graph *irg = current_ir_graph;
196 ir_node *old_block = get_nodes_block(node);
197 ir_node *block = be_transform_node(old_block);
198 dbg_info *dbgi = get_irn_dbg_info(node);
199 ir_mode *mode = get_irn_mode(node);
201 assert(is_Const(node));
203 if (mode_is_float(mode)) {
205 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
206 ir_node *nomem = new_NoMem();
210 if (ia32_cg_config.use_sse2) {
211 tarval *tv = get_Const_tarval(node);
212 if (tarval_is_null(tv)) {
213 load = new_rd_ia32_xZero(dbgi, irg, block);
214 set_ia32_ls_mode(load, mode);
216 } else if (tarval_is_one(tv)) {
217 int cnst = mode == mode_F ? 26 : 55;
218 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
219 ir_node *imm2 = create_Immediate(NULL, 0, 2);
220 ir_node *pslld, *psrld;
222 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
223 set_ia32_ls_mode(load, mode);
224 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
225 set_ia32_ls_mode(pslld, mode);
226 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
227 set_ia32_ls_mode(psrld, mode);
229 } else if (mode == mode_F) {
230 /* we can place any 32bit constant by using a movd gp, sse */
231 unsigned val = get_tarval_sub_bits(tv, 0) |
232 (get_tarval_sub_bits(tv, 1) << 8) |
233 (get_tarval_sub_bits(tv, 2) << 16) |
234 (get_tarval_sub_bits(tv, 3) << 24);
235 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
236 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
237 set_ia32_ls_mode(load, mode);
240 if (mode == mode_D) {
241 unsigned val = get_tarval_sub_bits(tv, 0) |
242 (get_tarval_sub_bits(tv, 1) << 8) |
243 (get_tarval_sub_bits(tv, 2) << 16) |
244 (get_tarval_sub_bits(tv, 3) << 24);
246 ir_node *imm32 = create_Immediate(NULL, 0, 32);
247 ir_node *cnst, *psllq;
249 /* fine, lower 32bit are zero, produce 32bit value */
250 val = get_tarval_sub_bits(tv, 4) |
251 (get_tarval_sub_bits(tv, 5) << 8) |
252 (get_tarval_sub_bits(tv, 6) << 16) |
253 (get_tarval_sub_bits(tv, 7) << 24);
254 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
255 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
256 set_ia32_ls_mode(load, mode);
257 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
258 set_ia32_ls_mode(psllq, mode);
263 floatent = create_float_const_entity(node);
265 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
267 set_ia32_op_type(load, ia32_AddrModeS);
268 set_ia32_am_sc(load, floatent);
269 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
270 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
273 if (is_Const_null(node)) {
274 load = new_rd_ia32_vfldz(dbgi, irg, block);
276 set_ia32_ls_mode(load, mode);
277 } else if (is_Const_one(node)) {
278 load = new_rd_ia32_vfld1(dbgi, irg, block);
280 set_ia32_ls_mode(load, mode);
282 floatent = create_float_const_entity(node);
284 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
285 set_ia32_op_type(load, ia32_AddrModeS);
286 set_ia32_am_sc(load, floatent);
287 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
288 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
289 /* take the mode from the entity */
290 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
294 /* Const Nodes before the initial IncSP are a bad idea, because
295 * they could be spilled and we have no SP ready at that point yet.
296 * So add a dependency to the initial frame pointer calculation to
297 * avoid that situation.
299 if (get_irg_start_block(irg) == block) {
300 add_irn_dep(load, get_irg_frame(irg));
303 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
305 } else { /* non-float mode */
307 tarval *tv = get_Const_tarval(node);
310 tv = tarval_convert_to(tv, mode_Iu);
312 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
314 panic("couldn't convert constant tarval (%+F)", node);
316 val = get_tarval_long(tv);
318 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
319 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
322 if (get_irg_start_block(irg) == block) {
323 add_irn_dep(cnst, get_irg_frame(irg));
331 * Transforms a SymConst.
333 static ir_node *gen_SymConst(ir_node *node) {
334 ir_graph *irg = current_ir_graph;
335 ir_node *old_block = get_nodes_block(node);
336 ir_node *block = be_transform_node(old_block);
337 dbg_info *dbgi = get_irn_dbg_info(node);
338 ir_mode *mode = get_irn_mode(node);
341 if (mode_is_float(mode)) {
342 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
343 ir_node *nomem = new_NoMem();
345 if (ia32_cg_config.use_sse2)
346 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
348 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
349 set_ia32_am_sc(cnst, get_SymConst_entity(node));
350 set_ia32_use_frame(cnst);
354 if(get_SymConst_kind(node) != symconst_addr_ent) {
355 panic("backend only support symconst_addr_ent (at %+F)", node);
357 entity = get_SymConst_entity(node);
358 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
361 /* Const Nodes before the initial IncSP are a bad idea, because
362 * they could be spilled and we have no SP ready at that point yet
364 if (get_irg_start_block(irg) == block) {
365 add_irn_dep(cnst, get_irg_frame(irg));
368 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
373 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
374 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
375 static const struct {
377 const char *ent_name;
378 const char *cnst_str;
381 } names [ia32_known_const_max] = {
382 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
383 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
384 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
385 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
386 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
388 static ir_entity *ent_cache[ia32_known_const_max];
390 const char *tp_name, *ent_name, *cnst_str;
398 ent_name = names[kct].ent_name;
399 if (! ent_cache[kct]) {
400 tp_name = names[kct].tp_name;
401 cnst_str = names[kct].cnst_str;
403 switch (names[kct].mode) {
404 case 0: mode = mode_Iu; break;
405 case 1: mode = mode_Lu; break;
406 default: mode = mode_F; break;
408 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
409 tp = new_type_primitive(new_id_from_str(tp_name), mode);
410 /* set the specified alignment */
411 set_type_alignment_bytes(tp, names[kct].align);
413 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
415 set_entity_ld_ident(ent, get_entity_ident(ent));
416 set_entity_visibility(ent, visibility_local);
417 set_entity_variability(ent, variability_constant);
418 set_entity_allocation(ent, allocation_static);
420 /* we create a new entity here: It's initialization must resist on the
422 rem = current_ir_graph;
423 current_ir_graph = get_const_code_irg();
424 cnst = new_Const(mode, tv);
425 current_ir_graph = rem;
427 set_atomic_ent_value(ent, cnst);
429 /* cache the entry */
430 ent_cache[kct] = ent;
433 return ent_cache[kct];
437 * return true if the node is a Proj(Load) and could be used in source address
438 * mode for another node. Will return only true if the @p other node is not
439 * dependent on the memory of the Load (for binary operations use the other
440 * input here, for unary operations use NULL).
442 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
443 ir_node *other, ir_node *other2, match_flags_t flags)
448 /* float constants are always available */
449 if (is_Const(node)) {
450 ir_mode *mode = get_irn_mode(node);
451 if (mode_is_float(mode)) {
452 if (ia32_cg_config.use_sse2) {
453 if (is_simple_sse_Const(node))
456 if (is_simple_x87_Const(node))
459 if (get_irn_n_edges(node) > 1)
467 load = get_Proj_pred(node);
468 pn = get_Proj_proj(node);
469 if (!is_Load(load) || pn != pn_Load_res)
471 if (get_nodes_block(load) != block)
473 /* we only use address mode if we're the only user of the load */
474 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
476 /* in some edge cases with address mode we might reach the load normally
477 * and through some AM sequence, if it is already materialized then we
478 * can't create an AM node from it */
479 if (be_is_transformed(node))
482 /* don't do AM if other node inputs depend on the load (via mem-proj) */
483 if (other != NULL && prevents_AM(block, load, other))
486 if (other2 != NULL && prevents_AM(block, load, other2))
492 typedef struct ia32_address_mode_t ia32_address_mode_t;
493 struct ia32_address_mode_t {
498 ia32_op_type_t op_type;
502 unsigned commutative : 1;
503 unsigned ins_permuted : 1;
506 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
510 /* construct load address */
511 memset(addr, 0, sizeof(addr[0]));
512 ia32_create_address_mode(addr, ptr, /*force=*/0);
514 noreg_gp = ia32_new_NoReg_gp(env_cg);
515 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
516 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
517 addr->mem = be_transform_node(mem);
520 static void build_address(ia32_address_mode_t *am, ir_node *node)
522 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
523 ia32_address_t *addr = &am->addr;
529 if (is_Const(node)) {
530 ir_entity *entity = create_float_const_entity(node);
531 addr->base = noreg_gp;
532 addr->index = noreg_gp;
533 addr->mem = new_NoMem();
534 addr->symconst_ent = entity;
536 am->ls_mode = get_type_mode(get_entity_type(entity));
537 am->pinned = op_pin_state_floats;
541 load = get_Proj_pred(node);
542 ptr = get_Load_ptr(load);
543 mem = get_Load_mem(load);
544 new_mem = be_transform_node(mem);
545 am->pinned = get_irn_pinned(load);
546 am->ls_mode = get_Load_mode(load);
547 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
550 /* construct load address */
551 ia32_create_address_mode(addr, ptr, /*force=*/0);
553 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
554 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
558 static void set_address(ir_node *node, const ia32_address_t *addr)
560 set_ia32_am_scale(node, addr->scale);
561 set_ia32_am_sc(node, addr->symconst_ent);
562 set_ia32_am_offs_int(node, addr->offset);
563 if(addr->symconst_sign)
564 set_ia32_am_sc_sign(node);
566 set_ia32_use_frame(node);
567 set_ia32_frame_ent(node, addr->frame_entity);
571 * Apply attributes of a given address mode to a node.
573 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
575 set_address(node, &am->addr);
577 set_ia32_op_type(node, am->op_type);
578 set_ia32_ls_mode(node, am->ls_mode);
579 if (am->pinned == op_pin_state_pinned) {
580 /* beware: some nodes are already pinned and did not allow to change the state */
581 if (get_irn_pinned(node) != op_pin_state_pinned)
582 set_irn_pinned(node, op_pin_state_pinned);
585 set_ia32_commutative(node);
589 * Check, if a given node is a Down-Conv, ie. a integer Conv
590 * from a mode with a mode with more bits to a mode with lesser bits.
591 * Moreover, we return only true if the node has not more than 1 user.
593 * @param node the node
594 * @return non-zero if node is a Down-Conv
596 static int is_downconv(const ir_node *node)
604 /* we only want to skip the conv when we're the only user
605 * (not optimal but for now...)
607 if(get_irn_n_edges(node) > 1)
610 src_mode = get_irn_mode(get_Conv_op(node));
611 dest_mode = get_irn_mode(node);
612 return ia32_mode_needs_gp_reg(src_mode)
613 && ia32_mode_needs_gp_reg(dest_mode)
614 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
617 /* Skip all Down-Conv's on a given node and return the resulting node. */
618 ir_node *ia32_skip_downconv(ir_node *node) {
619 while (is_downconv(node))
620 node = get_Conv_op(node);
625 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
627 ir_mode *mode = get_irn_mode(node);
632 if(mode_is_signed(mode)) {
637 block = get_nodes_block(node);
638 dbgi = get_irn_dbg_info(node);
640 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
644 * matches operands of a node into ia32 addressing/operand modes. This covers
645 * usage of source address mode, immediates, operations with non 32-bit modes,
647 * The resulting data is filled into the @p am struct. block is the block
648 * of the node whose arguments are matched. op1, op2 are the first and second
649 * input that are matched (op1 may be NULL). other_op is another unrelated
650 * input that is not matched! but which is needed sometimes to check if AM
651 * for op1/op2 is legal.
652 * @p flags describes the supported modes of the operation in detail.
654 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
655 ir_node *op1, ir_node *op2, ir_node *other_op,
658 ia32_address_t *addr = &am->addr;
659 ir_mode *mode = get_irn_mode(op2);
660 int mode_bits = get_mode_size_bits(mode);
661 ir_node *noreg_gp, *new_op1, *new_op2;
663 unsigned commutative;
664 int use_am_and_immediates;
667 memset(am, 0, sizeof(am[0]));
669 commutative = (flags & match_commutative) != 0;
670 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
671 use_am = (flags & match_am) != 0;
672 use_immediate = (flags & match_immediate) != 0;
673 assert(!use_am_and_immediates || use_immediate);
676 assert(!commutative || op1 != NULL);
677 assert(use_am || !(flags & match_8bit_am));
678 assert(use_am || !(flags & match_16bit_am));
680 if (mode_bits == 8) {
681 if (!(flags & match_8bit_am))
683 /* we don't automatically add upconvs yet */
684 assert((flags & match_mode_neutral) || (flags & match_8bit));
685 } else if (mode_bits == 16) {
686 if (!(flags & match_16bit_am))
688 /* we don't automatically add upconvs yet */
689 assert((flags & match_mode_neutral) || (flags & match_16bit));
692 /* we can simply skip downconvs for mode neutral nodes: the upper bits
693 * can be random for these operations */
694 if (flags & match_mode_neutral) {
695 op2 = ia32_skip_downconv(op2);
697 op1 = ia32_skip_downconv(op1);
701 /* match immediates. firm nodes are normalized: constants are always on the
704 if (!(flags & match_try_am) && use_immediate) {
705 new_op2 = try_create_Immediate(op2, 0);
708 noreg_gp = ia32_new_NoReg_gp(env_cg);
709 if (new_op2 == NULL &&
710 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
711 build_address(am, op2);
712 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
713 if (mode_is_float(mode)) {
714 new_op2 = ia32_new_NoReg_vfp(env_cg);
718 am->op_type = ia32_AddrModeS;
719 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
721 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
723 build_address(am, op1);
725 if (mode_is_float(mode)) {
726 noreg = ia32_new_NoReg_vfp(env_cg);
731 if (new_op2 != NULL) {
734 new_op1 = be_transform_node(op2);
736 am->ins_permuted = 1;
738 am->op_type = ia32_AddrModeS;
740 am->op_type = ia32_Normal;
742 if (flags & match_try_am) {
748 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
750 new_op2 = be_transform_node(op2);
752 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
754 if (addr->base == NULL)
755 addr->base = noreg_gp;
756 if (addr->index == NULL)
757 addr->index = noreg_gp;
758 if (addr->mem == NULL)
759 addr->mem = new_NoMem();
761 am->new_op1 = new_op1;
762 am->new_op2 = new_op2;
763 am->commutative = commutative;
766 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
768 mark_irn_visited(old_node);
769 be_set_transformed_node(old_node, new_node);
772 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
777 if (am->mem_proj == NULL)
780 /* we have to create a mode_T so the old MemProj can attach to us */
781 mode = get_irn_mode(node);
782 load = get_Proj_pred(am->mem_proj);
784 set_transformed_and_mark(load, node);
786 if (mode != mode_T) {
787 set_irn_mode(node, mode_T);
788 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
795 * Construct a standard binary operation, set AM and immediate if required.
797 * @param node The original node for which the binop is created
798 * @param op1 The first operand
799 * @param op2 The second operand
800 * @param func The node constructor function
801 * @return The constructed ia32 node.
803 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
804 construct_binop_func *func, match_flags_t flags)
807 ir_node *block, *new_block, *new_node;
808 ia32_address_mode_t am;
809 ia32_address_t *addr = &am.addr;
811 block = get_nodes_block(node);
812 match_arguments(&am, block, op1, op2, NULL, flags);
814 dbgi = get_irn_dbg_info(node);
815 new_block = be_transform_node(block);
816 new_node = func(dbgi, current_ir_graph, new_block,
817 addr->base, addr->index, addr->mem,
818 am.new_op1, am.new_op2);
819 set_am_attributes(new_node, &am);
820 /* we can't use source address mode anymore when using immediates */
821 if (!(flags & match_am_and_immediates) &&
822 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
823 set_ia32_am_support(new_node, ia32_am_none);
824 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
826 new_node = fix_mem_proj(new_node, &am);
833 n_ia32_l_binop_right,
834 n_ia32_l_binop_eflags
836 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
837 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
838 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
839 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
840 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
841 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
844 * Construct a binary operation which also consumes the eflags.
846 * @param node The node to transform
847 * @param func The node constructor function
848 * @param flags The match flags
849 * @return The constructor ia32 node
851 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
854 ir_node *src_block = get_nodes_block(node);
855 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
856 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
857 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
859 ir_node *block, *new_node, *new_eflags;
860 ia32_address_mode_t am;
861 ia32_address_t *addr = &am.addr;
863 match_arguments(&am, src_block, op1, op2, eflags, flags);
865 dbgi = get_irn_dbg_info(node);
866 block = be_transform_node(src_block);
867 new_eflags = be_transform_node(eflags);
868 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
869 addr->mem, am.new_op1, am.new_op2, new_eflags);
870 set_am_attributes(new_node, &am);
871 /* we can't use source address mode anymore when using immediates */
872 if (!(flags & match_am_and_immediates) &&
873 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
874 set_ia32_am_support(new_node, ia32_am_none);
875 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
877 new_node = fix_mem_proj(new_node, &am);
882 static ir_node *get_fpcw(void)
885 if (initial_fpcw != NULL)
888 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
889 &ia32_fp_cw_regs[REG_FPCW]);
890 initial_fpcw = be_transform_node(fpcw);
896 * Construct a standard binary operation, set AM and immediate if required.
898 * @param op1 The first operand
899 * @param op2 The second operand
900 * @param func The node constructor function
901 * @return The constructed ia32 node.
903 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
904 construct_binop_float_func *func,
907 ir_mode *mode = get_irn_mode(node);
909 ir_node *block, *new_block, *new_node;
910 ia32_address_mode_t am;
911 ia32_address_t *addr = &am.addr;
913 /* cannot use address mode with long double on x87 */
914 if (get_mode_size_bits(mode) > 64)
917 block = get_nodes_block(node);
918 match_arguments(&am, block, op1, op2, NULL, flags);
920 dbgi = get_irn_dbg_info(node);
921 new_block = be_transform_node(block);
922 new_node = func(dbgi, current_ir_graph, new_block,
923 addr->base, addr->index, addr->mem,
924 am.new_op1, am.new_op2, get_fpcw());
925 set_am_attributes(new_node, &am);
927 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
929 new_node = fix_mem_proj(new_node, &am);
935 * Construct a shift/rotate binary operation, sets AM and immediate if required.
937 * @param op1 The first operand
938 * @param op2 The second operand
939 * @param func The node constructor function
940 * @return The constructed ia32 node.
942 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
943 construct_shift_func *func,
947 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
949 assert(! mode_is_float(get_irn_mode(node)));
950 assert(flags & match_immediate);
951 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
953 if (flags & match_mode_neutral) {
954 op1 = ia32_skip_downconv(op1);
955 new_op1 = be_transform_node(op1);
956 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
957 new_op1 = create_upconv(op1, node);
959 new_op1 = be_transform_node(op1);
962 /* the shift amount can be any mode that is bigger than 5 bits, since all
963 * other bits are ignored anyway */
964 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
965 ir_node *const op = get_Conv_op(op2);
966 if (mode_is_float(get_irn_mode(op)))
969 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
971 new_op2 = create_immediate_or_transform(op2, 0);
973 dbgi = get_irn_dbg_info(node);
974 block = get_nodes_block(node);
975 new_block = be_transform_node(block);
976 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
977 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
979 /* lowered shift instruction may have a dependency operand, handle it here */
980 if (get_irn_arity(node) == 3) {
981 /* we have a dependency */
982 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
983 add_irn_dep(new_node, new_dep);
991 * Construct a standard unary operation, set AM and immediate if required.
993 * @param op The operand
994 * @param func The node constructor function
995 * @return The constructed ia32 node.
997 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1001 ir_node *block, *new_block, *new_op, *new_node;
1003 assert(flags == 0 || flags == match_mode_neutral);
1004 if (flags & match_mode_neutral) {
1005 op = ia32_skip_downconv(op);
1008 new_op = be_transform_node(op);
1009 dbgi = get_irn_dbg_info(node);
1010 block = get_nodes_block(node);
1011 new_block = be_transform_node(block);
1012 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1014 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1019 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1020 ia32_address_t *addr)
1022 ir_node *base, *index, *res;
1026 base = ia32_new_NoReg_gp(env_cg);
1028 base = be_transform_node(base);
1031 index = addr->index;
1032 if (index == NULL) {
1033 index = ia32_new_NoReg_gp(env_cg);
1035 index = be_transform_node(index);
1038 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1039 set_address(res, addr);
1045 * Returns non-zero if a given address mode has a symbolic or
1046 * numerical offset != 0.
1048 static int am_has_immediates(const ia32_address_t *addr)
1050 return addr->offset != 0 || addr->symconst_ent != NULL
1051 || addr->frame_entity || addr->use_frame;
1055 * Creates an ia32 Add.
1057 * @return the created ia32 Add node
1059 static ir_node *gen_Add(ir_node *node) {
1060 ir_mode *mode = get_irn_mode(node);
1061 ir_node *op1 = get_Add_left(node);
1062 ir_node *op2 = get_Add_right(node);
1064 ir_node *block, *new_block, *new_node, *add_immediate_op;
1065 ia32_address_t addr;
1066 ia32_address_mode_t am;
1068 if (mode_is_float(mode)) {
1069 if (ia32_cg_config.use_sse2)
1070 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1071 match_commutative | match_am);
1073 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1074 match_commutative | match_am);
1077 ia32_mark_non_am(node);
1079 op2 = ia32_skip_downconv(op2);
1080 op1 = ia32_skip_downconv(op1);
1084 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1085 * 1. Add with immediate -> Lea
1086 * 2. Add with possible source address mode -> Add
1087 * 3. Otherwise -> Lea
1089 memset(&addr, 0, sizeof(addr));
1090 ia32_create_address_mode(&addr, node, /*force=*/1);
1091 add_immediate_op = NULL;
1093 dbgi = get_irn_dbg_info(node);
1094 block = get_nodes_block(node);
1095 new_block = be_transform_node(block);
1098 if(addr.base == NULL && addr.index == NULL) {
1099 ir_graph *irg = current_ir_graph;
1100 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1101 addr.symconst_sign, addr.offset);
1102 add_irn_dep(new_node, get_irg_frame(irg));
1103 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1106 /* add with immediate? */
1107 if(addr.index == NULL) {
1108 add_immediate_op = addr.base;
1109 } else if(addr.base == NULL && addr.scale == 0) {
1110 add_immediate_op = addr.index;
1113 if(add_immediate_op != NULL) {
1114 if(!am_has_immediates(&addr)) {
1115 #ifdef DEBUG_libfirm
1116 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1119 return be_transform_node(add_immediate_op);
1122 new_node = create_lea_from_address(dbgi, new_block, &addr);
1123 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1127 /* test if we can use source address mode */
1128 match_arguments(&am, block, op1, op2, NULL, match_commutative
1129 | match_mode_neutral | match_am | match_immediate | match_try_am);
1131 /* construct an Add with source address mode */
1132 if (am.op_type == ia32_AddrModeS) {
1133 ir_graph *irg = current_ir_graph;
1134 ia32_address_t *am_addr = &am.addr;
1135 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1136 am_addr->index, am_addr->mem, am.new_op1,
1138 set_am_attributes(new_node, &am);
1139 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1141 new_node = fix_mem_proj(new_node, &am);
1146 /* otherwise construct a lea */
1147 new_node = create_lea_from_address(dbgi, new_block, &addr);
1148 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1153 * Creates an ia32 Mul.
1155 * @return the created ia32 Mul node
1157 static ir_node *gen_Mul(ir_node *node) {
1158 ir_node *op1 = get_Mul_left(node);
1159 ir_node *op2 = get_Mul_right(node);
1160 ir_mode *mode = get_irn_mode(node);
1162 if (mode_is_float(mode)) {
1163 if (ia32_cg_config.use_sse2)
1164 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1165 match_commutative | match_am);
1167 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1168 match_commutative | match_am);
1170 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1171 match_commutative | match_am | match_mode_neutral |
1172 match_immediate | match_am_and_immediates);
1176 * Creates an ia32 Mulh.
1177 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1178 * this result while Mul returns the lower 32 bit.
1180 * @return the created ia32 Mulh node
1182 static ir_node *gen_Mulh(ir_node *node) {
1183 ir_node *block = get_nodes_block(node);
1184 ir_node *new_block = be_transform_node(block);
1185 dbg_info *dbgi = get_irn_dbg_info(node);
1186 ir_node *op1 = get_Mulh_left(node);
1187 ir_node *op2 = get_Mulh_right(node);
1188 ir_mode *mode = get_irn_mode(node);
1190 ir_node *proj_res_high;
1192 if (mode_is_signed(mode)) {
1193 new_node = gen_binop(node, op1, op2, new_rd_ia32_IMul1OP, match_commutative | match_am);
1194 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1195 mode_Iu, pn_ia32_IMul1OP_res_high);
1197 new_node = gen_binop(node, op1, op2, new_rd_ia32_Mul, match_commutative | match_am);
1198 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1199 mode_Iu, pn_ia32_Mul_res_high);
1201 return proj_res_high;
1205 * Creates an ia32 And.
1207 * @return The created ia32 And node
1209 static ir_node *gen_And(ir_node *node) {
1210 ir_node *op1 = get_And_left(node);
1211 ir_node *op2 = get_And_right(node);
1212 assert(! mode_is_float(get_irn_mode(node)));
1214 /* is it a zero extension? */
1215 if (is_Const(op2)) {
1216 tarval *tv = get_Const_tarval(op2);
1217 long v = get_tarval_long(tv);
1219 if (v == 0xFF || v == 0xFFFF) {
1220 dbg_info *dbgi = get_irn_dbg_info(node);
1221 ir_node *block = get_nodes_block(node);
1228 assert(v == 0xFFFF);
1231 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1236 return gen_binop(node, op1, op2, new_rd_ia32_And,
1237 match_commutative | match_mode_neutral | match_am
1244 * Creates an ia32 Or.
1246 * @return The created ia32 Or node
1248 static ir_node *gen_Or(ir_node *node) {
1249 ir_node *op1 = get_Or_left(node);
1250 ir_node *op2 = get_Or_right(node);
1252 assert (! mode_is_float(get_irn_mode(node)));
1253 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1254 | match_mode_neutral | match_am | match_immediate);
1260 * Creates an ia32 Eor.
1262 * @return The created ia32 Eor node
1264 static ir_node *gen_Eor(ir_node *node) {
1265 ir_node *op1 = get_Eor_left(node);
1266 ir_node *op2 = get_Eor_right(node);
1268 assert(! mode_is_float(get_irn_mode(node)));
1269 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1270 | match_mode_neutral | match_am | match_immediate);
1275 * Creates an ia32 Sub.
1277 * @return The created ia32 Sub node
1279 static ir_node *gen_Sub(ir_node *node) {
1280 ir_node *op1 = get_Sub_left(node);
1281 ir_node *op2 = get_Sub_right(node);
1282 ir_mode *mode = get_irn_mode(node);
1284 if (mode_is_float(mode)) {
1285 if (ia32_cg_config.use_sse2)
1286 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1288 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1292 if (is_Const(op2)) {
1293 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1297 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1298 | match_am | match_immediate);
1301 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1302 ir_node *const src_val,
1303 ir_node *const src_mem,
1304 ir_node *const am_mem)
1306 if (is_NoMem(am_mem)) {
1307 return be_transform_node(src_mem);
1308 } else if (is_Proj(src_val) &&
1310 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1311 /* avoid memory loop */
1313 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1314 ir_node *const ptr_pred = get_Proj_pred(src_val);
1315 int const arity = get_Sync_n_preds(src_mem);
1320 NEW_ARR_A(ir_node*, ins, arity + 1);
1322 for (i = arity - 1; i >= 0; --i) {
1323 ir_node *const pred = get_Sync_pred(src_mem, i);
1325 /* avoid memory loop */
1326 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1329 ins[n++] = be_transform_node(pred);
1334 return new_r_Sync(irg, block, n, ins);
1338 ins[0] = be_transform_node(src_mem);
1340 return new_r_Sync(irg, block, 2, ins);
1345 * Generates an ia32 DivMod with additional infrastructure for the
1346 * register allocator if needed.
1348 static ir_node *create_Div(ir_node *node)
1350 ir_graph *irg = current_ir_graph;
1351 dbg_info *dbgi = get_irn_dbg_info(node);
1352 ir_node *block = get_nodes_block(node);
1353 ir_node *new_block = be_transform_node(block);
1360 ir_node *sign_extension;
1361 ia32_address_mode_t am;
1362 ia32_address_t *addr = &am.addr;
1364 /* the upper bits have random contents for smaller modes */
1365 switch (get_irn_opcode(node)) {
1367 op1 = get_Div_left(node);
1368 op2 = get_Div_right(node);
1369 mem = get_Div_mem(node);
1370 mode = get_Div_resmode(node);
1373 op1 = get_Mod_left(node);
1374 op2 = get_Mod_right(node);
1375 mem = get_Mod_mem(node);
1376 mode = get_Mod_resmode(node);
1379 op1 = get_DivMod_left(node);
1380 op2 = get_DivMod_right(node);
1381 mem = get_DivMod_mem(node);
1382 mode = get_DivMod_resmode(node);
1385 panic("invalid divmod node %+F", node);
1388 match_arguments(&am, block, op1, op2, NULL, match_am);
1390 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1391 is the memory of the consumed address. We can have only the second op as address
1392 in Div nodes, so check only op2. */
1393 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1395 if (mode_is_signed(mode)) {
1396 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1397 add_irn_dep(produceval, get_irg_frame(irg));
1398 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1401 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1402 addr->index, new_mem, am.new_op2,
1403 am.new_op1, sign_extension);
1405 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1406 add_irn_dep(sign_extension, get_irg_frame(irg));
1408 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1409 addr->index, new_mem, am.new_op2,
1410 am.new_op1, sign_extension);
1413 set_irn_pinned(new_node, get_irn_pinned(node));
1415 set_am_attributes(new_node, &am);
1416 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1418 new_node = fix_mem_proj(new_node, &am);
1424 static ir_node *gen_Mod(ir_node *node) {
1425 return create_Div(node);
1428 static ir_node *gen_Div(ir_node *node) {
1429 return create_Div(node);
1432 static ir_node *gen_DivMod(ir_node *node) {
1433 return create_Div(node);
1439 * Creates an ia32 floating Div.
1441 * @return The created ia32 xDiv node
1443 static ir_node *gen_Quot(ir_node *node)
1445 ir_node *op1 = get_Quot_left(node);
1446 ir_node *op2 = get_Quot_right(node);
1448 if (ia32_cg_config.use_sse2) {
1449 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1451 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1457 * Creates an ia32 Shl.
1459 * @return The created ia32 Shl node
1461 static ir_node *gen_Shl(ir_node *node) {
1462 ir_node *left = get_Shl_left(node);
1463 ir_node *right = get_Shl_right(node);
1465 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1466 match_mode_neutral | match_immediate);
1470 * Creates an ia32 Shr.
1472 * @return The created ia32 Shr node
1474 static ir_node *gen_Shr(ir_node *node) {
1475 ir_node *left = get_Shr_left(node);
1476 ir_node *right = get_Shr_right(node);
1478 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1484 * Creates an ia32 Sar.
1486 * @return The created ia32 Shrs node
1488 static ir_node *gen_Shrs(ir_node *node) {
1489 ir_node *left = get_Shrs_left(node);
1490 ir_node *right = get_Shrs_right(node);
1491 ir_mode *mode = get_irn_mode(node);
1493 if(is_Const(right) && mode == mode_Is) {
1494 tarval *tv = get_Const_tarval(right);
1495 long val = get_tarval_long(tv);
1497 /* this is a sign extension */
1498 ir_graph *irg = current_ir_graph;
1499 dbg_info *dbgi = get_irn_dbg_info(node);
1500 ir_node *block = be_transform_node(get_nodes_block(node));
1502 ir_node *new_op = be_transform_node(op);
1503 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1504 add_irn_dep(pval, get_irg_frame(irg));
1506 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1510 /* 8 or 16 bit sign extension? */
1511 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1512 ir_node *shl_left = get_Shl_left(left);
1513 ir_node *shl_right = get_Shl_right(left);
1514 if(is_Const(shl_right)) {
1515 tarval *tv1 = get_Const_tarval(right);
1516 tarval *tv2 = get_Const_tarval(shl_right);
1517 if(tv1 == tv2 && tarval_is_long(tv1)) {
1518 long val = get_tarval_long(tv1);
1519 if(val == 16 || val == 24) {
1520 dbg_info *dbgi = get_irn_dbg_info(node);
1521 ir_node *block = get_nodes_block(node);
1531 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1540 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1546 * Creates an ia32 Rol.
1548 * @param op1 The first operator
1549 * @param op2 The second operator
1550 * @return The created ia32 RotL node
1552 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) {
1568 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1574 * Creates an ia32 RotR or RotL (depending on the found pattern).
1576 * @return The created ia32 RotL or RotR node
1578 static ir_node *gen_Rotl(ir_node *node) {
1579 ir_node *rotate = NULL;
1580 ir_node *op1 = get_Rotl_left(node);
1581 ir_node *op2 = get_Rotl_right(node);
1583 /* Firm has only RotL, so we are looking for a right (op2)
1584 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1585 that means we can create a RotR instead of an Add and a RotL */
1589 ir_node *left = get_Add_left(add);
1590 ir_node *right = get_Add_right(add);
1591 if (is_Const(right)) {
1592 tarval *tv = get_Const_tarval(right);
1593 ir_mode *mode = get_irn_mode(node);
1594 long bits = get_mode_size_bits(mode);
1596 if (is_Minus(left) &&
1597 tarval_is_long(tv) &&
1598 get_tarval_long(tv) == bits &&
1601 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1602 rotate = gen_Ror(node, op1, get_Minus_op(left));
1607 if (rotate == NULL) {
1608 rotate = gen_Rol(node, op1, op2);
1617 * Transforms a Minus node.
1619 * @return The created ia32 Minus node
1621 static ir_node *gen_Minus(ir_node *node)
1623 ir_node *op = get_Minus_op(node);
1624 ir_node *block = be_transform_node(get_nodes_block(node));
1625 ir_graph *irg = current_ir_graph;
1626 dbg_info *dbgi = get_irn_dbg_info(node);
1627 ir_mode *mode = get_irn_mode(node);
1632 if (mode_is_float(mode)) {
1633 ir_node *new_op = be_transform_node(op);
1634 if (ia32_cg_config.use_sse2) {
1635 /* TODO: non-optimal... if we have many xXors, then we should
1636 * rather create a load for the const and use that instead of
1637 * several AM nodes... */
1638 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1639 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1640 ir_node *nomem = new_rd_NoMem(irg);
1642 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1643 nomem, new_op, noreg_xmm);
1645 size = get_mode_size_bits(mode);
1646 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1648 set_ia32_am_sc(new_node, ent);
1649 set_ia32_op_type(new_node, ia32_AddrModeS);
1650 set_ia32_ls_mode(new_node, mode);
1652 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1655 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1658 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1664 * Transforms a Not node.
1666 * @return The created ia32 Not node
1668 static ir_node *gen_Not(ir_node *node) {
1669 ir_node *op = get_Not_op(node);
1671 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1672 assert (! mode_is_float(get_irn_mode(node)));
1674 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1680 * Transforms an Abs node.
1682 * @return The created ia32 Abs node
1684 static ir_node *gen_Abs(ir_node *node)
1686 ir_node *block = get_nodes_block(node);
1687 ir_node *new_block = be_transform_node(block);
1688 ir_node *op = get_Abs_op(node);
1689 ir_graph *irg = current_ir_graph;
1690 dbg_info *dbgi = get_irn_dbg_info(node);
1691 ir_mode *mode = get_irn_mode(node);
1692 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1693 ir_node *nomem = new_NoMem();
1699 if (mode_is_float(mode)) {
1700 new_op = be_transform_node(op);
1702 if (ia32_cg_config.use_sse2) {
1703 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1704 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1705 nomem, new_op, noreg_fp);
1707 size = get_mode_size_bits(mode);
1708 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1710 set_ia32_am_sc(new_node, ent);
1712 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1714 set_ia32_op_type(new_node, ia32_AddrModeS);
1715 set_ia32_ls_mode(new_node, mode);
1717 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1718 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1721 ir_node *xor, *pval, *sign_extension;
1723 if (get_mode_size_bits(mode) == 32) {
1724 new_op = be_transform_node(op);
1726 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1729 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1730 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1733 add_irn_dep(pval, get_irg_frame(irg));
1734 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1736 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1737 nomem, new_op, sign_extension);
1738 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1740 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1741 nomem, xor, sign_extension);
1742 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1749 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1751 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1752 dbg_info *dbgi = get_irn_dbg_info(cmp);
1753 ir_node *block = get_nodes_block(cmp);
1754 ir_node *new_block = be_transform_node(block);
1755 ir_node *op1 = be_transform_node(x);
1756 ir_node *op2 = be_transform_node(n);
1758 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1762 * Transform a node returning a "flag" result.
1764 * @param node the node to transform
1765 * @param pnc_out the compare mode to use
1767 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1776 /* we have a Cmp as input */
1777 if (is_Proj(node)) {
1778 ir_node *pred = get_Proj_pred(node);
1780 pn_Cmp pnc = get_Proj_proj(node);
1781 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1782 ir_node *l = get_Cmp_left(pred);
1783 ir_node *r = get_Cmp_right(pred);
1785 ir_node *la = get_And_left(l);
1786 ir_node *ra = get_And_right(l);
1788 ir_node *c = get_Shl_left(la);
1789 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1790 /* (1 << n) & ra) */
1791 ir_node *n = get_Shl_right(la);
1792 flags = gen_bt(pred, ra, n);
1793 /* we must generate a Jc/Jnc jump */
1794 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1797 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1802 ir_node *c = get_Shl_left(ra);
1803 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1804 /* la & (1 << n)) */
1805 ir_node *n = get_Shl_right(ra);
1806 flags = gen_bt(pred, la, n);
1807 /* we must generate a Jc/Jnc jump */
1808 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1811 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1817 flags = be_transform_node(pred);
1823 /* a mode_b value, we have to compare it against 0 */
1824 dbgi = get_irn_dbg_info(node);
1825 new_block = be_transform_node(get_nodes_block(node));
1826 new_op = be_transform_node(node);
1827 noreg = ia32_new_NoReg_gp(env_cg);
1828 nomem = new_NoMem();
1829 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1830 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1831 *pnc_out = pn_Cmp_Lg;
1836 * Transforms a Load.
1838 * @return the created ia32 Load node
1840 static ir_node *gen_Load(ir_node *node) {
1841 ir_node *old_block = get_nodes_block(node);
1842 ir_node *block = be_transform_node(old_block);
1843 ir_node *ptr = get_Load_ptr(node);
1844 ir_node *mem = get_Load_mem(node);
1845 ir_node *new_mem = be_transform_node(mem);
1848 ir_graph *irg = current_ir_graph;
1849 dbg_info *dbgi = get_irn_dbg_info(node);
1850 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1851 ir_mode *mode = get_Load_mode(node);
1854 ia32_address_t addr;
1856 /* construct load address */
1857 memset(&addr, 0, sizeof(addr));
1858 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1865 base = be_transform_node(base);
1871 index = be_transform_node(index);
1874 if (mode_is_float(mode)) {
1875 if (ia32_cg_config.use_sse2) {
1876 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1878 res_mode = mode_xmm;
1880 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1882 res_mode = mode_vfp;
1885 assert(mode != mode_b);
1887 /* create a conv node with address mode for smaller modes */
1888 if(get_mode_size_bits(mode) < 32) {
1889 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1890 new_mem, noreg, mode);
1892 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1897 set_irn_pinned(new_node, get_irn_pinned(node));
1898 set_ia32_op_type(new_node, ia32_AddrModeS);
1899 set_ia32_ls_mode(new_node, mode);
1900 set_address(new_node, &addr);
1902 if(get_irn_pinned(node) == op_pin_state_floats) {
1903 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1906 /* make sure we are scheduled behind the initial IncSP/Barrier
1907 * to avoid spills being placed before it
1909 if (block == get_irg_start_block(irg)) {
1910 add_irn_dep(new_node, get_irg_frame(irg));
1913 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1918 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1919 ir_node *ptr, ir_node *other)
1926 /* we only use address mode if we're the only user of the load */
1927 if (get_irn_n_edges(node) > 1)
1930 load = get_Proj_pred(node);
1933 if (get_nodes_block(load) != block)
1936 /* store should have the same pointer as the load */
1937 if (get_Load_ptr(load) != ptr)
1940 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1941 if (other != NULL &&
1942 get_nodes_block(other) == block &&
1943 heights_reachable_in_block(heights, other, load)) {
1950 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
1951 ir_node *const pred = get_Sync_pred(mem, i);
1953 if (is_Proj(pred) && get_Proj_pred(pred) == load)
1956 if (get_nodes_block(pred) == block &&
1957 heights_reachable_in_block(heights, pred, load)) {
1962 /* Store should be attached to the load */
1963 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
1970 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1971 ir_node *mem, ir_node *ptr, ir_mode *mode,
1972 construct_binop_dest_func *func,
1973 construct_binop_dest_func *func8bit,
1974 match_flags_t flags)
1976 ir_node *src_block = get_nodes_block(node);
1978 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1979 ir_graph *irg = current_ir_graph;
1986 ia32_address_mode_t am;
1987 ia32_address_t *addr = &am.addr;
1988 memset(&am, 0, sizeof(am));
1990 assert(flags & match_dest_am);
1991 assert(flags & match_immediate); /* there is no destam node without... */
1992 commutative = (flags & match_commutative) != 0;
1994 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
1995 build_address(&am, op1);
1996 new_op = create_immediate_or_transform(op2, 0);
1997 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1998 build_address(&am, op2);
1999 new_op = create_immediate_or_transform(op1, 0);
2004 if(addr->base == NULL)
2005 addr->base = noreg_gp;
2006 if(addr->index == NULL)
2007 addr->index = noreg_gp;
2008 if(addr->mem == NULL)
2009 addr->mem = new_NoMem();
2011 dbgi = get_irn_dbg_info(node);
2012 block = be_transform_node(src_block);
2013 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2015 if(get_mode_size_bits(mode) == 8) {
2016 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2019 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
2022 set_address(new_node, addr);
2023 set_ia32_op_type(new_node, ia32_AddrModeD);
2024 set_ia32_ls_mode(new_node, mode);
2025 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2027 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2028 mem_proj = be_transform_node(am.mem_proj);
2029 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2034 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2035 ir_node *ptr, ir_mode *mode,
2036 construct_unop_dest_func *func)
2038 ir_graph *irg = current_ir_graph;
2039 ir_node *src_block = get_nodes_block(node);
2045 ia32_address_mode_t am;
2046 ia32_address_t *addr = &am.addr;
2047 memset(&am, 0, sizeof(am));
2049 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2052 build_address(&am, op);
2054 dbgi = get_irn_dbg_info(node);
2055 block = be_transform_node(src_block);
2056 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2057 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2058 set_address(new_node, addr);
2059 set_ia32_op_type(new_node, ia32_AddrModeD);
2060 set_ia32_ls_mode(new_node, mode);
2061 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2063 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2064 mem_proj = be_transform_node(am.mem_proj);
2065 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2070 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2071 ir_mode *mode = get_irn_mode(node);
2072 ir_node *mux_true = get_Mux_true(node);
2073 ir_node *mux_false = get_Mux_false(node);
2084 ia32_address_t addr;
2086 if(get_mode_size_bits(mode) != 8)
2089 if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2091 } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2097 build_address_ptr(&addr, ptr, mem);
2099 irg = current_ir_graph;
2100 dbgi = get_irn_dbg_info(node);
2101 block = get_nodes_block(node);
2102 new_block = be_transform_node(block);
2103 cond = get_Mux_sel(node);
2104 flags = get_flags_node(cond, &pnc);
2105 new_mem = be_transform_node(mem);
2106 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2107 addr.index, addr.mem, flags, pnc, negated);
2108 set_address(new_node, &addr);
2109 set_ia32_op_type(new_node, ia32_AddrModeD);
2110 set_ia32_ls_mode(new_node, mode);
2111 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2116 static ir_node *try_create_dest_am(ir_node *node) {
2117 ir_node *val = get_Store_value(node);
2118 ir_node *mem = get_Store_mem(node);
2119 ir_node *ptr = get_Store_ptr(node);
2120 ir_mode *mode = get_irn_mode(val);
2121 unsigned bits = get_mode_size_bits(mode);
2126 /* handle only GP modes for now... */
2127 if(!ia32_mode_needs_gp_reg(mode))
2131 /* store must be the only user of the val node */
2132 if(get_irn_n_edges(val) > 1)
2134 /* skip pointless convs */
2136 ir_node *conv_op = get_Conv_op(val);
2137 ir_mode *pred_mode = get_irn_mode(conv_op);
2138 if (!ia32_mode_needs_gp_reg(pred_mode))
2140 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2148 /* value must be in the same block */
2149 if(get_nodes_block(node) != get_nodes_block(val))
2152 switch (get_irn_opcode(val)) {
2154 op1 = get_Add_left(val);
2155 op2 = get_Add_right(val);
2156 if(is_Const_1(op2)) {
2157 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2158 new_rd_ia32_IncMem);
2160 } else if(is_Const_Minus_1(op2)) {
2161 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2162 new_rd_ia32_DecMem);
2165 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2166 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2167 match_dest_am | match_commutative |
2171 op1 = get_Sub_left(val);
2172 op2 = get_Sub_right(val);
2173 if (is_Const(op2)) {
2174 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2176 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2177 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2178 match_dest_am | match_immediate |
2182 op1 = get_And_left(val);
2183 op2 = get_And_right(val);
2184 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2185 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2186 match_dest_am | match_commutative |
2190 op1 = get_Or_left(val);
2191 op2 = get_Or_right(val);
2192 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2193 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2194 match_dest_am | match_commutative |
2198 op1 = get_Eor_left(val);
2199 op2 = get_Eor_right(val);
2200 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2201 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2202 match_dest_am | match_commutative |
2206 op1 = get_Shl_left(val);
2207 op2 = get_Shl_right(val);
2208 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2209 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2210 match_dest_am | match_immediate);
2213 op1 = get_Shr_left(val);
2214 op2 = get_Shr_right(val);
2215 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2216 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2217 match_dest_am | match_immediate);
2220 op1 = get_Shrs_left(val);
2221 op2 = get_Shrs_right(val);
2222 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2223 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2224 match_dest_am | match_immediate);
2227 op1 = get_Rotl_left(val);
2228 op2 = get_Rotl_right(val);
2229 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2230 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2231 match_dest_am | match_immediate);
2233 /* TODO: match ROR patterns... */
2235 new_node = try_create_SetMem(val, ptr, mem);
2238 op1 = get_Minus_op(val);
2239 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2242 /* should be lowered already */
2243 assert(mode != mode_b);
2244 op1 = get_Not_op(val);
2245 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2251 if(new_node != NULL) {
2252 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2253 get_irn_pinned(node) == op_pin_state_pinned) {
2254 set_irn_pinned(new_node, op_pin_state_pinned);
2261 static int is_float_to_int_conv(const ir_node *node)
2263 ir_mode *mode = get_irn_mode(node);
2267 if (mode != mode_Is && mode != mode_Hs)
2272 conv_op = get_Conv_op(node);
2273 conv_mode = get_irn_mode(conv_op);
2275 if(!mode_is_float(conv_mode))
2282 * Transform a Store(floatConst).
2284 * @return the created ia32 Store node
2286 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2288 ir_mode *mode = get_irn_mode(cns);
2289 unsigned size = get_mode_size_bytes(mode);
2290 tarval *tv = get_Const_tarval(cns);
2291 ir_node *block = get_nodes_block(node);
2292 ir_node *new_block = be_transform_node(block);
2293 ir_node *ptr = get_Store_ptr(node);
2294 ir_node *mem = get_Store_mem(node);
2295 ir_graph *irg = current_ir_graph;
2296 dbg_info *dbgi = get_irn_dbg_info(node);
2300 ia32_address_t addr;
2302 assert(size % 4 == 0);
2305 build_address_ptr(&addr, ptr, mem);
2309 get_tarval_sub_bits(tv, ofs) |
2310 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2311 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2312 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2313 ir_node *imm = create_Immediate(NULL, 0, val);
2315 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2316 addr.index, addr.mem, imm);
2318 set_irn_pinned(new_node, get_irn_pinned(node));
2319 set_ia32_op_type(new_node, ia32_AddrModeD);
2320 set_ia32_ls_mode(new_node, mode_Iu);
2321 set_address(new_node, &addr);
2322 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2324 ins[i++] = new_node;
2329 } while (size != 0);
2331 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2335 * Generate a vfist or vfisttp instruction.
2337 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2338 ir_node *mem, ir_node *val, ir_node **fist)
2342 if (ia32_cg_config.use_fisttp) {
2343 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2344 if other users exists */
2345 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2346 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2347 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2348 be_new_Keep(reg_class, irg, block, 1, &value);
2350 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2353 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2356 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2362 * Transforms a normal Store.
2364 * @return the created ia32 Store node
2366 static ir_node *gen_normal_Store(ir_node *node)
2368 ir_node *val = get_Store_value(node);
2369 ir_mode *mode = get_irn_mode(val);
2370 ir_node *block = get_nodes_block(node);
2371 ir_node *new_block = be_transform_node(block);
2372 ir_node *ptr = get_Store_ptr(node);
2373 ir_node *mem = get_Store_mem(node);
2374 ir_graph *irg = current_ir_graph;
2375 dbg_info *dbgi = get_irn_dbg_info(node);
2376 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2377 ir_node *new_val, *new_node, *store;
2378 ia32_address_t addr;
2380 /* check for destination address mode */
2381 new_node = try_create_dest_am(node);
2382 if (new_node != NULL)
2385 /* construct store address */
2386 memset(&addr, 0, sizeof(addr));
2387 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2389 if (addr.base == NULL) {
2392 addr.base = be_transform_node(addr.base);
2395 if (addr.index == NULL) {
2398 addr.index = be_transform_node(addr.index);
2400 addr.mem = be_transform_node(mem);
2402 if (mode_is_float(mode)) {
2403 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2405 while (is_Conv(val) && mode == get_irn_mode(val)) {
2406 ir_node *op = get_Conv_op(val);
2407 if (!mode_is_float(get_irn_mode(op)))
2411 new_val = be_transform_node(val);
2412 if (ia32_cg_config.use_sse2) {
2413 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2414 addr.index, addr.mem, new_val);
2416 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2417 addr.index, addr.mem, new_val, mode);
2420 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2421 val = get_Conv_op(val);
2423 /* TODO: is this optimisation still necessary at all (middleend)? */
2424 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2425 while (is_Conv(val)) {
2426 ir_node *op = get_Conv_op(val);
2427 if (!mode_is_float(get_irn_mode(op)))
2429 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2433 new_val = be_transform_node(val);
2434 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2436 new_val = create_immediate_or_transform(val, 0);
2437 assert(mode != mode_b);
2439 if (get_mode_size_bits(mode) == 8) {
2440 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2441 addr.index, addr.mem, new_val);
2443 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2444 addr.index, addr.mem, new_val);
2449 set_irn_pinned(store, get_irn_pinned(node));
2450 set_ia32_op_type(store, ia32_AddrModeD);
2451 set_ia32_ls_mode(store, mode);
2453 set_address(store, &addr);
2454 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2460 * Transforms a Store.
2462 * @return the created ia32 Store node
2464 static ir_node *gen_Store(ir_node *node)
2466 ir_node *val = get_Store_value(node);
2467 ir_mode *mode = get_irn_mode(val);
2469 if (mode_is_float(mode) && is_Const(val)) {
2472 /* we are storing a floating point constant */
2473 if (ia32_cg_config.use_sse2) {
2474 transform = !is_simple_sse_Const(val);
2476 transform = !is_simple_x87_Const(val);
2479 return gen_float_const_Store(node, val);
2481 return gen_normal_Store(node);
2485 * Transforms a Switch.
2487 * @return the created ia32 SwitchJmp node
2489 static ir_node *create_Switch(ir_node *node)
2491 ir_graph *irg = current_ir_graph;
2492 dbg_info *dbgi = get_irn_dbg_info(node);
2493 ir_node *block = be_transform_node(get_nodes_block(node));
2494 ir_node *sel = get_Cond_selector(node);
2495 ir_node *new_sel = be_transform_node(sel);
2496 int switch_min = INT_MAX;
2497 int switch_max = INT_MIN;
2498 long default_pn = get_Cond_defaultProj(node);
2500 const ir_edge_t *edge;
2502 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2504 /* determine the smallest switch case value */
2505 foreach_out_edge(node, edge) {
2506 ir_node *proj = get_edge_src_irn(edge);
2507 long pn = get_Proj_proj(proj);
2508 if(pn == default_pn)
2517 if((unsigned) (switch_max - switch_min) > 256000) {
2518 panic("Size of switch %+F bigger than 256000", node);
2521 if (switch_min != 0) {
2522 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2524 /* if smallest switch case is not 0 we need an additional sub */
2525 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2526 add_ia32_am_offs_int(new_sel, -switch_min);
2527 set_ia32_op_type(new_sel, ia32_AddrModeS);
2529 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2532 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2533 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2539 * Transform a Cond node.
2541 static ir_node *gen_Cond(ir_node *node) {
2542 ir_node *block = get_nodes_block(node);
2543 ir_node *new_block = be_transform_node(block);
2544 ir_graph *irg = current_ir_graph;
2545 dbg_info *dbgi = get_irn_dbg_info(node);
2546 ir_node *sel = get_Cond_selector(node);
2547 ir_mode *sel_mode = get_irn_mode(sel);
2548 ir_node *flags = NULL;
2552 if (sel_mode != mode_b) {
2553 return create_Switch(node);
2556 /* we get flags from a Cmp */
2557 flags = get_flags_node(sel, &pnc);
2559 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2560 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2565 static ir_node *gen_be_Copy(ir_node *node)
2567 ir_node *new_node = be_duplicate_node(node);
2568 ir_mode *mode = get_irn_mode(new_node);
2570 if (ia32_mode_needs_gp_reg(mode)) {
2571 set_irn_mode(new_node, mode_Iu);
2577 static ir_node *create_Fucom(ir_node *node)
2579 ir_graph *irg = current_ir_graph;
2580 dbg_info *dbgi = get_irn_dbg_info(node);
2581 ir_node *block = get_nodes_block(node);
2582 ir_node *new_block = be_transform_node(block);
2583 ir_node *left = get_Cmp_left(node);
2584 ir_node *new_left = be_transform_node(left);
2585 ir_node *right = get_Cmp_right(node);
2589 if(ia32_cg_config.use_fucomi) {
2590 new_right = be_transform_node(right);
2591 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2593 set_ia32_commutative(new_node);
2594 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2596 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2597 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2600 new_right = be_transform_node(right);
2601 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2605 set_ia32_commutative(new_node);
2607 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2609 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2610 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2616 static ir_node *create_Ucomi(ir_node *node)
2618 ir_graph *irg = current_ir_graph;
2619 dbg_info *dbgi = get_irn_dbg_info(node);
2620 ir_node *src_block = get_nodes_block(node);
2621 ir_node *new_block = be_transform_node(src_block);
2622 ir_node *left = get_Cmp_left(node);
2623 ir_node *right = get_Cmp_right(node);
2625 ia32_address_mode_t am;
2626 ia32_address_t *addr = &am.addr;
2628 match_arguments(&am, src_block, left, right, NULL,
2629 match_commutative | match_am);
2631 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2632 addr->mem, am.new_op1, am.new_op2,
2634 set_am_attributes(new_node, &am);
2636 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2638 new_node = fix_mem_proj(new_node, &am);
2644 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2645 * to fold an and into a test node
2647 static bool can_fold_test_and(ir_node *node)
2649 const ir_edge_t *edge;
2651 /** we can only have eq and lg projs */
2652 foreach_out_edge(node, edge) {
2653 ir_node *proj = get_edge_src_irn(edge);
2654 pn_Cmp pnc = get_Proj_proj(proj);
2655 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2663 * returns true if it is assured, that the upper bits of a node are "clean"
2664 * which means for a 16 or 8 bit value, that the upper bits in the register
2665 * are 0 for unsigned and a copy of the last significant bit for signed
2668 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2670 assert(ia32_mode_needs_gp_reg(mode));
2671 if (get_mode_size_bits(mode) >= 32)
2674 if (is_Proj(transformed_node))
2675 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2677 if (is_ia32_Conv_I2I(transformed_node)
2678 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2679 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2680 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2682 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2688 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2689 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2690 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2691 const ia32_immediate_attr_t *attr
2692 = get_ia32_immediate_attr_const(right);
2693 if (attr->symconst == 0
2694 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2698 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2701 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2702 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2703 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2704 const ia32_immediate_attr_t *attr
2705 = get_ia32_immediate_attr_const(right);
2706 if (attr->symconst == 0
2707 && (unsigned) attr->offset
2708 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2715 /* TODO recurse on Or, Xor, ... if appropriate? */
2717 if (is_ia32_Immediate(transformed_node)
2718 || is_ia32_Const(transformed_node)) {
2719 const ia32_immediate_attr_t *attr
2720 = get_ia32_immediate_attr_const(transformed_node);
2721 if (mode_is_signed(mode)) {
2722 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2723 if (shifted == 0 || shifted == -1)
2726 unsigned long shifted = (unsigned long) attr->offset;
2727 shifted >>= get_mode_size_bits(mode);
2737 * Generate code for a Cmp.
2739 static ir_node *gen_Cmp(ir_node *node)
2741 ir_graph *irg = current_ir_graph;
2742 dbg_info *dbgi = get_irn_dbg_info(node);
2743 ir_node *block = get_nodes_block(node);
2744 ir_node *new_block = be_transform_node(block);
2745 ir_node *left = get_Cmp_left(node);
2746 ir_node *right = get_Cmp_right(node);
2747 ir_mode *cmp_mode = get_irn_mode(left);
2749 ia32_address_mode_t am;
2750 ia32_address_t *addr = &am.addr;
2753 if(mode_is_float(cmp_mode)) {
2754 if (ia32_cg_config.use_sse2) {
2755 return create_Ucomi(node);
2757 return create_Fucom(node);
2761 assert(ia32_mode_needs_gp_reg(cmp_mode));
2763 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2764 cmp_unsigned = !mode_is_signed(cmp_mode);
2765 if (is_Const_0(right) &&
2767 get_irn_n_edges(left) == 1 &&
2768 can_fold_test_and(node)) {
2769 /* Test(and_left, and_right) */
2770 ir_node *and_left = get_And_left(left);
2771 ir_node *and_right = get_And_right(left);
2773 /* matze: code here used mode instead of cmd_mode, I think it is always
2774 * the same as cmp_mode, but I leave this here to see if this is really
2777 assert(get_irn_mode(and_left) == cmp_mode);
2779 match_arguments(&am, block, and_left, and_right, NULL,
2781 match_am | match_8bit_am | match_16bit_am |
2782 match_am_and_immediates | match_immediate |
2783 match_8bit | match_16bit);
2785 /* use 32bit compare mode if possible since the opcode is smaller */
2786 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2787 upper_bits_clean(am.new_op2, cmp_mode)) {
2788 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2791 if (get_mode_size_bits(cmp_mode) == 8) {
2792 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2793 addr->index, addr->mem, am.new_op1,
2794 am.new_op2, am.ins_permuted,
2797 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2798 addr->index, addr->mem, am.new_op1,
2799 am.new_op2, am.ins_permuted,
2803 /* Cmp(left, right) */
2804 match_arguments(&am, block, left, right, NULL,
2805 match_commutative | match_am | match_8bit_am |
2806 match_16bit_am | match_am_and_immediates |
2807 match_immediate | match_8bit | match_16bit);
2808 /* use 32bit compare mode if possible since the opcode is smaller */
2809 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2810 upper_bits_clean(am.new_op2, cmp_mode)) {
2811 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2814 if (get_mode_size_bits(cmp_mode) == 8) {
2815 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2816 addr->index, addr->mem, am.new_op1,
2817 am.new_op2, am.ins_permuted,
2820 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2821 addr->index, addr->mem, am.new_op1,
2822 am.new_op2, am.ins_permuted, cmp_unsigned);
2825 set_am_attributes(new_node, &am);
2826 set_ia32_ls_mode(new_node, cmp_mode);
2828 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2830 new_node = fix_mem_proj(new_node, &am);
2835 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2838 ir_graph *irg = current_ir_graph;
2839 dbg_info *dbgi = get_irn_dbg_info(node);
2840 ir_node *block = get_nodes_block(node);
2841 ir_node *new_block = be_transform_node(block);
2842 ir_node *val_true = get_Mux_true(node);
2843 ir_node *val_false = get_Mux_false(node);
2845 match_flags_t match_flags;
2846 ia32_address_mode_t am;
2847 ia32_address_t *addr;
2849 assert(ia32_cg_config.use_cmov);
2850 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2854 match_flags = match_commutative | match_am | match_16bit_am |
2857 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2859 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2860 addr->mem, am.new_op1, am.new_op2, new_flags,
2861 am.ins_permuted, pnc);
2862 set_am_attributes(new_node, &am);
2864 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2866 new_node = fix_mem_proj(new_node, &am);
2872 * Creates a ia32 Setcc instruction.
2874 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2875 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2878 ir_graph *irg = current_ir_graph;
2879 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2880 ir_node *nomem = new_NoMem();
2881 ir_mode *mode = get_irn_mode(orig_node);
2884 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2885 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2887 /* we might need to conv the result up */
2888 if (get_mode_size_bits(mode) > 8) {
2889 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2890 nomem, new_node, mode_Bu);
2891 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2898 * Create instruction for an unsigned Difference or Zero.
2900 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2901 ir_graph *irg = current_ir_graph;
2902 ir_mode *mode = get_irn_mode(psi);
2903 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2906 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2907 match_mode_neutral | match_am | match_immediate | match_two_users);
2909 block = get_nodes_block(new_node);
2911 if (is_Proj(new_node)) {
2912 sub = get_Proj_pred(new_node);
2913 assert(is_ia32_Sub(sub));
2916 set_irn_mode(sub, mode_T);
2917 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2919 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2921 dbgi = get_irn_dbg_info(psi);
2922 noreg = ia32_new_NoReg_gp(env_cg);
2923 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2924 nomem = new_NoMem();
2925 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2927 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2928 set_ia32_commutative(new_node);
2933 * Transforms a Mux node into CMov.
2935 * @return The transformed node.
2937 static ir_node *gen_Mux(ir_node *node)
2939 dbg_info *dbgi = get_irn_dbg_info(node);
2940 ir_node *block = get_nodes_block(node);
2941 ir_node *new_block = be_transform_node(block);
2942 ir_node *mux_true = get_Mux_true(node);
2943 ir_node *mux_false = get_Mux_false(node);
2944 ir_node *cond = get_Mux_sel(node);
2945 ir_mode *mode = get_irn_mode(node);
2948 assert(get_irn_mode(cond) == mode_b);
2950 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2951 if (mode_is_float(mode)) {
2952 ir_node *cmp = get_Proj_pred(cond);
2953 ir_node *cmp_left = get_Cmp_left(cmp);
2954 ir_node *cmp_right = get_Cmp_right(cmp);
2955 pn_Cmp pnc = get_Proj_proj(cond);
2957 if (ia32_cg_config.use_sse2) {
2958 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2959 if (cmp_left == mux_true && cmp_right == mux_false) {
2960 /* Mux(a <= b, a, b) => MIN */
2961 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2962 match_commutative | match_am | match_two_users);
2963 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2964 /* Mux(a <= b, b, a) => MAX */
2965 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2966 match_commutative | match_am | match_two_users);
2968 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2969 if (cmp_left == mux_true && cmp_right == mux_false) {
2970 /* Mux(a >= b, a, b) => MAX */
2971 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2972 match_commutative | match_am | match_two_users);
2973 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2974 /* Mux(a >= b, b, a) => MIN */
2975 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2976 match_commutative | match_am | match_two_users);
2980 panic("cannot transform floating point Mux");
2986 assert(ia32_mode_needs_gp_reg(mode));
2988 if (is_Proj(cond)) {
2989 ir_node *cmp = get_Proj_pred(cond);
2991 ir_node *cmp_left = get_Cmp_left(cmp);
2992 ir_node *cmp_right = get_Cmp_right(cmp);
2993 pn_Cmp pnc = get_Proj_proj(cond);
2995 /* check for unsigned Doz first */
2996 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2997 is_Const_0(mux_false) && is_Sub(mux_true) &&
2998 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2999 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3000 return create_Doz(node, cmp_left, cmp_right);
3001 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3002 is_Const_0(mux_true) && is_Sub(mux_false) &&
3003 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3004 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3005 return create_Doz(node, cmp_left, cmp_right);
3010 flags = get_flags_node(cond, &pnc);
3012 if (is_Const(mux_true) && is_Const(mux_false)) {
3013 /* both are const, good */
3014 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3015 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3016 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3017 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3019 /* Not that simple. */
3024 new_node = create_CMov(node, cond, flags, pnc);
3032 * Create a conversion from x87 state register to general purpose.
3034 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3035 ir_node *block = be_transform_node(get_nodes_block(node));
3036 ir_node *op = get_Conv_op(node);
3037 ir_node *new_op = be_transform_node(op);
3038 ia32_code_gen_t *cg = env_cg;
3039 ir_graph *irg = current_ir_graph;
3040 dbg_info *dbgi = get_irn_dbg_info(node);
3041 ir_node *noreg = ia32_new_NoReg_gp(cg);
3042 ir_mode *mode = get_irn_mode(node);
3043 ir_node *fist, *load, *mem;
3045 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3046 set_irn_pinned(fist, op_pin_state_floats);
3047 set_ia32_use_frame(fist);
3048 set_ia32_op_type(fist, ia32_AddrModeD);
3050 assert(get_mode_size_bits(mode) <= 32);
3051 /* exception we can only store signed 32 bit integers, so for unsigned
3052 we store a 64bit (signed) integer and load the lower bits */
3053 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3054 set_ia32_ls_mode(fist, mode_Ls);
3056 set_ia32_ls_mode(fist, mode_Is);
3058 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3061 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3063 set_irn_pinned(load, op_pin_state_floats);
3064 set_ia32_use_frame(load);
3065 set_ia32_op_type(load, ia32_AddrModeS);
3066 set_ia32_ls_mode(load, mode_Is);
3067 if(get_ia32_ls_mode(fist) == mode_Ls) {
3068 ia32_attr_t *attr = get_ia32_attr(load);
3069 attr->data.need_64bit_stackent = 1;
3071 ia32_attr_t *attr = get_ia32_attr(load);
3072 attr->data.need_32bit_stackent = 1;
3074 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3076 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3080 * Creates a x87 strict Conv by placing a Store and a Load
3082 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3084 ir_node *block = get_nodes_block(node);
3085 ir_graph *irg = current_ir_graph;
3086 dbg_info *dbgi = get_irn_dbg_info(node);
3087 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3088 ir_node *nomem = new_NoMem();
3089 ir_node *frame = get_irg_frame(irg);
3090 ir_node *store, *load;
3093 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3095 set_ia32_use_frame(store);
3096 set_ia32_op_type(store, ia32_AddrModeD);
3097 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3099 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3101 set_ia32_use_frame(load);
3102 set_ia32_op_type(load, ia32_AddrModeS);
3103 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3105 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3110 * Create a conversion from general purpose to x87 register
3112 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3113 ir_node *src_block = get_nodes_block(node);
3114 ir_node *block = be_transform_node(src_block);
3115 ir_graph *irg = current_ir_graph;
3116 dbg_info *dbgi = get_irn_dbg_info(node);
3117 ir_node *op = get_Conv_op(node);
3118 ir_node *new_op = NULL;
3122 ir_mode *store_mode;
3128 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3129 if (src_mode == mode_Is || src_mode == mode_Hs) {
3130 ia32_address_mode_t am;
3132 match_arguments(&am, src_block, NULL, op, NULL,
3133 match_am | match_try_am | match_16bit | match_16bit_am);
3134 if (am.op_type == ia32_AddrModeS) {
3135 ia32_address_t *addr = &am.addr;
3137 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3138 addr->index, addr->mem);
3139 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3142 set_am_attributes(fild, &am);
3143 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3145 fix_mem_proj(fild, &am);
3150 if(new_op == NULL) {
3151 new_op = be_transform_node(op);
3154 noreg = ia32_new_NoReg_gp(env_cg);
3155 nomem = new_NoMem();
3156 mode = get_irn_mode(op);
3158 /* first convert to 32 bit signed if necessary */
3159 src_bits = get_mode_size_bits(src_mode);
3160 if (src_bits == 8) {
3161 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3163 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3165 } else if (src_bits < 32) {
3166 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3168 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3172 assert(get_mode_size_bits(mode) == 32);
3175 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3178 set_ia32_use_frame(store);
3179 set_ia32_op_type(store, ia32_AddrModeD);
3180 set_ia32_ls_mode(store, mode_Iu);
3182 /* exception for 32bit unsigned, do a 64bit spill+load */
3183 if(!mode_is_signed(mode)) {
3186 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3188 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3189 get_irg_frame(irg), noreg, nomem,
3192 set_ia32_use_frame(zero_store);
3193 set_ia32_op_type(zero_store, ia32_AddrModeD);
3194 add_ia32_am_offs_int(zero_store, 4);
3195 set_ia32_ls_mode(zero_store, mode_Iu);
3200 store = new_rd_Sync(dbgi, irg, block, 2, in);
3201 store_mode = mode_Ls;
3203 store_mode = mode_Is;
3207 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3209 set_ia32_use_frame(fild);
3210 set_ia32_op_type(fild, ia32_AddrModeS);
3211 set_ia32_ls_mode(fild, store_mode);
3213 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3219 * Create a conversion from one integer mode into another one
3221 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3222 dbg_info *dbgi, ir_node *block, ir_node *op,
3225 ir_graph *irg = current_ir_graph;
3226 int src_bits = get_mode_size_bits(src_mode);
3227 int tgt_bits = get_mode_size_bits(tgt_mode);
3228 ir_node *new_block = be_transform_node(block);
3230 ir_mode *smaller_mode;
3232 ia32_address_mode_t am;
3233 ia32_address_t *addr = &am.addr;
3236 if (src_bits < tgt_bits) {
3237 smaller_mode = src_mode;
3238 smaller_bits = src_bits;
3240 smaller_mode = tgt_mode;
3241 smaller_bits = tgt_bits;
3244 #ifdef DEBUG_libfirm
3246 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3251 match_arguments(&am, block, NULL, op, NULL,
3252 match_8bit | match_16bit |
3253 match_am | match_8bit_am | match_16bit_am);
3255 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3256 /* unnecessary conv. in theory it shouldn't have been AM */
3257 assert(is_ia32_NoReg_GP(addr->base));
3258 assert(is_ia32_NoReg_GP(addr->index));
3259 assert(is_NoMem(addr->mem));
3260 assert(am.addr.offset == 0);
3261 assert(am.addr.symconst_ent == NULL);
3265 if (smaller_bits == 8) {
3266 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3267 addr->index, addr->mem, am.new_op2,
3270 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3271 addr->index, addr->mem, am.new_op2,
3274 set_am_attributes(new_node, &am);
3275 /* match_arguments assume that out-mode = in-mode, this isn't true here
3277 set_ia32_ls_mode(new_node, smaller_mode);
3278 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3279 new_node = fix_mem_proj(new_node, &am);
3284 * Transforms a Conv node.
3286 * @return The created ia32 Conv node
3288 static ir_node *gen_Conv(ir_node *node) {
3289 ir_node *block = get_nodes_block(node);
3290 ir_node *new_block = be_transform_node(block);
3291 ir_node *op = get_Conv_op(node);
3292 ir_node *new_op = NULL;
3293 ir_graph *irg = current_ir_graph;
3294 dbg_info *dbgi = get_irn_dbg_info(node);
3295 ir_mode *src_mode = get_irn_mode(op);
3296 ir_mode *tgt_mode = get_irn_mode(node);
3297 int src_bits = get_mode_size_bits(src_mode);
3298 int tgt_bits = get_mode_size_bits(tgt_mode);
3299 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3300 ir_node *nomem = new_rd_NoMem(irg);
3301 ir_node *res = NULL;
3303 if (src_mode == mode_b) {
3304 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3305 /* nothing to do, we already model bools as 0/1 ints */
3306 return be_transform_node(op);
3309 if (src_mode == tgt_mode) {
3310 if (get_Conv_strict(node)) {
3311 if (ia32_cg_config.use_sse2) {
3312 /* when we are in SSE mode, we can kill all strict no-op conversion */
3313 return be_transform_node(op);
3316 /* this should be optimized already, but who knows... */
3317 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3318 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3319 return be_transform_node(op);
3323 if (mode_is_float(src_mode)) {
3324 new_op = be_transform_node(op);
3325 /* we convert from float ... */
3326 if (mode_is_float(tgt_mode)) {
3327 if(src_mode == mode_E && tgt_mode == mode_D
3328 && !get_Conv_strict(node)) {
3329 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3334 if (ia32_cg_config.use_sse2) {
3335 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3336 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3338 set_ia32_ls_mode(res, tgt_mode);
3340 if(get_Conv_strict(node)) {
3341 res = gen_x87_strict_conv(tgt_mode, new_op);
3342 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3345 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3350 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3351 if (ia32_cg_config.use_sse2) {
3352 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3354 set_ia32_ls_mode(res, src_mode);
3356 return gen_x87_fp_to_gp(node);
3360 /* we convert from int ... */
3361 if (mode_is_float(tgt_mode)) {
3363 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3364 if (ia32_cg_config.use_sse2) {
3365 new_op = be_transform_node(op);
3366 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3368 set_ia32_ls_mode(res, tgt_mode);
3370 res = gen_x87_gp_to_fp(node, src_mode);
3371 if(get_Conv_strict(node)) {
3372 /* The strict-Conv is only necessary, if the int mode has more bits
3373 * than the float mantissa */
3374 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3375 size_t float_mantissa;
3376 /* FIXME There is no way to get the mantissa size of a mode */
3377 switch (get_mode_size_bits(tgt_mode)) {
3378 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3379 case 64: float_mantissa = 52 + 1; break;
3381 case 96: float_mantissa = 64; break;
3382 default: float_mantissa = 0; break;
3384 if (float_mantissa < int_mantissa) {
3385 res = gen_x87_strict_conv(tgt_mode, res);
3386 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3391 } else if(tgt_mode == mode_b) {
3392 /* mode_b lowering already took care that we only have 0/1 values */
3393 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3394 src_mode, tgt_mode));
3395 return be_transform_node(op);
3398 if (src_bits == tgt_bits) {
3399 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3400 src_mode, tgt_mode));
3401 return be_transform_node(op);
3404 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3412 static ir_node *create_immediate_or_transform(ir_node *node,
3413 char immediate_constraint_type)
3415 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3416 if (new_node == NULL) {
3417 new_node = be_transform_node(node);
3423 * Transforms a FrameAddr into an ia32 Add.
3425 static ir_node *gen_be_FrameAddr(ir_node *node) {
3426 ir_node *block = be_transform_node(get_nodes_block(node));
3427 ir_node *op = be_get_FrameAddr_frame(node);
3428 ir_node *new_op = be_transform_node(op);
3429 ir_graph *irg = current_ir_graph;
3430 dbg_info *dbgi = get_irn_dbg_info(node);
3431 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3434 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3435 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3436 set_ia32_use_frame(new_node);
3438 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3444 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3446 static ir_node *gen_be_Return(ir_node *node) {
3447 ir_graph *irg = current_ir_graph;
3448 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3449 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3450 ir_entity *ent = get_irg_entity(irg);
3451 ir_type *tp = get_entity_type(ent);
3456 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3457 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3460 int pn_ret_val, pn_ret_mem, arity, i;
3462 assert(ret_val != NULL);
3463 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3464 return be_duplicate_node(node);
3467 res_type = get_method_res_type(tp, 0);
3469 if (! is_Primitive_type(res_type)) {
3470 return be_duplicate_node(node);
3473 mode = get_type_mode(res_type);
3474 if (! mode_is_float(mode)) {
3475 return be_duplicate_node(node);
3478 assert(get_method_n_ress(tp) == 1);
3480 pn_ret_val = get_Proj_proj(ret_val);
3481 pn_ret_mem = get_Proj_proj(ret_mem);
3483 /* get the Barrier */
3484 barrier = get_Proj_pred(ret_val);
3486 /* get result input of the Barrier */
3487 ret_val = get_irn_n(barrier, pn_ret_val);
3488 new_ret_val = be_transform_node(ret_val);
3490 /* get memory input of the Barrier */
3491 ret_mem = get_irn_n(barrier, pn_ret_mem);
3492 new_ret_mem = be_transform_node(ret_mem);
3494 frame = get_irg_frame(irg);
3496 dbgi = get_irn_dbg_info(barrier);
3497 block = be_transform_node(get_nodes_block(barrier));
3499 noreg = ia32_new_NoReg_gp(env_cg);
3501 /* store xmm0 onto stack */
3502 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3503 new_ret_mem, new_ret_val);
3504 set_ia32_ls_mode(sse_store, mode);
3505 set_ia32_op_type(sse_store, ia32_AddrModeD);
3506 set_ia32_use_frame(sse_store);
3508 /* load into x87 register */
3509 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3510 set_ia32_op_type(fld, ia32_AddrModeS);
3511 set_ia32_use_frame(fld);
3513 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3514 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3516 /* create a new barrier */
3517 arity = get_irn_arity(barrier);
3518 in = alloca(arity * sizeof(in[0]));
3519 for (i = 0; i < arity; ++i) {
3522 if (i == pn_ret_val) {
3524 } else if (i == pn_ret_mem) {
3527 ir_node *in = get_irn_n(barrier, i);
3528 new_in = be_transform_node(in);
3533 new_barrier = new_ir_node(dbgi, irg, block,
3534 get_irn_op(barrier), get_irn_mode(barrier),
3536 copy_node_attr(barrier, new_barrier);
3537 be_duplicate_deps(barrier, new_barrier);
3538 set_transformed_and_mark(barrier, new_barrier);
3540 /* transform normally */
3541 return be_duplicate_node(node);
3545 * Transform a be_AddSP into an ia32_SubSP.
3547 static ir_node *gen_be_AddSP(ir_node *node)
3549 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3550 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3552 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3553 match_am | match_immediate);
3557 * Transform a be_SubSP into an ia32_AddSP
3559 static ir_node *gen_be_SubSP(ir_node *node)
3561 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3562 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3564 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3565 match_am | match_immediate);
3569 * Change some phi modes
3571 static ir_node *gen_Phi(ir_node *node) {
3572 ir_node *block = be_transform_node(get_nodes_block(node));
3573 ir_graph *irg = current_ir_graph;
3574 dbg_info *dbgi = get_irn_dbg_info(node);
3575 ir_mode *mode = get_irn_mode(node);
3578 if(ia32_mode_needs_gp_reg(mode)) {
3579 /* we shouldn't have any 64bit stuff around anymore */
3580 assert(get_mode_size_bits(mode) <= 32);
3581 /* all integer operations are on 32bit registers now */
3583 } else if(mode_is_float(mode)) {
3584 if (ia32_cg_config.use_sse2) {
3591 /* phi nodes allow loops, so we use the old arguments for now
3592 * and fix this later */
3593 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3594 get_irn_in(node) + 1);
3595 copy_node_attr(node, phi);
3596 be_duplicate_deps(node, phi);
3598 be_enqueue_preds(node);
3606 static ir_node *gen_IJmp(ir_node *node)
3608 ir_node *block = get_nodes_block(node);
3609 ir_node *new_block = be_transform_node(block);
3610 dbg_info *dbgi = get_irn_dbg_info(node);
3611 ir_node *op = get_IJmp_target(node);
3613 ia32_address_mode_t am;
3614 ia32_address_t *addr = &am.addr;
3616 assert(get_irn_mode(op) == mode_P);
3618 match_arguments(&am, block, NULL, op, NULL,
3619 match_am | match_8bit_am | match_16bit_am |
3620 match_immediate | match_8bit | match_16bit);
3622 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3623 addr->base, addr->index, addr->mem,
3625 set_am_attributes(new_node, &am);
3626 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3628 new_node = fix_mem_proj(new_node, &am);
3634 * Transform a Bound node.
3636 static ir_node *gen_Bound(ir_node *node)
3639 ir_node *lower = get_Bound_lower(node);
3640 dbg_info *dbgi = get_irn_dbg_info(node);
3642 if (is_Const_0(lower)) {
3643 /* typical case for Java */
3644 ir_node *sub, *res, *flags, *block;
3645 ir_graph *irg = current_ir_graph;
3647 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3648 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3650 block = get_nodes_block(res);
3651 if (! is_Proj(res)) {
3653 set_irn_mode(sub, mode_T);
3654 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3656 sub = get_Proj_pred(res);
3658 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3659 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3660 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3662 panic("generic Bound not supported in ia32 Backend");
3668 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3670 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3671 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3673 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3674 match_immediate | match_mode_neutral);
3677 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3679 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3680 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3681 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3685 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3687 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3688 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3689 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3693 static ir_node *gen_ia32_l_Add(ir_node *node) {
3694 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3695 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3696 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3697 match_commutative | match_am | match_immediate |
3698 match_mode_neutral);
3700 if(is_Proj(lowered)) {
3701 lowered = get_Proj_pred(lowered);
3703 assert(is_ia32_Add(lowered));
3704 set_irn_mode(lowered, mode_T);
3710 static ir_node *gen_ia32_l_Adc(ir_node *node)
3712 return gen_binop_flags(node, new_rd_ia32_Adc,
3713 match_commutative | match_am | match_immediate |
3714 match_mode_neutral);
3718 * Transforms a l_MulS into a "real" MulS node.
3720 * @return the created ia32 Mul node
3722 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3723 ir_node *left = get_binop_left(node);
3724 ir_node *right = get_binop_right(node);
3726 return gen_binop(node, left, right, new_rd_ia32_Mul,
3727 match_commutative | match_am | match_mode_neutral);
3731 * Transforms a l_IMulS into a "real" IMul1OPS node.
3733 * @return the created ia32 IMul1OP node
3735 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3736 ir_node *left = get_binop_left(node);
3737 ir_node *right = get_binop_right(node);
3739 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3740 match_commutative | match_am | match_mode_neutral);
3743 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3744 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3745 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3746 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3747 match_am | match_immediate | match_mode_neutral);
3749 if(is_Proj(lowered)) {
3750 lowered = get_Proj_pred(lowered);
3752 assert(is_ia32_Sub(lowered));
3753 set_irn_mode(lowered, mode_T);
3759 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3760 return gen_binop_flags(node, new_rd_ia32_Sbb,
3761 match_am | match_immediate | match_mode_neutral);
3765 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3766 * op1 - target to be shifted
3767 * op2 - contains bits to be shifted into target
3769 * Only op3 can be an immediate.
3771 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3772 ir_node *low, ir_node *count)
3774 ir_node *block = get_nodes_block(node);
3775 ir_node *new_block = be_transform_node(block);
3776 ir_graph *irg = current_ir_graph;
3777 dbg_info *dbgi = get_irn_dbg_info(node);
3778 ir_node *new_high = be_transform_node(high);
3779 ir_node *new_low = be_transform_node(low);
3783 /* the shift amount can be any mode that is bigger than 5 bits, since all
3784 * other bits are ignored anyway */
3785 while (is_Conv(count) &&
3786 get_irn_n_edges(count) == 1 &&
3787 mode_is_int(get_irn_mode(count))) {
3788 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3789 count = get_Conv_op(count);
3791 new_count = create_immediate_or_transform(count, 0);
3793 if (is_ia32_l_ShlD(node)) {
3794 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3797 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3800 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3805 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3807 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3808 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3809 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3810 return gen_lowered_64bit_shifts(node, high, low, count);
3813 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3815 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3816 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3817 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3818 return gen_lowered_64bit_shifts(node, high, low, count);
3821 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3822 ir_node *src_block = get_nodes_block(node);
3823 ir_node *block = be_transform_node(src_block);
3824 ir_graph *irg = current_ir_graph;
3825 dbg_info *dbgi = get_irn_dbg_info(node);
3826 ir_node *frame = get_irg_frame(irg);
3827 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3828 ir_node *nomem = new_NoMem();
3829 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3830 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3831 ir_node *new_val_low = be_transform_node(val_low);
3832 ir_node *new_val_high = be_transform_node(val_high);
3837 ir_node *store_high;
3839 if(!mode_is_signed(get_irn_mode(val_high))) {
3840 panic("unsigned long long -> float not supported yet (%+F)", node);
3844 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3846 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3848 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3849 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3851 set_ia32_use_frame(store_low);
3852 set_ia32_use_frame(store_high);
3853 set_ia32_op_type(store_low, ia32_AddrModeD);
3854 set_ia32_op_type(store_high, ia32_AddrModeD);
3855 set_ia32_ls_mode(store_low, mode_Iu);
3856 set_ia32_ls_mode(store_high, mode_Is);
3857 add_ia32_am_offs_int(store_high, 4);
3861 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3864 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3866 set_ia32_use_frame(fild);
3867 set_ia32_op_type(fild, ia32_AddrModeS);
3868 set_ia32_ls_mode(fild, mode_Ls);
3870 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3872 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3875 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3876 ir_node *src_block = get_nodes_block(node);
3877 ir_node *block = be_transform_node(src_block);
3878 ir_graph *irg = current_ir_graph;
3879 dbg_info *dbgi = get_irn_dbg_info(node);
3880 ir_node *frame = get_irg_frame(irg);
3881 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3882 ir_node *nomem = new_NoMem();
3883 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3884 ir_node *new_val = be_transform_node(val);
3885 ir_node *fist, *mem;
3887 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3888 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3889 set_ia32_use_frame(fist);
3890 set_ia32_op_type(fist, ia32_AddrModeD);
3891 set_ia32_ls_mode(fist, mode_Ls);
3897 * the BAD transformer.
3899 static ir_node *bad_transform(ir_node *node) {
3900 panic("No transform function for %+F available.", node);
3904 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
3905 ir_graph *irg = current_ir_graph;
3906 ir_node *block = be_transform_node(get_nodes_block(node));
3907 ir_node *pred = get_Proj_pred(node);
3908 ir_node *new_pred = be_transform_node(pred);
3909 ir_node *frame = get_irg_frame(irg);
3910 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3911 dbg_info *dbgi = get_irn_dbg_info(node);
3912 long pn = get_Proj_proj(node);
3917 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3918 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3919 set_ia32_use_frame(load);
3920 set_ia32_op_type(load, ia32_AddrModeS);
3921 set_ia32_ls_mode(load, mode_Iu);
3922 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3923 * 32 bit from it with this particular load */
3924 attr = get_ia32_attr(load);
3925 attr->data.need_64bit_stackent = 1;
3927 if (pn == pn_ia32_l_FloattoLL_res_high) {
3928 add_ia32_am_offs_int(load, 4);
3930 assert(pn == pn_ia32_l_FloattoLL_res_low);
3933 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3939 * Transform the Projs of an AddSP.
3941 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(env_cg->arch_env, 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) {
3968 ir_node *block = be_transform_node(get_nodes_block(node));
3969 ir_node *pred = get_Proj_pred(node);
3970 ir_node *new_pred = be_transform_node(pred);
3971 ir_graph *irg = current_ir_graph;
3972 dbg_info *dbgi = get_irn_dbg_info(node);
3973 long proj = get_Proj_proj(node);
3975 if (proj == pn_be_SubSP_sp) {
3976 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3977 pn_ia32_AddSP_stack);
3978 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3980 } else if (proj == pn_be_SubSP_M) {
3981 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3984 panic("No idea how to transform proj->SubSP");
3988 * Transform and renumber the Projs from a Load.
3990 static ir_node *gen_Proj_Load(ir_node *node) {
3992 ir_node *block = be_transform_node(get_nodes_block(node));
3993 ir_node *pred = get_Proj_pred(node);
3994 ir_graph *irg = current_ir_graph;
3995 dbg_info *dbgi = get_irn_dbg_info(node);
3996 long proj = get_Proj_proj(node);
3998 /* loads might be part of source address mode matches, so we don't
3999 * transform the ProjMs yet (with the exception of loads whose result is
4002 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4005 /* this is needed, because sometimes we have loops that are only
4006 reachable through the ProjM */
4007 be_enqueue_preds(node);
4008 /* do it in 2 steps, to silence firm verifier */
4009 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4010 set_Proj_proj(res, pn_ia32_mem);
4014 /* renumber the proj */
4015 new_pred = be_transform_node(pred);
4016 if (is_ia32_Load(new_pred)) {
4019 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4021 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4022 case pn_Load_X_regular:
4023 return new_rd_Jmp(dbgi, irg, block);
4024 case pn_Load_X_except:
4025 /* This Load might raise an exception. Mark it. */
4026 set_ia32_exc_label(new_pred, 1);
4027 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4031 } else if (is_ia32_Conv_I2I(new_pred) ||
4032 is_ia32_Conv_I2I8Bit(new_pred)) {
4033 set_irn_mode(new_pred, mode_T);
4034 if (proj == pn_Load_res) {
4035 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4036 } else if (proj == pn_Load_M) {
4037 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4039 } else if (is_ia32_xLoad(new_pred)) {
4042 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4044 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4045 case pn_Load_X_regular:
4046 return new_rd_Jmp(dbgi, irg, block);
4047 case pn_Load_X_except:
4048 /* This Load might raise an exception. Mark it. */
4049 set_ia32_exc_label(new_pred, 1);
4050 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4054 } else if (is_ia32_vfld(new_pred)) {
4057 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4059 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4060 case pn_Load_X_regular:
4061 return new_rd_Jmp(dbgi, irg, block);
4062 case pn_Load_X_except:
4063 /* This Load might raise an exception. Mark it. */
4064 set_ia32_exc_label(new_pred, 1);
4065 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4070 /* can happen for ProJMs when source address mode happened for the
4073 /* however it should not be the result proj, as that would mean the
4074 load had multiple users and should not have been used for
4076 if (proj != pn_Load_M) {
4077 panic("internal error: transformed node not a Load");
4079 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4082 panic("No idea how to transform proj");
4086 * Transform and renumber the Projs from a DivMod like instruction.
4088 static ir_node *gen_Proj_DivMod(ir_node *node) {
4089 ir_node *block = be_transform_node(get_nodes_block(node));
4090 ir_node *pred = get_Proj_pred(node);
4091 ir_node *new_pred = be_transform_node(pred);
4092 ir_graph *irg = current_ir_graph;
4093 dbg_info *dbgi = get_irn_dbg_info(node);
4094 long proj = get_Proj_proj(node);
4096 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4098 switch (get_irn_opcode(pred)) {
4102 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4104 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4105 case pn_Div_X_regular:
4106 return new_rd_Jmp(dbgi, irg, block);
4107 case pn_Div_X_except:
4108 set_ia32_exc_label(new_pred, 1);
4109 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4117 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4119 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4120 case pn_Mod_X_except:
4121 set_ia32_exc_label(new_pred, 1);
4122 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4130 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4131 case pn_DivMod_res_div:
4132 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4133 case pn_DivMod_res_mod:
4134 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4135 case pn_DivMod_X_regular:
4136 return new_rd_Jmp(dbgi, irg, block);
4137 case pn_DivMod_X_except:
4138 set_ia32_exc_label(new_pred, 1);
4139 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4148 panic("No idea how to transform proj->DivMod");
4152 * Transform and renumber the Projs from a CopyB.
4154 static ir_node *gen_Proj_CopyB(ir_node *node) {
4155 ir_node *block = be_transform_node(get_nodes_block(node));
4156 ir_node *pred = get_Proj_pred(node);
4157 ir_node *new_pred = be_transform_node(pred);
4158 ir_graph *irg = current_ir_graph;
4159 dbg_info *dbgi = get_irn_dbg_info(node);
4160 long proj = get_Proj_proj(node);
4163 case pn_CopyB_M_regular:
4164 if (is_ia32_CopyB_i(new_pred)) {
4165 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4166 } else if (is_ia32_CopyB(new_pred)) {
4167 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4174 panic("No idea how to transform proj->CopyB");
4178 * Transform and renumber the Projs from a Quot.
4180 static ir_node *gen_Proj_Quot(ir_node *node) {
4181 ir_node *block = be_transform_node(get_nodes_block(node));
4182 ir_node *pred = get_Proj_pred(node);
4183 ir_node *new_pred = be_transform_node(pred);
4184 ir_graph *irg = current_ir_graph;
4185 dbg_info *dbgi = get_irn_dbg_info(node);
4186 long proj = get_Proj_proj(node);
4190 if (is_ia32_xDiv(new_pred)) {
4191 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4192 } else if (is_ia32_vfdiv(new_pred)) {
4193 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4197 if (is_ia32_xDiv(new_pred)) {
4198 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4199 } else if (is_ia32_vfdiv(new_pred)) {
4200 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4203 case pn_Quot_X_regular:
4204 case pn_Quot_X_except:
4209 panic("No idea how to transform proj->Quot");
4212 static ir_node *gen_be_Call(ir_node *node)
4214 dbg_info *const dbgi = get_irn_dbg_info(node);
4215 ir_graph *const irg = current_ir_graph;
4216 ir_node *const src_block = get_nodes_block(node);
4217 ir_node *const block = be_transform_node(src_block);
4218 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4219 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4220 ir_node *const sp = be_transform_node(src_sp);
4221 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4222 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4223 ia32_address_mode_t am;
4224 ia32_address_t *const addr = &am.addr;
4229 ir_node * eax = noreg;
4230 ir_node * ecx = noreg;
4231 ir_node * edx = noreg;
4232 unsigned const pop = be_Call_get_pop(node);
4233 ir_type *const call_tp = be_Call_get_type(node);
4235 /* Run the x87 simulator if the call returns a float value */
4236 if (get_method_n_ress(call_tp) > 0) {
4237 ir_type *const res_type = get_method_res_type(call_tp, 0);
4238 ir_mode *const res_mode = get_type_mode(res_type);
4240 if (res_mode != NULL && mode_is_float(res_mode)) {
4241 env_cg->do_x87_sim = 1;
4245 /* We do not want be_Call direct calls */
4246 assert(be_Call_get_entity(node) == NULL);
4248 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4249 match_am | match_immediate);
4251 i = get_irn_arity(node) - 1;
4252 fpcw = be_transform_node(get_irn_n(node, i--));
4253 for (; i >= be_pos_Call_first_arg; --i) {
4254 arch_register_req_t const *const req =
4255 arch_get_register_req(env_cg->arch_env, node, i);
4256 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4258 assert(req->type == arch_register_req_type_limited);
4259 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4261 switch (*req->limited) {
4262 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4263 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4264 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4265 default: panic("Invalid GP register for register parameter");
4269 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4270 call = new_rd_ia32_Call(dbgi, irg, block, addr->base, addr->index, mem,
4271 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4272 set_am_attributes(call, &am);
4273 call = fix_mem_proj(call, &am);
4275 if (get_irn_pinned(node) == op_pin_state_pinned)
4276 set_irn_pinned(call, op_pin_state_pinned);
4278 SET_IA32_ORIG_NODE(call, ia32_get_old_node_name(env_cg, node));
4282 static ir_node *gen_be_IncSP(ir_node *node) {
4283 ir_node *res = be_duplicate_node(node);
4284 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4290 * Transform the Projs from a be_Call.
4292 static ir_node *gen_Proj_be_Call(ir_node *node)
4294 ir_node *block = be_transform_node(get_nodes_block(node));
4295 ir_node *call = get_Proj_pred(node);
4296 ir_node *new_call = be_transform_node(call);
4297 ir_graph *irg = current_ir_graph;
4298 dbg_info *dbgi = get_irn_dbg_info(node);
4299 ir_type *method_type = be_Call_get_type(call);
4300 int n_res = get_method_n_ress(method_type);
4301 long proj = get_Proj_proj(node);
4302 ir_mode *mode = get_irn_mode(node);
4304 const arch_register_class_t *cls;
4307 /* The following is kinda tricky: If we're using SSE, then we have to
4308 * move the result value of the call in floating point registers to an
4309 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4310 * after the call, we have to make sure to correctly make the
4311 * MemProj and the result Proj use these 2 nodes
4313 if (proj == pn_be_Call_M_regular) {
4314 // get new node for result, are we doing the sse load/store hack?
4315 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4316 ir_node *call_res_new;
4317 ir_node *call_res_pred = NULL;
4319 if (call_res != NULL) {
4320 call_res_new = be_transform_node(call_res);
4321 call_res_pred = get_Proj_pred(call_res_new);
4324 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4325 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4328 assert(is_ia32_xLoad(call_res_pred));
4329 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4333 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4334 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4336 ir_node *frame = get_irg_frame(irg);
4337 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4339 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4342 /* in case there is no memory output: create one to serialize the copy
4344 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4345 pn_be_Call_M_regular);
4346 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4347 pn_be_Call_first_res);
4349 /* store st(0) onto stack */
4350 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4352 set_ia32_op_type(fstp, ia32_AddrModeD);
4353 set_ia32_use_frame(fstp);
4355 /* load into SSE register */
4356 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4358 set_ia32_op_type(sse_load, ia32_AddrModeS);
4359 set_ia32_use_frame(sse_load);
4361 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4367 /* transform call modes */
4368 if (mode_is_data(mode)) {
4369 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4373 /* Map from be_Call to ia32_Call proj number */
4374 if (proj == pn_be_Call_sp) {
4375 proj = pn_ia32_Call_stack;
4376 } else if (proj == pn_be_Call_M_regular) {
4377 proj = pn_ia32_Call_M;
4379 arch_register_req_t const *const req = arch_get_register_req(env_cg->arch_env, node, BE_OUT_POS(proj));
4380 int const n_outs = get_ia32_n_res(new_call);
4383 assert(proj >= pn_be_Call_first_res);
4384 assert(req->type == arch_register_req_type_limited);
4386 for (i = 0; i < n_outs; ++i) {
4387 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4389 if (new_req->type != arch_register_req_type_limited ||
4390 new_req->cls != req->cls ||
4391 *new_req->limited != *req->limited)
4400 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4402 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4404 case pn_ia32_Call_stack:
4405 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4408 case pn_ia32_Call_fpcw:
4409 arch_set_irn_register(env_cg->arch_env, res, &ia32_fp_cw_regs[REG_FPCW]);
4417 * Transform the Projs from a Cmp.
4419 static ir_node *gen_Proj_Cmp(ir_node *node)
4421 /* this probably means not all mode_b nodes were lowered... */
4422 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4427 * Transform the Projs from a Bound.
4429 static ir_node *gen_Proj_Bound(ir_node *node)
4431 ir_node *new_node, *block;
4432 ir_node *pred = get_Proj_pred(node);
4434 switch (get_Proj_proj(node)) {
4436 return be_transform_node(get_Bound_mem(pred));
4437 case pn_Bound_X_regular:
4438 new_node = be_transform_node(pred);
4439 block = get_nodes_block(new_node);
4440 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4441 case pn_Bound_X_except:
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_false);
4446 return be_transform_node(get_Bound_index(pred));
4448 panic("unsupported Proj from Bound");
4452 static ir_node *gen_Proj_ASM(ir_node *node)
4458 if (get_irn_mode(node) != mode_M)
4459 return be_duplicate_node(node);
4461 pred = get_Proj_pred(node);
4462 new_pred = be_transform_node(pred);
4463 block = get_nodes_block(new_pred);
4464 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4465 get_ia32_n_res(new_pred) + 1);
4469 * Transform and potentially renumber Proj nodes.
4471 static ir_node *gen_Proj(ir_node *node) {
4472 ir_node *pred = get_Proj_pred(node);
4475 switch (get_irn_opcode(pred)) {
4477 proj = get_Proj_proj(node);
4478 if (proj == pn_Store_M) {
4479 return be_transform_node(pred);
4481 panic("No idea how to transform proj->Store");
4484 return gen_Proj_Load(node);
4486 return gen_Proj_ASM(node);
4490 return gen_Proj_DivMod(node);
4492 return gen_Proj_CopyB(node);
4494 return gen_Proj_Quot(node);
4496 return gen_Proj_be_SubSP(node);
4498 return gen_Proj_be_AddSP(node);
4500 return gen_Proj_be_Call(node);
4502 return gen_Proj_Cmp(node);
4504 return gen_Proj_Bound(node);
4506 proj = get_Proj_proj(node);
4507 if (proj == pn_Start_X_initial_exec) {
4508 ir_node *block = get_nodes_block(pred);
4509 dbg_info *dbgi = get_irn_dbg_info(node);
4512 /* we exchange the ProjX with a jump */
4513 block = be_transform_node(block);
4514 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
4517 if (node == be_get_old_anchor(anchor_tls)) {
4518 return gen_Proj_tls(node);
4523 if (is_ia32_l_FloattoLL(pred)) {
4524 return gen_Proj_l_FloattoLL(node);
4526 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4530 ir_mode *mode = get_irn_mode(node);
4531 if (ia32_mode_needs_gp_reg(mode)) {
4532 ir_node *new_pred = be_transform_node(pred);
4533 ir_node *block = be_transform_node(get_nodes_block(node));
4534 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4535 mode_Iu, get_Proj_proj(node));
4536 #ifdef DEBUG_libfirm
4537 new_proj->node_nr = node->node_nr;
4543 return be_duplicate_node(node);
4547 * Enters all transform functions into the generic pointer
4549 static void register_transformers(void)
4553 /* first clear the generic function pointer for all ops */
4554 clear_irp_opcodes_generic_func();
4556 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4557 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4595 /* transform ops from intrinsic lowering */
4607 GEN(ia32_l_LLtoFloat);
4608 GEN(ia32_l_FloattoLL);
4614 /* we should never see these nodes */
4629 /* handle generic backend nodes */
4638 op_Mulh = get_op_Mulh();
4647 * Pre-transform all unknown and noreg nodes.
4649 static void ia32_pretransform_node(void *arch_cg) {
4650 ia32_code_gen_t *cg = arch_cg;
4652 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4653 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4654 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4655 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4656 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4657 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4662 * Walker, checks if all ia32 nodes producing more than one result have their
4663 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4665 static void add_missing_keep_walker(ir_node *node, void *data)
4668 unsigned found_projs = 0;
4669 const ir_edge_t *edge;
4670 ir_mode *mode = get_irn_mode(node);
4675 if(!is_ia32_irn(node))
4678 n_outs = get_ia32_n_res(node);
4681 if(is_ia32_SwitchJmp(node))
4684 assert(n_outs < (int) sizeof(unsigned) * 8);
4685 foreach_out_edge(node, edge) {
4686 ir_node *proj = get_edge_src_irn(edge);
4689 /* The node could be kept */
4693 if (get_irn_mode(proj) == mode_M)
4696 pn = get_Proj_proj(proj);
4697 assert(pn < n_outs);
4698 found_projs |= 1 << pn;
4702 /* are keeps missing? */
4704 for(i = 0; i < n_outs; ++i) {
4707 const arch_register_req_t *req;
4708 const arch_register_class_t *cls;
4710 if(found_projs & (1 << i)) {
4714 req = get_ia32_out_req(node, i);
4719 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4723 block = get_nodes_block(node);
4724 in[0] = new_r_Proj(current_ir_graph, block, node,
4725 arch_register_class_mode(cls), i);
4726 if(last_keep != NULL) {
4727 be_Keep_add_node(last_keep, cls, in[0]);
4729 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4730 if(sched_is_scheduled(node)) {
4731 sched_add_after(node, last_keep);
4738 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4741 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4743 ir_graph *irg = be_get_birg_irg(cg->birg);
4744 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4747 /* do the transformation */
4748 void ia32_transform_graph(ia32_code_gen_t *cg) {
4750 ir_graph *irg = cg->irg;
4752 register_transformers();
4754 initial_fpcw = NULL;
4756 BE_TIMER_PUSH(t_heights);
4757 heights = heights_new(irg);
4758 BE_TIMER_POP(t_heights);
4759 ia32_calculate_non_address_mode_nodes(cg->birg);
4761 /* the transform phase is not safe for CSE (yet) because several nodes get
4762 * attributes set after their creation */
4763 cse_last = get_opt_cse();
4766 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4768 set_opt_cse(cse_last);
4770 ia32_free_non_address_mode_nodes();
4771 heights_free(heights);
4775 void ia32_init_transform(void)
4777 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");