2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
35 #include "irgraph_t.h"
40 #include "iredges_t.h"
52 #include "../benode_t.h"
53 #include "../besched.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
60 #include "bearch_ia32_t.h"
61 #include "ia32_common_transform.h"
62 #include "ia32_nodes_attr.h"
63 #include "ia32_transform.h"
64 #include "ia32_new_nodes.h"
65 #include "ia32_map_regs.h"
66 #include "ia32_dbg_stat.h"
67 #include "ia32_optimize.h"
68 #include "ia32_util.h"
69 #include "ia32_address_mode.h"
70 #include "ia32_architecture.h"
72 #include "gen_ia32_regalloc_if.h"
74 #define SFP_SIGN "0x80000000"
75 #define DFP_SIGN "0x8000000000000000"
76 #define SFP_ABS "0x7FFFFFFF"
77 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
78 #define DFP_INTMAX "9223372036854775807"
80 #define TP_SFP_SIGN "ia32_sfp_sign"
81 #define TP_DFP_SIGN "ia32_dfp_sign"
82 #define TP_SFP_ABS "ia32_sfp_abs"
83 #define TP_DFP_ABS "ia32_dfp_abs"
84 #define TP_INT_MAX "ia32_int_max"
86 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
87 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
88 #define ENT_SFP_ABS "IA32_SFP_ABS"
89 #define ENT_DFP_ABS "IA32_DFP_ABS"
90 #define ENT_INT_MAX "IA32_INT_MAX"
92 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
93 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
95 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
97 static ir_node *initial_fpcw = NULL;
99 extern ir_op *get_op_Mulh(void);
101 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
102 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
103 ir_node *op1, ir_node *op2);
105 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
106 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
107 ir_node *op1, ir_node *op2, ir_node *flags);
109 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
110 ir_node *block, ir_node *op1, ir_node *op2);
112 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
113 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
116 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
117 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
119 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
120 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
121 ir_node *op1, ir_node *op2, ir_node *fpcw);
123 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
124 ir_node *block, ir_node *op);
126 static ir_node *create_immediate_or_transform(ir_node *node,
127 char immediate_constraint_type);
129 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
130 dbg_info *dbgi, ir_node *block,
131 ir_node *op, ir_node *orig_node);
133 /** Return non-zero is a node represents the 0 constant. */
134 static int is_Const_0(ir_node *node) {
135 return is_Const(node) && is_Const_null(node);
138 /** Return non-zero is a node represents the 1 constant. */
139 static int is_Const_1(ir_node *node) {
140 return is_Const(node) && is_Const_one(node);
143 /** Return non-zero is a node represents the -1 constant. */
144 static int is_Const_Minus_1(ir_node *node) {
145 return is_Const(node) && is_Const_all_one(node);
149 * returns true if constant can be created with a simple float command
151 static int is_simple_x87_Const(ir_node *node)
153 tarval *tv = get_Const_tarval(node);
154 if (tarval_is_null(tv) || tarval_is_one(tv))
157 /* TODO: match all the other float constants */
162 * returns true if constant can be created with a simple float command
164 static int is_simple_sse_Const(ir_node *node)
166 tarval *tv = get_Const_tarval(node);
167 ir_mode *mode = get_tarval_mode(tv);
172 if (tarval_is_null(tv) || tarval_is_one(tv))
175 if (mode == mode_D) {
176 unsigned val = get_tarval_sub_bits(tv, 0) |
177 (get_tarval_sub_bits(tv, 1) << 8) |
178 (get_tarval_sub_bits(tv, 2) << 16) |
179 (get_tarval_sub_bits(tv, 3) << 24);
181 /* lower 32bit are zero, really a 32bit constant */
185 /* TODO: match all the other float constants */
190 * Transforms a Const.
192 static ir_node *gen_Const(ir_node *node) {
193 ir_graph *irg = current_ir_graph;
194 ir_node *old_block = get_nodes_block(node);
195 ir_node *block = be_transform_node(old_block);
196 dbg_info *dbgi = get_irn_dbg_info(node);
197 ir_mode *mode = get_irn_mode(node);
199 assert(is_Const(node));
201 if (mode_is_float(mode)) {
203 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
204 ir_node *nomem = new_NoMem();
208 if (ia32_cg_config.use_sse2) {
209 tarval *tv = get_Const_tarval(node);
210 if (tarval_is_null(tv)) {
211 load = new_rd_ia32_xZero(dbgi, irg, block);
212 set_ia32_ls_mode(load, mode);
214 } else if (tarval_is_one(tv)) {
215 int cnst = mode == mode_F ? 26 : 55;
216 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
217 ir_node *imm2 = create_Immediate(NULL, 0, 2);
218 ir_node *pslld, *psrld;
220 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
221 set_ia32_ls_mode(load, mode);
222 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
223 set_ia32_ls_mode(pslld, mode);
224 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
225 set_ia32_ls_mode(psrld, mode);
227 } else if (mode == mode_F) {
228 /* we can place any 32bit constant by using a movd gp, sse */
229 unsigned val = get_tarval_sub_bits(tv, 0) |
230 (get_tarval_sub_bits(tv, 1) << 8) |
231 (get_tarval_sub_bits(tv, 2) << 16) |
232 (get_tarval_sub_bits(tv, 3) << 24);
233 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
234 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
235 set_ia32_ls_mode(load, mode);
238 if (mode == mode_D) {
239 unsigned val = get_tarval_sub_bits(tv, 0) |
240 (get_tarval_sub_bits(tv, 1) << 8) |
241 (get_tarval_sub_bits(tv, 2) << 16) |
242 (get_tarval_sub_bits(tv, 3) << 24);
244 ir_node *imm32 = create_Immediate(NULL, 0, 32);
245 ir_node *cnst, *psllq;
247 /* fine, lower 32bit are zero, produce 32bit value */
248 val = get_tarval_sub_bits(tv, 4) |
249 (get_tarval_sub_bits(tv, 5) << 8) |
250 (get_tarval_sub_bits(tv, 6) << 16) |
251 (get_tarval_sub_bits(tv, 7) << 24);
252 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
253 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
254 set_ia32_ls_mode(load, mode);
255 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
256 set_ia32_ls_mode(psllq, mode);
261 floatent = create_float_const_entity(node);
263 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
265 set_ia32_op_type(load, ia32_AddrModeS);
266 set_ia32_am_sc(load, floatent);
267 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
268 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
271 if (is_Const_null(node)) {
272 load = new_rd_ia32_vfldz(dbgi, irg, block);
274 set_ia32_ls_mode(load, mode);
275 } else if (is_Const_one(node)) {
276 load = new_rd_ia32_vfld1(dbgi, irg, block);
278 set_ia32_ls_mode(load, mode);
280 floatent = create_float_const_entity(node);
282 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
283 set_ia32_op_type(load, ia32_AddrModeS);
284 set_ia32_am_sc(load, floatent);
285 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
286 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
287 /* take the mode from the entity */
288 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
292 /* Const Nodes before the initial IncSP are a bad idea, because
293 * they could be spilled and we have no SP ready at that point yet.
294 * So add a dependency to the initial frame pointer calculation to
295 * avoid that situation.
297 if (get_irg_start_block(irg) == block) {
298 add_irn_dep(load, get_irg_frame(irg));
301 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
303 } else { /* non-float mode */
305 tarval *tv = get_Const_tarval(node);
308 tv = tarval_convert_to(tv, mode_Iu);
310 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
312 panic("couldn't convert constant tarval (%+F)", node);
314 val = get_tarval_long(tv);
316 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
317 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
320 if (get_irg_start_block(irg) == block) {
321 add_irn_dep(cnst, get_irg_frame(irg));
329 * Transforms a SymConst.
331 static ir_node *gen_SymConst(ir_node *node) {
332 ir_graph *irg = current_ir_graph;
333 ir_node *old_block = get_nodes_block(node);
334 ir_node *block = be_transform_node(old_block);
335 dbg_info *dbgi = get_irn_dbg_info(node);
336 ir_mode *mode = get_irn_mode(node);
339 if (mode_is_float(mode)) {
340 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
341 ir_node *nomem = new_NoMem();
343 if (ia32_cg_config.use_sse2)
344 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
346 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
347 set_ia32_am_sc(cnst, get_SymConst_entity(node));
348 set_ia32_use_frame(cnst);
352 if(get_SymConst_kind(node) != symconst_addr_ent) {
353 panic("backend only support symconst_addr_ent (at %+F)", node);
355 entity = get_SymConst_entity(node);
356 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
359 /* Const Nodes before the initial IncSP are a bad idea, because
360 * they could be spilled and we have no SP ready at that point yet
362 if (get_irg_start_block(irg) == block) {
363 add_irn_dep(cnst, get_irg_frame(irg));
366 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
371 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
372 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
373 static const struct {
375 const char *ent_name;
376 const char *cnst_str;
379 } names [ia32_known_const_max] = {
380 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
381 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
382 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
383 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
384 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
386 static ir_entity *ent_cache[ia32_known_const_max];
388 const char *tp_name, *ent_name, *cnst_str;
396 ent_name = names[kct].ent_name;
397 if (! ent_cache[kct]) {
398 tp_name = names[kct].tp_name;
399 cnst_str = names[kct].cnst_str;
401 switch (names[kct].mode) {
402 case 0: mode = mode_Iu; break;
403 case 1: mode = mode_Lu; break;
404 default: mode = mode_F; break;
406 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
407 tp = new_type_primitive(new_id_from_str(tp_name), mode);
408 /* set the specified alignment */
409 set_type_alignment_bytes(tp, names[kct].align);
411 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
413 set_entity_ld_ident(ent, get_entity_ident(ent));
414 set_entity_visibility(ent, visibility_local);
415 set_entity_variability(ent, variability_constant);
416 set_entity_allocation(ent, allocation_static);
418 /* we create a new entity here: It's initialization must resist on the
420 rem = current_ir_graph;
421 current_ir_graph = get_const_code_irg();
422 cnst = new_Const(mode, tv);
423 current_ir_graph = rem;
425 set_atomic_ent_value(ent, cnst);
427 /* cache the entry */
428 ent_cache[kct] = ent;
431 return ent_cache[kct];
434 static int prevents_AM(ir_node *const block, ir_node *const am_candidate,
435 ir_node *const other)
437 if (get_nodes_block(other) != block)
440 if (is_Sync(other)) {
443 for (i = get_Sync_n_preds(other) - 1; i >= 0; --i) {
444 ir_node *const pred = get_Sync_pred(other, i);
446 if (get_nodes_block(pred) != block)
449 /* Do not block ourselves from getting eaten */
450 if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate)
453 if (!heights_reachable_in_block(heights, pred, am_candidate))
461 /* Do not block ourselves from getting eaten */
462 if (is_Proj(other) && get_Proj_pred(other) == am_candidate)
465 if (!heights_reachable_in_block(heights, other, am_candidate))
473 * return true if the node is a Proj(Load) and could be used in source address
474 * mode for another node. Will return only true if the @p other node is not
475 * dependent on the memory of the Load (for binary operations use the other
476 * input here, for unary operations use NULL).
478 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
479 ir_node *other, ir_node *other2, match_flags_t flags)
484 /* float constants are always available */
485 if (is_Const(node)) {
486 ir_mode *mode = get_irn_mode(node);
487 if (mode_is_float(mode)) {
488 if (ia32_cg_config.use_sse2) {
489 if (is_simple_sse_Const(node))
492 if (is_simple_x87_Const(node))
495 if (get_irn_n_edges(node) > 1)
503 load = get_Proj_pred(node);
504 pn = get_Proj_proj(node);
505 if (!is_Load(load) || pn != pn_Load_res)
507 if (get_nodes_block(load) != block)
509 /* we only use address mode if we're the only user of the load */
510 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
512 /* in some edge cases with address mode we might reach the load normally
513 * and through some AM sequence, if it is already materialized then we
514 * can't create an AM node from it */
515 if (be_is_transformed(node))
518 /* don't do AM if other node inputs depend on the load (via mem-proj) */
519 if (other != NULL && prevents_AM(block, load, other))
522 if (other2 != NULL && prevents_AM(block, load, other2))
528 typedef struct ia32_address_mode_t ia32_address_mode_t;
529 struct ia32_address_mode_t {
533 ia32_op_type_t op_type;
537 unsigned commutative : 1;
538 unsigned ins_permuted : 1;
541 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
545 /* construct load address */
546 memset(addr, 0, sizeof(addr[0]));
547 ia32_create_address_mode(addr, ptr, /*force=*/0);
549 noreg_gp = ia32_new_NoReg_gp(env_cg);
550 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
551 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
552 addr->mem = be_transform_node(mem);
555 static void build_address(ia32_address_mode_t *am, ir_node *node)
557 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
558 ia32_address_t *addr = &am->addr;
564 if (is_Const(node)) {
565 ir_entity *entity = create_float_const_entity(node);
566 addr->base = noreg_gp;
567 addr->index = noreg_gp;
568 addr->mem = new_NoMem();
569 addr->symconst_ent = entity;
571 am->ls_mode = get_type_mode(get_entity_type(entity));
572 am->pinned = op_pin_state_floats;
576 load = get_Proj_pred(node);
577 ptr = get_Load_ptr(load);
578 mem = get_Load_mem(load);
579 new_mem = be_transform_node(mem);
580 am->pinned = get_irn_pinned(load);
581 am->ls_mode = get_Load_mode(load);
582 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
584 /* construct load address */
585 ia32_create_address_mode(addr, ptr, /*force=*/0);
587 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
588 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
592 static void set_address(ir_node *node, const ia32_address_t *addr)
594 set_ia32_am_scale(node, addr->scale);
595 set_ia32_am_sc(node, addr->symconst_ent);
596 set_ia32_am_offs_int(node, addr->offset);
597 if(addr->symconst_sign)
598 set_ia32_am_sc_sign(node);
600 set_ia32_use_frame(node);
601 set_ia32_frame_ent(node, addr->frame_entity);
605 * Apply attributes of a given address mode to a node.
607 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
609 set_address(node, &am->addr);
611 set_ia32_op_type(node, am->op_type);
612 set_ia32_ls_mode(node, am->ls_mode);
613 if (am->pinned == op_pin_state_pinned) {
614 /* beware: some nodes are already pinned and did not allow to change the state */
615 if (get_irn_pinned(node) != op_pin_state_pinned)
616 set_irn_pinned(node, op_pin_state_pinned);
619 set_ia32_commutative(node);
623 * Check, if a given node is a Down-Conv, ie. a integer Conv
624 * from a mode with a mode with more bits to a mode with lesser bits.
625 * Moreover, we return only true if the node has not more than 1 user.
627 * @param node the node
628 * @return non-zero if node is a Down-Conv
630 static int is_downconv(const ir_node *node)
638 /* we only want to skip the conv when we're the only user
639 * (not optimal but for now...)
641 if(get_irn_n_edges(node) > 1)
644 src_mode = get_irn_mode(get_Conv_op(node));
645 dest_mode = get_irn_mode(node);
646 return ia32_mode_needs_gp_reg(src_mode)
647 && ia32_mode_needs_gp_reg(dest_mode)
648 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
651 /* Skip all Down-Conv's on a given node and return the resulting node. */
652 ir_node *ia32_skip_downconv(ir_node *node) {
653 while (is_downconv(node))
654 node = get_Conv_op(node);
659 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
661 ir_mode *mode = get_irn_mode(node);
666 if(mode_is_signed(mode)) {
671 block = get_nodes_block(node);
672 dbgi = get_irn_dbg_info(node);
674 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
678 * matches operands of a node into ia32 addressing/operand modes. This covers
679 * usage of source address mode, immediates, operations with non 32-bit modes,
681 * The resulting data is filled into the @p am struct. block is the block
682 * of the node whose arguments are matched. op1, op2 are the first and second
683 * input that are matched (op1 may be NULL). other_op is another unrelated
684 * input that is not matched! but which is needed sometimes to check if AM
685 * for op1/op2 is legal.
686 * @p flags describes the supported modes of the operation in detail.
688 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
689 ir_node *op1, ir_node *op2, ir_node *other_op,
692 ia32_address_t *addr = &am->addr;
693 ir_mode *mode = get_irn_mode(op2);
694 int mode_bits = get_mode_size_bits(mode);
695 ir_node *noreg_gp, *new_op1, *new_op2;
697 unsigned commutative;
698 int use_am_and_immediates;
701 memset(am, 0, sizeof(am[0]));
703 commutative = (flags & match_commutative) != 0;
704 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
705 use_am = (flags & match_am) != 0;
706 use_immediate = (flags & match_immediate) != 0;
707 assert(!use_am_and_immediates || use_immediate);
710 assert(!commutative || op1 != NULL);
711 assert(use_am || !(flags & match_8bit_am));
712 assert(use_am || !(flags & match_16bit_am));
714 if (mode_bits == 8) {
715 if (!(flags & match_8bit_am))
717 /* we don't automatically add upconvs yet */
718 assert((flags & match_mode_neutral) || (flags & match_8bit));
719 } else if (mode_bits == 16) {
720 if (!(flags & match_16bit_am))
722 /* we don't automatically add upconvs yet */
723 assert((flags & match_mode_neutral) || (flags & match_16bit));
726 /* we can simply skip downconvs for mode neutral nodes: the upper bits
727 * can be random for these operations */
728 if (flags & match_mode_neutral) {
729 op2 = ia32_skip_downconv(op2);
731 op1 = ia32_skip_downconv(op1);
735 /* match immediates. firm nodes are normalized: constants are always on the
738 if (!(flags & match_try_am) && use_immediate) {
739 new_op2 = try_create_Immediate(op2, 0);
742 noreg_gp = ia32_new_NoReg_gp(env_cg);
743 if (new_op2 == NULL &&
744 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
745 build_address(am, op2);
746 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
747 if (mode_is_float(mode)) {
748 new_op2 = ia32_new_NoReg_vfp(env_cg);
752 am->op_type = ia32_AddrModeS;
753 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
755 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
757 build_address(am, op1);
759 if (mode_is_float(mode)) {
760 noreg = ia32_new_NoReg_vfp(env_cg);
765 if (new_op2 != NULL) {
768 new_op1 = be_transform_node(op2);
770 am->ins_permuted = 1;
772 am->op_type = ia32_AddrModeS;
774 if (flags & match_try_am) {
777 am->op_type = ia32_Normal;
781 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
783 new_op2 = be_transform_node(op2);
784 am->op_type = ia32_Normal;
785 am->ls_mode = get_irn_mode(op2);
786 if (flags & match_mode_neutral)
787 am->ls_mode = mode_Iu;
789 if (addr->base == NULL)
790 addr->base = noreg_gp;
791 if (addr->index == NULL)
792 addr->index = noreg_gp;
793 if (addr->mem == NULL)
794 addr->mem = new_NoMem();
796 am->new_op1 = new_op1;
797 am->new_op2 = new_op2;
798 am->commutative = commutative;
801 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
806 if (am->mem_proj == NULL)
809 /* we have to create a mode_T so the old MemProj can attach to us */
810 mode = get_irn_mode(node);
811 load = get_Proj_pred(am->mem_proj);
813 mark_irn_visited(load);
814 be_set_transformed_node(load, node);
816 if (mode != mode_T) {
817 set_irn_mode(node, mode_T);
818 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
825 * Construct a standard binary operation, set AM and immediate if required.
827 * @param node The original node for which the binop is created
828 * @param op1 The first operand
829 * @param op2 The second operand
830 * @param func The node constructor function
831 * @return The constructed ia32 node.
833 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
834 construct_binop_func *func, match_flags_t flags)
837 ir_node *block, *new_block, *new_node;
838 ia32_address_mode_t am;
839 ia32_address_t *addr = &am.addr;
841 block = get_nodes_block(node);
842 match_arguments(&am, block, op1, op2, NULL, flags);
844 dbgi = get_irn_dbg_info(node);
845 new_block = be_transform_node(block);
846 new_node = func(dbgi, current_ir_graph, new_block,
847 addr->base, addr->index, addr->mem,
848 am.new_op1, am.new_op2);
849 set_am_attributes(new_node, &am);
850 /* we can't use source address mode anymore when using immediates */
851 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
852 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
853 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
855 new_node = fix_mem_proj(new_node, &am);
862 n_ia32_l_binop_right,
863 n_ia32_l_binop_eflags
865 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
866 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
867 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
868 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
869 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
870 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
873 * Construct a binary operation which also consumes the eflags.
875 * @param node The node to transform
876 * @param func The node constructor function
877 * @param flags The match flags
878 * @return The constructor ia32 node
880 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
883 ir_node *src_block = get_nodes_block(node);
884 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
885 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
886 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
888 ir_node *block, *new_node, *new_eflags;
889 ia32_address_mode_t am;
890 ia32_address_t *addr = &am.addr;
892 match_arguments(&am, src_block, op1, op2, eflags, flags);
894 dbgi = get_irn_dbg_info(node);
895 block = be_transform_node(src_block);
896 new_eflags = be_transform_node(eflags);
897 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
898 addr->mem, am.new_op1, am.new_op2, new_eflags);
899 set_am_attributes(new_node, &am);
900 /* we can't use source address mode anymore when using immediates */
901 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
902 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
903 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
905 new_node = fix_mem_proj(new_node, &am);
910 static ir_node *get_fpcw(void)
913 if (initial_fpcw != NULL)
916 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
917 &ia32_fp_cw_regs[REG_FPCW]);
918 initial_fpcw = be_transform_node(fpcw);
924 * Construct a standard binary operation, set AM and immediate if required.
926 * @param op1 The first operand
927 * @param op2 The second operand
928 * @param func The node constructor function
929 * @return The constructed ia32 node.
931 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
932 construct_binop_float_func *func,
935 ir_mode *mode = get_irn_mode(node);
937 ir_node *block, *new_block, *new_node;
938 ia32_address_mode_t am;
939 ia32_address_t *addr = &am.addr;
941 /* cannot use address mode with long double on x87 */
942 if (get_mode_size_bits(mode) > 64)
945 block = get_nodes_block(node);
946 match_arguments(&am, block, op1, op2, NULL, flags);
948 dbgi = get_irn_dbg_info(node);
949 new_block = be_transform_node(block);
950 new_node = func(dbgi, current_ir_graph, new_block,
951 addr->base, addr->index, addr->mem,
952 am.new_op1, am.new_op2, get_fpcw());
953 set_am_attributes(new_node, &am);
955 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
957 new_node = fix_mem_proj(new_node, &am);
963 * Construct a shift/rotate binary operation, sets AM and immediate if required.
965 * @param op1 The first operand
966 * @param op2 The second operand
967 * @param func The node constructor function
968 * @return The constructed ia32 node.
970 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
971 construct_shift_func *func,
975 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
977 assert(! mode_is_float(get_irn_mode(node)));
978 assert(flags & match_immediate);
979 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
981 if (flags & match_mode_neutral) {
982 op1 = ia32_skip_downconv(op1);
983 new_op1 = be_transform_node(op1);
984 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
985 new_op1 = create_upconv(op1, node);
987 new_op1 = be_transform_node(op1);
990 /* the shift amount can be any mode that is bigger than 5 bits, since all
991 * other bits are ignored anyway */
992 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
993 ir_node *const op = get_Conv_op(op2);
994 if (mode_is_float(get_irn_mode(op)))
997 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
999 new_op2 = create_immediate_or_transform(op2, 0);
1001 dbgi = get_irn_dbg_info(node);
1002 block = get_nodes_block(node);
1003 new_block = be_transform_node(block);
1004 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1005 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1007 /* lowered shift instruction may have a dependency operand, handle it here */
1008 if (get_irn_arity(node) == 3) {
1009 /* we have a dependency */
1010 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1011 add_irn_dep(new_node, new_dep);
1019 * Construct a standard unary operation, set AM and immediate if required.
1021 * @param op The operand
1022 * @param func The node constructor function
1023 * @return The constructed ia32 node.
1025 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1026 match_flags_t flags)
1029 ir_node *block, *new_block, *new_op, *new_node;
1031 assert(flags == 0 || flags == match_mode_neutral);
1032 if (flags & match_mode_neutral) {
1033 op = ia32_skip_downconv(op);
1036 new_op = be_transform_node(op);
1037 dbgi = get_irn_dbg_info(node);
1038 block = get_nodes_block(node);
1039 new_block = be_transform_node(block);
1040 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1042 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1047 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1048 ia32_address_t *addr)
1050 ir_node *base, *index, *res;
1054 base = ia32_new_NoReg_gp(env_cg);
1056 base = be_transform_node(base);
1059 index = addr->index;
1060 if (index == NULL) {
1061 index = ia32_new_NoReg_gp(env_cg);
1063 index = be_transform_node(index);
1066 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1067 set_address(res, addr);
1073 * Returns non-zero if a given address mode has a symbolic or
1074 * numerical offset != 0.
1076 static int am_has_immediates(const ia32_address_t *addr)
1078 return addr->offset != 0 || addr->symconst_ent != NULL
1079 || addr->frame_entity || addr->use_frame;
1083 * Creates an ia32 Add.
1085 * @return the created ia32 Add node
1087 static ir_node *gen_Add(ir_node *node) {
1088 ir_mode *mode = get_irn_mode(node);
1089 ir_node *op1 = get_Add_left(node);
1090 ir_node *op2 = get_Add_right(node);
1092 ir_node *block, *new_block, *new_node, *add_immediate_op;
1093 ia32_address_t addr;
1094 ia32_address_mode_t am;
1096 if (mode_is_float(mode)) {
1097 if (ia32_cg_config.use_sse2)
1098 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1099 match_commutative | match_am);
1101 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1102 match_commutative | match_am);
1105 ia32_mark_non_am(node);
1107 op2 = ia32_skip_downconv(op2);
1108 op1 = ia32_skip_downconv(op1);
1112 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1113 * 1. Add with immediate -> Lea
1114 * 2. Add with possible source address mode -> Add
1115 * 3. Otherwise -> Lea
1117 memset(&addr, 0, sizeof(addr));
1118 ia32_create_address_mode(&addr, node, /*force=*/1);
1119 add_immediate_op = NULL;
1121 dbgi = get_irn_dbg_info(node);
1122 block = get_nodes_block(node);
1123 new_block = be_transform_node(block);
1126 if(addr.base == NULL && addr.index == NULL) {
1127 ir_graph *irg = current_ir_graph;
1128 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1129 addr.symconst_sign, addr.offset);
1130 add_irn_dep(new_node, get_irg_frame(irg));
1131 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1134 /* add with immediate? */
1135 if(addr.index == NULL) {
1136 add_immediate_op = addr.base;
1137 } else if(addr.base == NULL && addr.scale == 0) {
1138 add_immediate_op = addr.index;
1141 if(add_immediate_op != NULL) {
1142 if(!am_has_immediates(&addr)) {
1143 #ifdef DEBUG_libfirm
1144 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1147 return be_transform_node(add_immediate_op);
1150 new_node = create_lea_from_address(dbgi, new_block, &addr);
1151 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1155 /* test if we can use source address mode */
1156 match_arguments(&am, block, op1, op2, NULL, match_commutative
1157 | match_mode_neutral | match_am | match_immediate | match_try_am);
1159 /* construct an Add with source address mode */
1160 if (am.op_type == ia32_AddrModeS) {
1161 ir_graph *irg = current_ir_graph;
1162 ia32_address_t *am_addr = &am.addr;
1163 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1164 am_addr->index, am_addr->mem, am.new_op1,
1166 set_am_attributes(new_node, &am);
1167 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1169 new_node = fix_mem_proj(new_node, &am);
1174 /* otherwise construct a lea */
1175 new_node = create_lea_from_address(dbgi, new_block, &addr);
1176 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1181 * Creates an ia32 Mul.
1183 * @return the created ia32 Mul node
1185 static ir_node *gen_Mul(ir_node *node) {
1186 ir_node *op1 = get_Mul_left(node);
1187 ir_node *op2 = get_Mul_right(node);
1188 ir_mode *mode = get_irn_mode(node);
1190 if (mode_is_float(mode)) {
1191 if (ia32_cg_config.use_sse2)
1192 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1193 match_commutative | match_am);
1195 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1196 match_commutative | match_am);
1198 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1199 match_commutative | match_am | match_mode_neutral |
1200 match_immediate | match_am_and_immediates);
1204 * Creates an ia32 Mulh.
1205 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1206 * this result while Mul returns the lower 32 bit.
1208 * @return the created ia32 Mulh node
1210 static ir_node *gen_Mulh(ir_node *node)
1212 ir_node *block = get_nodes_block(node);
1213 ir_node *new_block = be_transform_node(block);
1214 ir_graph *irg = current_ir_graph;
1215 dbg_info *dbgi = get_irn_dbg_info(node);
1216 ir_mode *mode = get_irn_mode(node);
1217 ir_node *op1 = get_Mulh_left(node);
1218 ir_node *op2 = get_Mulh_right(node);
1219 ir_node *proj_res_high;
1221 ia32_address_mode_t am;
1222 ia32_address_t *addr = &am.addr;
1224 assert(!mode_is_float(mode) && "Mulh with float not supported");
1225 assert(get_mode_size_bits(mode) == 32);
1227 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1229 if (mode_is_signed(mode)) {
1230 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1231 addr->index, addr->mem, am.new_op1,
1234 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1235 addr->index, addr->mem, am.new_op1,
1239 set_am_attributes(new_node, &am);
1240 /* we can't use source address mode anymore when using immediates */
1241 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1242 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1243 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1245 assert(get_irn_mode(new_node) == mode_T);
1247 fix_mem_proj(new_node, &am);
1249 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1250 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1251 mode_Iu, pn_ia32_IMul1OP_res_high);
1253 return proj_res_high;
1259 * Creates an ia32 And.
1261 * @return The created ia32 And node
1263 static ir_node *gen_And(ir_node *node) {
1264 ir_node *op1 = get_And_left(node);
1265 ir_node *op2 = get_And_right(node);
1266 assert(! mode_is_float(get_irn_mode(node)));
1268 /* is it a zero extension? */
1269 if (is_Const(op2)) {
1270 tarval *tv = get_Const_tarval(op2);
1271 long v = get_tarval_long(tv);
1273 if (v == 0xFF || v == 0xFFFF) {
1274 dbg_info *dbgi = get_irn_dbg_info(node);
1275 ir_node *block = get_nodes_block(node);
1282 assert(v == 0xFFFF);
1285 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1290 return gen_binop(node, op1, op2, new_rd_ia32_And,
1291 match_commutative | match_mode_neutral | match_am
1298 * Creates an ia32 Or.
1300 * @return The created ia32 Or node
1302 static ir_node *gen_Or(ir_node *node) {
1303 ir_node *op1 = get_Or_left(node);
1304 ir_node *op2 = get_Or_right(node);
1306 assert (! mode_is_float(get_irn_mode(node)));
1307 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1308 | match_mode_neutral | match_am | match_immediate);
1314 * Creates an ia32 Eor.
1316 * @return The created ia32 Eor node
1318 static ir_node *gen_Eor(ir_node *node) {
1319 ir_node *op1 = get_Eor_left(node);
1320 ir_node *op2 = get_Eor_right(node);
1322 assert(! mode_is_float(get_irn_mode(node)));
1323 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1324 | match_mode_neutral | match_am | match_immediate);
1329 * Creates an ia32 Sub.
1331 * @return The created ia32 Sub node
1333 static ir_node *gen_Sub(ir_node *node) {
1334 ir_node *op1 = get_Sub_left(node);
1335 ir_node *op2 = get_Sub_right(node);
1336 ir_mode *mode = get_irn_mode(node);
1338 if (mode_is_float(mode)) {
1339 if (ia32_cg_config.use_sse2)
1340 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1342 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1346 if (is_Const(op2)) {
1347 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1351 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1352 | match_am | match_immediate);
1355 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1356 ir_node *const src_val,
1357 ir_node *const src_mem,
1358 ir_node *const am_mem)
1360 if (is_NoMem(am_mem)) {
1361 return be_transform_node(src_mem);
1362 } else if (is_Proj(src_val) &&
1364 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1365 /* avoid memory loop */
1367 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1368 ir_node *const ptr_pred = get_Proj_pred(src_val);
1369 int const arity = get_Sync_n_preds(src_mem);
1374 NEW_ARR_A(ir_node*, ins, arity + 1);
1376 for (i = arity - 1; i >= 0; --i) {
1377 ir_node *const pred = get_Sync_pred(src_mem, i);
1379 /* avoid memory loop */
1380 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1383 ins[n++] = be_transform_node(pred);
1388 return new_r_Sync(irg, block, n, ins);
1392 ins[0] = be_transform_node(src_mem);
1394 return new_r_Sync(irg, block, 2, ins);
1399 * Generates an ia32 DivMod with additional infrastructure for the
1400 * register allocator if needed.
1402 static ir_node *create_Div(ir_node *node)
1404 ir_graph *irg = current_ir_graph;
1405 dbg_info *dbgi = get_irn_dbg_info(node);
1406 ir_node *block = get_nodes_block(node);
1407 ir_node *new_block = be_transform_node(block);
1414 ir_node *sign_extension;
1415 ia32_address_mode_t am;
1416 ia32_address_t *addr = &am.addr;
1418 /* the upper bits have random contents for smaller modes */
1419 switch (get_irn_opcode(node)) {
1421 op1 = get_Div_left(node);
1422 op2 = get_Div_right(node);
1423 mem = get_Div_mem(node);
1424 mode = get_Div_resmode(node);
1427 op1 = get_Mod_left(node);
1428 op2 = get_Mod_right(node);
1429 mem = get_Mod_mem(node);
1430 mode = get_Mod_resmode(node);
1433 op1 = get_DivMod_left(node);
1434 op2 = get_DivMod_right(node);
1435 mem = get_DivMod_mem(node);
1436 mode = get_DivMod_resmode(node);
1439 panic("invalid divmod node %+F", node);
1442 match_arguments(&am, block, op1, op2, NULL, match_am);
1444 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1445 is the memory of the consumed address. We can have only the second op as address
1446 in Div nodes, so check only op2. */
1447 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1449 if (mode_is_signed(mode)) {
1450 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1451 add_irn_dep(produceval, get_irg_frame(irg));
1452 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1455 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1456 addr->index, new_mem, am.new_op2,
1457 am.new_op1, sign_extension);
1459 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1460 add_irn_dep(sign_extension, get_irg_frame(irg));
1462 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1463 addr->index, new_mem, am.new_op2,
1464 am.new_op1, sign_extension);
1467 set_irn_pinned(new_node, get_irn_pinned(node));
1469 set_am_attributes(new_node, &am);
1470 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1472 new_node = fix_mem_proj(new_node, &am);
1478 static ir_node *gen_Mod(ir_node *node) {
1479 return create_Div(node);
1482 static ir_node *gen_Div(ir_node *node) {
1483 return create_Div(node);
1486 static ir_node *gen_DivMod(ir_node *node) {
1487 return create_Div(node);
1493 * Creates an ia32 floating Div.
1495 * @return The created ia32 xDiv node
1497 static ir_node *gen_Quot(ir_node *node)
1499 ir_node *op1 = get_Quot_left(node);
1500 ir_node *op2 = get_Quot_right(node);
1502 if (ia32_cg_config.use_sse2) {
1503 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1505 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1511 * Creates an ia32 Shl.
1513 * @return The created ia32 Shl node
1515 static ir_node *gen_Shl(ir_node *node) {
1516 ir_node *left = get_Shl_left(node);
1517 ir_node *right = get_Shl_right(node);
1519 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1520 match_mode_neutral | match_immediate);
1524 * Creates an ia32 Shr.
1526 * @return The created ia32 Shr node
1528 static ir_node *gen_Shr(ir_node *node) {
1529 ir_node *left = get_Shr_left(node);
1530 ir_node *right = get_Shr_right(node);
1532 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1538 * Creates an ia32 Sar.
1540 * @return The created ia32 Shrs node
1542 static ir_node *gen_Shrs(ir_node *node) {
1543 ir_node *left = get_Shrs_left(node);
1544 ir_node *right = get_Shrs_right(node);
1545 ir_mode *mode = get_irn_mode(node);
1547 if(is_Const(right) && mode == mode_Is) {
1548 tarval *tv = get_Const_tarval(right);
1549 long val = get_tarval_long(tv);
1551 /* this is a sign extension */
1552 ir_graph *irg = current_ir_graph;
1553 dbg_info *dbgi = get_irn_dbg_info(node);
1554 ir_node *block = be_transform_node(get_nodes_block(node));
1556 ir_node *new_op = be_transform_node(op);
1557 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1558 add_irn_dep(pval, get_irg_frame(irg));
1560 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1564 /* 8 or 16 bit sign extension? */
1565 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1566 ir_node *shl_left = get_Shl_left(left);
1567 ir_node *shl_right = get_Shl_right(left);
1568 if(is_Const(shl_right)) {
1569 tarval *tv1 = get_Const_tarval(right);
1570 tarval *tv2 = get_Const_tarval(shl_right);
1571 if(tv1 == tv2 && tarval_is_long(tv1)) {
1572 long val = get_tarval_long(tv1);
1573 if(val == 16 || val == 24) {
1574 dbg_info *dbgi = get_irn_dbg_info(node);
1575 ir_node *block = get_nodes_block(node);
1585 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1594 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1600 * Creates an ia32 Rol.
1602 * @param op1 The first operator
1603 * @param op2 The second operator
1604 * @return The created ia32 RotL node
1606 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1607 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1613 * Creates an ia32 Ror.
1614 * NOTE: There is no RotR with immediate because this would always be a RotL
1615 * "imm-mode_size_bits" which can be pre-calculated.
1617 * @param op1 The first operator
1618 * @param op2 The second operator
1619 * @return The created ia32 RotR node
1621 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1622 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1628 * Creates an ia32 RotR or RotL (depending on the found pattern).
1630 * @return The created ia32 RotL or RotR node
1632 static ir_node *gen_Rotl(ir_node *node) {
1633 ir_node *rotate = NULL;
1634 ir_node *op1 = get_Rotl_left(node);
1635 ir_node *op2 = get_Rotl_right(node);
1637 /* Firm has only RotL, so we are looking for a right (op2)
1638 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1639 that means we can create a RotR instead of an Add and a RotL */
1643 ir_node *left = get_Add_left(add);
1644 ir_node *right = get_Add_right(add);
1645 if (is_Const(right)) {
1646 tarval *tv = get_Const_tarval(right);
1647 ir_mode *mode = get_irn_mode(node);
1648 long bits = get_mode_size_bits(mode);
1650 if (is_Minus(left) &&
1651 tarval_is_long(tv) &&
1652 get_tarval_long(tv) == bits &&
1655 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1656 rotate = gen_Ror(node, op1, get_Minus_op(left));
1661 if (rotate == NULL) {
1662 rotate = gen_Rol(node, op1, op2);
1671 * Transforms a Minus node.
1673 * @return The created ia32 Minus node
1675 static ir_node *gen_Minus(ir_node *node)
1677 ir_node *op = get_Minus_op(node);
1678 ir_node *block = be_transform_node(get_nodes_block(node));
1679 ir_graph *irg = current_ir_graph;
1680 dbg_info *dbgi = get_irn_dbg_info(node);
1681 ir_mode *mode = get_irn_mode(node);
1686 if (mode_is_float(mode)) {
1687 ir_node *new_op = be_transform_node(op);
1688 if (ia32_cg_config.use_sse2) {
1689 /* TODO: non-optimal... if we have many xXors, then we should
1690 * rather create a load for the const and use that instead of
1691 * several AM nodes... */
1692 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1693 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1694 ir_node *nomem = new_rd_NoMem(irg);
1696 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1697 nomem, new_op, noreg_xmm);
1699 size = get_mode_size_bits(mode);
1700 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1702 set_ia32_am_sc(new_node, ent);
1703 set_ia32_op_type(new_node, ia32_AddrModeS);
1704 set_ia32_ls_mode(new_node, mode);
1706 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1709 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1712 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1718 * Transforms a Not node.
1720 * @return The created ia32 Not node
1722 static ir_node *gen_Not(ir_node *node) {
1723 ir_node *op = get_Not_op(node);
1725 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1726 assert (! mode_is_float(get_irn_mode(node)));
1728 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1734 * Transforms an Abs node.
1736 * @return The created ia32 Abs node
1738 static ir_node *gen_Abs(ir_node *node)
1740 ir_node *block = get_nodes_block(node);
1741 ir_node *new_block = be_transform_node(block);
1742 ir_node *op = get_Abs_op(node);
1743 ir_graph *irg = current_ir_graph;
1744 dbg_info *dbgi = get_irn_dbg_info(node);
1745 ir_mode *mode = get_irn_mode(node);
1746 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1747 ir_node *nomem = new_NoMem();
1753 if (mode_is_float(mode)) {
1754 new_op = be_transform_node(op);
1756 if (ia32_cg_config.use_sse2) {
1757 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1758 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1759 nomem, new_op, noreg_fp);
1761 size = get_mode_size_bits(mode);
1762 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1764 set_ia32_am_sc(new_node, ent);
1766 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1768 set_ia32_op_type(new_node, ia32_AddrModeS);
1769 set_ia32_ls_mode(new_node, mode);
1771 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1772 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1775 ir_node *xor, *pval, *sign_extension;
1777 if (get_mode_size_bits(mode) == 32) {
1778 new_op = be_transform_node(op);
1780 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1783 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1784 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1787 add_irn_dep(pval, get_irg_frame(irg));
1788 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1790 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1791 nomem, new_op, sign_extension);
1792 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1794 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1795 nomem, xor, sign_extension);
1796 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1803 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1805 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1806 dbg_info *dbgi = get_irn_dbg_info(cmp);
1807 ir_node *block = get_nodes_block(cmp);
1808 ir_node *new_block = be_transform_node(block);
1809 ir_node *op1 = be_transform_node(x);
1810 ir_node *op2 = be_transform_node(n);
1812 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1816 * Transform a node returning a "flag" result.
1818 * @param node the node to transform
1819 * @param pnc_out the compare mode to use
1821 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1830 /* we have a Cmp as input */
1831 if (is_Proj(node)) {
1832 ir_node *pred = get_Proj_pred(node);
1834 pn_Cmp pnc = get_Proj_proj(node);
1835 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1836 ir_node *l = get_Cmp_left(pred);
1837 ir_node *r = get_Cmp_right(pred);
1839 ir_node *la = get_And_left(l);
1840 ir_node *ra = get_And_right(l);
1842 ir_node *c = get_Shl_left(la);
1843 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1844 /* (1 << n) & ra) */
1845 ir_node *n = get_Shl_right(la);
1846 flags = gen_bt(pred, ra, n);
1847 /* we must generate a Jc/Jnc jump */
1848 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1851 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1856 ir_node *c = get_Shl_left(ra);
1857 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1858 /* la & (1 << n)) */
1859 ir_node *n = get_Shl_right(ra);
1860 flags = gen_bt(pred, la, n);
1861 /* we must generate a Jc/Jnc jump */
1862 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1865 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1871 flags = be_transform_node(pred);
1877 /* a mode_b value, we have to compare it against 0 */
1878 dbgi = get_irn_dbg_info(node);
1879 new_block = be_transform_node(get_nodes_block(node));
1880 new_op = be_transform_node(node);
1881 noreg = ia32_new_NoReg_gp(env_cg);
1882 nomem = new_NoMem();
1883 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1884 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1885 *pnc_out = pn_Cmp_Lg;
1890 * Transforms a Load.
1892 * @return the created ia32 Load node
1894 static ir_node *gen_Load(ir_node *node) {
1895 ir_node *old_block = get_nodes_block(node);
1896 ir_node *block = be_transform_node(old_block);
1897 ir_node *ptr = get_Load_ptr(node);
1898 ir_node *mem = get_Load_mem(node);
1899 ir_node *new_mem = be_transform_node(mem);
1902 ir_graph *irg = current_ir_graph;
1903 dbg_info *dbgi = get_irn_dbg_info(node);
1904 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1905 ir_mode *mode = get_Load_mode(node);
1908 ia32_address_t addr;
1910 /* construct load address */
1911 memset(&addr, 0, sizeof(addr));
1912 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1919 base = be_transform_node(base);
1925 index = be_transform_node(index);
1928 if (mode_is_float(mode)) {
1929 if (ia32_cg_config.use_sse2) {
1930 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1932 res_mode = mode_xmm;
1934 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1936 res_mode = mode_vfp;
1939 assert(mode != mode_b);
1941 /* create a conv node with address mode for smaller modes */
1942 if(get_mode_size_bits(mode) < 32) {
1943 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1944 new_mem, noreg, mode);
1946 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1951 set_irn_pinned(new_node, get_irn_pinned(node));
1952 set_ia32_op_type(new_node, ia32_AddrModeS);
1953 set_ia32_ls_mode(new_node, mode);
1954 set_address(new_node, &addr);
1956 if(get_irn_pinned(node) == op_pin_state_floats) {
1957 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1960 /* make sure we are scheduled behind the initial IncSP/Barrier
1961 * to avoid spills being placed before it
1963 if (block == get_irg_start_block(irg)) {
1964 add_irn_dep(new_node, get_irg_frame(irg));
1967 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1972 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1973 ir_node *ptr, ir_node *other)
1980 /* we only use address mode if we're the only user of the load */
1981 if (get_irn_n_edges(node) > 1)
1984 load = get_Proj_pred(node);
1987 if (get_nodes_block(load) != block)
1990 /* store should have the same pointer as the load */
1991 if (get_Load_ptr(load) != ptr)
1994 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1995 if (other != NULL &&
1996 get_nodes_block(other) == block &&
1997 heights_reachable_in_block(heights, other, load)) {
2004 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
2005 ir_node *const pred = get_Sync_pred(mem, i);
2007 if (is_Proj(pred) && get_Proj_pred(pred) == load)
2010 if (get_nodes_block(pred) == block &&
2011 heights_reachable_in_block(heights, pred, load)) {
2016 /* Store should be attached to the load */
2017 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
2024 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
2026 mark_irn_visited(old_node);
2027 be_set_transformed_node(old_node, new_node);
2030 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2031 ir_node *mem, ir_node *ptr, ir_mode *mode,
2032 construct_binop_dest_func *func,
2033 construct_binop_dest_func *func8bit,
2034 match_flags_t flags)
2036 ir_node *src_block = get_nodes_block(node);
2038 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2039 ir_graph *irg = current_ir_graph;
2045 ia32_address_mode_t am;
2046 ia32_address_t *addr = &am.addr;
2047 memset(&am, 0, sizeof(am));
2049 assert(flags & match_dest_am);
2050 assert(flags & match_immediate); /* there is no destam node without... */
2051 commutative = (flags & match_commutative) != 0;
2053 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2054 build_address(&am, op1);
2055 new_op = create_immediate_or_transform(op2, 0);
2056 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2057 build_address(&am, op2);
2058 new_op = create_immediate_or_transform(op1, 0);
2063 if(addr->base == NULL)
2064 addr->base = noreg_gp;
2065 if(addr->index == NULL)
2066 addr->index = noreg_gp;
2067 if(addr->mem == NULL)
2068 addr->mem = new_NoMem();
2070 dbgi = get_irn_dbg_info(node);
2071 block = be_transform_node(src_block);
2072 if(get_mode_size_bits(mode) == 8) {
2073 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2076 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
2079 set_address(new_node, addr);
2080 set_ia32_op_type(new_node, ia32_AddrModeD);
2081 set_ia32_ls_mode(new_node, mode);
2082 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2084 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2085 mem_proj = be_transform_node(am.mem_proj);
2086 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2091 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2092 ir_node *ptr, ir_mode *mode,
2093 construct_unop_dest_func *func)
2095 ir_graph *irg = current_ir_graph;
2096 ir_node *src_block = get_nodes_block(node);
2101 ia32_address_mode_t am;
2102 ia32_address_t *addr = &am.addr;
2103 memset(&am, 0, sizeof(am));
2105 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2108 build_address(&am, op);
2110 dbgi = get_irn_dbg_info(node);
2111 block = be_transform_node(src_block);
2112 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2113 set_address(new_node, addr);
2114 set_ia32_op_type(new_node, ia32_AddrModeD);
2115 set_ia32_ls_mode(new_node, mode);
2116 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2118 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2119 mem_proj = be_transform_node(am.mem_proj);
2120 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2125 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2126 ir_mode *mode = get_irn_mode(node);
2127 ir_node *mux_true = get_Mux_true(node);
2128 ir_node *mux_false = get_Mux_false(node);
2139 ia32_address_t addr;
2141 if(get_mode_size_bits(mode) != 8)
2144 if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2146 } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2152 build_address_ptr(&addr, ptr, mem);
2154 irg = current_ir_graph;
2155 dbgi = get_irn_dbg_info(node);
2156 block = get_nodes_block(node);
2157 new_block = be_transform_node(block);
2158 cond = get_Mux_sel(node);
2159 flags = get_flags_node(cond, &pnc);
2160 new_mem = be_transform_node(mem);
2161 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2162 addr.index, addr.mem, flags, pnc, negated);
2163 set_address(new_node, &addr);
2164 set_ia32_op_type(new_node, ia32_AddrModeD);
2165 set_ia32_ls_mode(new_node, mode);
2166 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2171 static ir_node *try_create_dest_am(ir_node *node) {
2172 ir_node *val = get_Store_value(node);
2173 ir_node *mem = get_Store_mem(node);
2174 ir_node *ptr = get_Store_ptr(node);
2175 ir_mode *mode = get_irn_mode(val);
2176 unsigned bits = get_mode_size_bits(mode);
2181 /* handle only GP modes for now... */
2182 if(!ia32_mode_needs_gp_reg(mode))
2186 /* store must be the only user of the val node */
2187 if(get_irn_n_edges(val) > 1)
2189 /* skip pointless convs */
2191 ir_node *conv_op = get_Conv_op(val);
2192 ir_mode *pred_mode = get_irn_mode(conv_op);
2193 if (!ia32_mode_needs_gp_reg(pred_mode))
2195 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2203 /* value must be in the same block */
2204 if(get_nodes_block(node) != get_nodes_block(val))
2207 switch (get_irn_opcode(val)) {
2209 op1 = get_Add_left(val);
2210 op2 = get_Add_right(val);
2211 if(is_Const_1(op2)) {
2212 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2213 new_rd_ia32_IncMem);
2215 } else if(is_Const_Minus_1(op2)) {
2216 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2217 new_rd_ia32_DecMem);
2220 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2221 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2222 match_dest_am | match_commutative |
2226 op1 = get_Sub_left(val);
2227 op2 = get_Sub_right(val);
2228 if (is_Const(op2)) {
2229 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2231 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2232 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2233 match_dest_am | match_immediate |
2237 op1 = get_And_left(val);
2238 op2 = get_And_right(val);
2239 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2240 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2241 match_dest_am | match_commutative |
2245 op1 = get_Or_left(val);
2246 op2 = get_Or_right(val);
2247 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2248 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2249 match_dest_am | match_commutative |
2253 op1 = get_Eor_left(val);
2254 op2 = get_Eor_right(val);
2255 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2256 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2257 match_dest_am | match_commutative |
2261 op1 = get_Shl_left(val);
2262 op2 = get_Shl_right(val);
2263 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2264 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2265 match_dest_am | match_immediate);
2268 op1 = get_Shr_left(val);
2269 op2 = get_Shr_right(val);
2270 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2271 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2272 match_dest_am | match_immediate);
2275 op1 = get_Shrs_left(val);
2276 op2 = get_Shrs_right(val);
2277 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2278 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2279 match_dest_am | match_immediate);
2282 op1 = get_Rotl_left(val);
2283 op2 = get_Rotl_right(val);
2284 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2285 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2286 match_dest_am | match_immediate);
2288 /* TODO: match ROR patterns... */
2290 new_node = try_create_SetMem(val, ptr, mem);
2293 op1 = get_Minus_op(val);
2294 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2297 /* should be lowered already */
2298 assert(mode != mode_b);
2299 op1 = get_Not_op(val);
2300 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2306 if(new_node != NULL) {
2307 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2308 get_irn_pinned(node) == op_pin_state_pinned) {
2309 set_irn_pinned(new_node, op_pin_state_pinned);
2316 static int is_float_to_int32_conv(const ir_node *node)
2318 ir_mode *mode = get_irn_mode(node);
2322 if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode))
2324 /* don't report unsigned as conv to 32bit, because we really need to do
2325 * a vfist with 64bit signed in this case */
2326 if(!mode_is_signed(mode))
2331 conv_op = get_Conv_op(node);
2332 conv_mode = get_irn_mode(conv_op);
2334 if(!mode_is_float(conv_mode))
2341 * Transform a Store(floatConst).
2343 * @return the created ia32 Store node
2345 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2347 ir_mode *mode = get_irn_mode(cns);
2348 unsigned size = get_mode_size_bytes(mode);
2349 tarval *tv = get_Const_tarval(cns);
2350 ir_node *block = get_nodes_block(node);
2351 ir_node *new_block = be_transform_node(block);
2352 ir_node *ptr = get_Store_ptr(node);
2353 ir_node *mem = get_Store_mem(node);
2354 ir_graph *irg = current_ir_graph;
2355 dbg_info *dbgi = get_irn_dbg_info(node);
2359 ia32_address_t addr;
2361 assert(size % 4 == 0);
2364 build_address_ptr(&addr, ptr, mem);
2368 get_tarval_sub_bits(tv, ofs) |
2369 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2370 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2371 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2372 ir_node *imm = create_Immediate(NULL, 0, val);
2374 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2375 addr.index, addr.mem, imm);
2377 set_irn_pinned(new_node, get_irn_pinned(node));
2378 set_ia32_op_type(new_node, ia32_AddrModeD);
2379 set_ia32_ls_mode(new_node, mode_Iu);
2380 set_address(new_node, &addr);
2381 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2383 ins[i++] = new_node;
2388 } while (size != 0);
2390 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2394 * Generate a vfist or vfisttp instruction.
2396 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2397 ir_node *mem, ir_node *val, ir_node **fist)
2401 if (ia32_cg_config.use_fisttp) {
2402 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2403 if other users exists */
2404 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2405 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2406 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2407 be_new_Keep(reg_class, irg, block, 1, &value);
2409 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2412 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2415 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2421 * Transforms a normal Store.
2423 * @return the created ia32 Store node
2425 static ir_node *gen_normal_Store(ir_node *node)
2427 ir_node *val = get_Store_value(node);
2428 ir_mode *mode = get_irn_mode(val);
2429 ir_node *block = get_nodes_block(node);
2430 ir_node *new_block = be_transform_node(block);
2431 ir_node *ptr = get_Store_ptr(node);
2432 ir_node *mem = get_Store_mem(node);
2433 ir_graph *irg = current_ir_graph;
2434 dbg_info *dbgi = get_irn_dbg_info(node);
2435 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2436 ir_node *new_val, *new_node, *store;
2437 ia32_address_t addr;
2439 /* check for destination address mode */
2440 new_node = try_create_dest_am(node);
2441 if (new_node != NULL)
2444 /* construct store address */
2445 memset(&addr, 0, sizeof(addr));
2446 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2448 if (addr.base == NULL) {
2451 addr.base = be_transform_node(addr.base);
2454 if (addr.index == NULL) {
2457 addr.index = be_transform_node(addr.index);
2459 addr.mem = be_transform_node(mem);
2461 if (mode_is_float(mode)) {
2462 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2464 while (is_Conv(val) && mode == get_irn_mode(val)) {
2465 ir_node *op = get_Conv_op(val);
2466 if (!mode_is_float(get_irn_mode(op)))
2470 new_val = be_transform_node(val);
2471 if (ia32_cg_config.use_sse2) {
2472 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2473 addr.index, addr.mem, new_val);
2475 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2476 addr.index, addr.mem, new_val, mode);
2479 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2480 val = get_Conv_op(val);
2482 /* TODO: is this optimisation still necessary at all (middleend)? */
2483 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2484 while (is_Conv(val)) {
2485 ir_node *op = get_Conv_op(val);
2486 if (!mode_is_float(get_irn_mode(op)))
2488 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2492 new_val = be_transform_node(val);
2493 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2495 new_val = create_immediate_or_transform(val, 0);
2496 assert(mode != mode_b);
2498 if (get_mode_size_bits(mode) == 8) {
2499 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2500 addr.index, addr.mem, new_val);
2502 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2503 addr.index, addr.mem, new_val);
2508 set_irn_pinned(store, get_irn_pinned(node));
2509 set_ia32_op_type(store, ia32_AddrModeD);
2510 set_ia32_ls_mode(store, mode);
2512 set_address(store, &addr);
2513 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2519 * Transforms a Store.
2521 * @return the created ia32 Store node
2523 static ir_node *gen_Store(ir_node *node)
2525 ir_node *val = get_Store_value(node);
2526 ir_mode *mode = get_irn_mode(val);
2528 if (mode_is_float(mode) && is_Const(val)) {
2531 /* we are storing a floating point constant */
2532 if (ia32_cg_config.use_sse2) {
2533 transform = !is_simple_sse_Const(val);
2535 transform = !is_simple_x87_Const(val);
2538 return gen_float_const_Store(node, val);
2540 return gen_normal_Store(node);
2544 * Transforms a Switch.
2546 * @return the created ia32 SwitchJmp node
2548 static ir_node *create_Switch(ir_node *node)
2550 ir_graph *irg = current_ir_graph;
2551 dbg_info *dbgi = get_irn_dbg_info(node);
2552 ir_node *block = be_transform_node(get_nodes_block(node));
2553 ir_node *sel = get_Cond_selector(node);
2554 ir_node *new_sel = be_transform_node(sel);
2555 int switch_min = INT_MAX;
2556 int switch_max = INT_MIN;
2557 long default_pn = get_Cond_defaultProj(node);
2559 const ir_edge_t *edge;
2561 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2563 /* determine the smallest switch case value */
2564 foreach_out_edge(node, edge) {
2565 ir_node *proj = get_edge_src_irn(edge);
2566 long pn = get_Proj_proj(proj);
2567 if(pn == default_pn)
2576 if((unsigned) (switch_max - switch_min) > 256000) {
2577 panic("Size of switch %+F bigger than 256000", node);
2580 if (switch_min != 0) {
2581 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2583 /* if smallest switch case is not 0 we need an additional sub */
2584 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2585 add_ia32_am_offs_int(new_sel, -switch_min);
2586 set_ia32_op_type(new_sel, ia32_AddrModeS);
2588 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2591 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2592 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2598 * Transform a Cond node.
2600 static ir_node *gen_Cond(ir_node *node) {
2601 ir_node *block = get_nodes_block(node);
2602 ir_node *new_block = be_transform_node(block);
2603 ir_graph *irg = current_ir_graph;
2604 dbg_info *dbgi = get_irn_dbg_info(node);
2605 ir_node *sel = get_Cond_selector(node);
2606 ir_mode *sel_mode = get_irn_mode(sel);
2607 ir_node *flags = NULL;
2611 if (sel_mode != mode_b) {
2612 return create_Switch(node);
2615 /* we get flags from a Cmp */
2616 flags = get_flags_node(sel, &pnc);
2618 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2619 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2624 static ir_node *gen_be_Copy(ir_node *node)
2626 ir_node *new_node = be_duplicate_node(node);
2627 ir_mode *mode = get_irn_mode(new_node);
2629 if (ia32_mode_needs_gp_reg(mode)) {
2630 set_irn_mode(new_node, mode_Iu);
2636 static ir_node *create_Fucom(ir_node *node)
2638 ir_graph *irg = current_ir_graph;
2639 dbg_info *dbgi = get_irn_dbg_info(node);
2640 ir_node *block = get_nodes_block(node);
2641 ir_node *new_block = be_transform_node(block);
2642 ir_node *left = get_Cmp_left(node);
2643 ir_node *new_left = be_transform_node(left);
2644 ir_node *right = get_Cmp_right(node);
2648 if(ia32_cg_config.use_fucomi) {
2649 new_right = be_transform_node(right);
2650 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2652 set_ia32_commutative(new_node);
2653 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2655 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2656 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2659 new_right = be_transform_node(right);
2660 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2664 set_ia32_commutative(new_node);
2666 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2668 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2669 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2675 static ir_node *create_Ucomi(ir_node *node)
2677 ir_graph *irg = current_ir_graph;
2678 dbg_info *dbgi = get_irn_dbg_info(node);
2679 ir_node *src_block = get_nodes_block(node);
2680 ir_node *new_block = be_transform_node(src_block);
2681 ir_node *left = get_Cmp_left(node);
2682 ir_node *right = get_Cmp_right(node);
2684 ia32_address_mode_t am;
2685 ia32_address_t *addr = &am.addr;
2687 match_arguments(&am, src_block, left, right, NULL,
2688 match_commutative | match_am);
2690 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2691 addr->mem, am.new_op1, am.new_op2,
2693 set_am_attributes(new_node, &am);
2695 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2697 new_node = fix_mem_proj(new_node, &am);
2703 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2704 * to fold an and into a test node
2706 static int can_fold_test_and(ir_node *node)
2708 const ir_edge_t *edge;
2710 /** we can only have eq and lg projs */
2711 foreach_out_edge(node, edge) {
2712 ir_node *proj = get_edge_src_irn(edge);
2713 pn_Cmp pnc = get_Proj_proj(proj);
2714 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2722 * Generate code for a Cmp.
2724 static ir_node *gen_Cmp(ir_node *node)
2726 ir_graph *irg = current_ir_graph;
2727 dbg_info *dbgi = get_irn_dbg_info(node);
2728 ir_node *block = get_nodes_block(node);
2729 ir_node *new_block = be_transform_node(block);
2730 ir_node *left = get_Cmp_left(node);
2731 ir_node *right = get_Cmp_right(node);
2732 ir_mode *cmp_mode = get_irn_mode(left);
2734 ia32_address_mode_t am;
2735 ia32_address_t *addr = &am.addr;
2738 if(mode_is_float(cmp_mode)) {
2739 if (ia32_cg_config.use_sse2) {
2740 return create_Ucomi(node);
2742 return create_Fucom(node);
2746 assert(ia32_mode_needs_gp_reg(cmp_mode));
2748 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2749 cmp_unsigned = !mode_is_signed(cmp_mode);
2750 if (is_Const_0(right) &&
2752 get_irn_n_edges(left) == 1 &&
2753 can_fold_test_and(node)) {
2754 /* Test(and_left, and_right) */
2755 ir_node *and_left = get_And_left(left);
2756 ir_node *and_right = get_And_right(left);
2757 ir_mode *mode = get_irn_mode(and_left);
2759 match_arguments(&am, block, and_left, and_right, NULL,
2761 match_am | match_8bit_am | match_16bit_am |
2762 match_am_and_immediates | match_immediate |
2763 match_8bit | match_16bit);
2764 if (get_mode_size_bits(mode) == 8) {
2765 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2766 addr->index, addr->mem, am.new_op1,
2767 am.new_op2, am.ins_permuted,
2770 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2771 addr->index, addr->mem, am.new_op1,
2772 am.new_op2, am.ins_permuted, cmp_unsigned);
2775 /* Cmp(left, right) */
2776 match_arguments(&am, block, left, right, NULL,
2777 match_commutative | match_am | match_8bit_am |
2778 match_16bit_am | match_am_and_immediates |
2779 match_immediate | match_8bit | match_16bit);
2780 if (get_mode_size_bits(cmp_mode) == 8) {
2781 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2782 addr->index, addr->mem, am.new_op1,
2783 am.new_op2, am.ins_permuted,
2786 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2787 addr->index, addr->mem, am.new_op1,
2788 am.new_op2, am.ins_permuted, cmp_unsigned);
2791 set_am_attributes(new_node, &am);
2792 set_ia32_ls_mode(new_node, cmp_mode);
2794 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2796 new_node = fix_mem_proj(new_node, &am);
2801 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2804 ir_graph *irg = current_ir_graph;
2805 dbg_info *dbgi = get_irn_dbg_info(node);
2806 ir_node *block = get_nodes_block(node);
2807 ir_node *new_block = be_transform_node(block);
2808 ir_node *val_true = get_Mux_true(node);
2809 ir_node *val_false = get_Mux_false(node);
2811 match_flags_t match_flags;
2812 ia32_address_mode_t am;
2813 ia32_address_t *addr;
2815 assert(ia32_cg_config.use_cmov);
2816 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2820 match_flags = match_commutative | match_am | match_16bit_am |
2823 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2825 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2826 addr->mem, am.new_op1, am.new_op2, new_flags,
2827 am.ins_permuted, pnc);
2828 set_am_attributes(new_node, &am);
2830 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2832 new_node = fix_mem_proj(new_node, &am);
2838 * Creates a ia32 Setcc instruction.
2840 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2841 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2844 ir_graph *irg = current_ir_graph;
2845 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2846 ir_node *nomem = new_NoMem();
2847 ir_mode *mode = get_irn_mode(orig_node);
2850 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2851 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2853 /* we might need to conv the result up */
2854 if (get_mode_size_bits(mode) > 8) {
2855 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2856 nomem, new_node, mode_Bu);
2857 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2864 * Create instruction for an unsigned Difference or Zero.
2866 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2867 ir_graph *irg = current_ir_graph;
2868 ir_mode *mode = get_irn_mode(psi);
2869 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2872 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2873 match_mode_neutral | match_am | match_immediate | match_two_users);
2875 block = get_nodes_block(new_node);
2877 if (is_Proj(new_node)) {
2878 sub = get_Proj_pred(new_node);
2879 assert(is_ia32_Sub(sub));
2882 set_irn_mode(sub, mode_T);
2883 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2885 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2887 dbgi = get_irn_dbg_info(psi);
2888 noreg = ia32_new_NoReg_gp(env_cg);
2889 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2890 nomem = new_NoMem();
2891 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2893 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2894 set_ia32_commutative(new_node);
2899 * Transforms a Mux node into CMov.
2901 * @return The transformed node.
2903 static ir_node *gen_Mux(ir_node *node)
2905 dbg_info *dbgi = get_irn_dbg_info(node);
2906 ir_node *block = get_nodes_block(node);
2907 ir_node *new_block = be_transform_node(block);
2908 ir_node *mux_true = get_Mux_true(node);
2909 ir_node *mux_false = get_Mux_false(node);
2910 ir_node *cond = get_Mux_sel(node);
2911 ir_mode *mode = get_irn_mode(node);
2914 assert(get_irn_mode(cond) == mode_b);
2916 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2917 if (mode_is_float(mode)) {
2918 ir_node *cmp = get_Proj_pred(cond);
2919 ir_node *cmp_left = get_Cmp_left(cmp);
2920 ir_node *cmp_right = get_Cmp_right(cmp);
2921 pn_Cmp pnc = get_Proj_proj(cond);
2923 if (ia32_cg_config.use_sse2) {
2924 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2925 if (cmp_left == mux_true && cmp_right == mux_false) {
2926 /* Mux(a <= b, a, b) => MIN */
2927 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2928 match_commutative | match_am | match_two_users);
2929 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2930 /* Mux(a <= b, b, a) => MAX */
2931 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2932 match_commutative | match_am | match_two_users);
2934 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2935 if (cmp_left == mux_true && cmp_right == mux_false) {
2936 /* Mux(a >= b, a, b) => MAX */
2937 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2938 match_commutative | match_am | match_two_users);
2939 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2940 /* Mux(a >= b, b, a) => MIN */
2941 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2942 match_commutative | match_am | match_two_users);
2946 panic("cannot transform floating point Mux");
2952 assert(ia32_mode_needs_gp_reg(mode));
2954 if (is_Proj(cond)) {
2955 ir_node *cmp = get_Proj_pred(cond);
2957 ir_node *cmp_left = get_Cmp_left(cmp);
2958 ir_node *cmp_right = get_Cmp_right(cmp);
2959 pn_Cmp pnc = get_Proj_proj(cond);
2961 /* check for unsigned Doz first */
2962 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2963 is_Const_0(mux_false) && is_Sub(mux_true) &&
2964 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2965 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2966 return create_Doz(node, cmp_left, cmp_right);
2967 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2968 is_Const_0(mux_true) && is_Sub(mux_false) &&
2969 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2970 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2971 return create_Doz(node, cmp_left, cmp_right);
2976 flags = get_flags_node(cond, &pnc);
2978 if (is_Const(mux_true) && is_Const(mux_false)) {
2979 /* both are const, good */
2980 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2981 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2982 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2983 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2985 /* Not that simple. */
2990 new_node = create_CMov(node, cond, flags, pnc);
2998 * Create a conversion from x87 state register to general purpose.
3000 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3001 ir_node *block = be_transform_node(get_nodes_block(node));
3002 ir_node *op = get_Conv_op(node);
3003 ir_node *new_op = be_transform_node(op);
3004 ia32_code_gen_t *cg = env_cg;
3005 ir_graph *irg = current_ir_graph;
3006 dbg_info *dbgi = get_irn_dbg_info(node);
3007 ir_node *noreg = ia32_new_NoReg_gp(cg);
3008 ir_mode *mode = get_irn_mode(node);
3009 ir_node *fist, *load, *mem;
3011 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3012 set_irn_pinned(fist, op_pin_state_floats);
3013 set_ia32_use_frame(fist);
3014 set_ia32_op_type(fist, ia32_AddrModeD);
3016 assert(get_mode_size_bits(mode) <= 32);
3017 /* exception we can only store signed 32 bit integers, so for unsigned
3018 we store a 64bit (signed) integer and load the lower bits */
3019 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3020 set_ia32_ls_mode(fist, mode_Ls);
3022 set_ia32_ls_mode(fist, mode_Is);
3024 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3027 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3029 set_irn_pinned(load, op_pin_state_floats);
3030 set_ia32_use_frame(load);
3031 set_ia32_op_type(load, ia32_AddrModeS);
3032 set_ia32_ls_mode(load, mode_Is);
3033 if(get_ia32_ls_mode(fist) == mode_Ls) {
3034 ia32_attr_t *attr = get_ia32_attr(load);
3035 attr->data.need_64bit_stackent = 1;
3037 ia32_attr_t *attr = get_ia32_attr(load);
3038 attr->data.need_32bit_stackent = 1;
3040 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3042 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3046 * Creates a x87 strict Conv by placing a Store and a Load
3048 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3050 ir_node *block = get_nodes_block(node);
3051 ir_graph *irg = current_ir_graph;
3052 dbg_info *dbgi = get_irn_dbg_info(node);
3053 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3054 ir_node *nomem = new_NoMem();
3055 ir_node *frame = get_irg_frame(irg);
3056 ir_node *store, *load;
3059 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3061 set_ia32_use_frame(store);
3062 set_ia32_op_type(store, ia32_AddrModeD);
3063 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3065 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3067 set_ia32_use_frame(load);
3068 set_ia32_op_type(load, ia32_AddrModeS);
3069 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3071 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3076 * Create a conversion from general purpose to x87 register
3078 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3079 ir_node *src_block = get_nodes_block(node);
3080 ir_node *block = be_transform_node(src_block);
3081 ir_graph *irg = current_ir_graph;
3082 dbg_info *dbgi = get_irn_dbg_info(node);
3083 ir_node *op = get_Conv_op(node);
3084 ir_node *new_op = NULL;
3088 ir_mode *store_mode;
3094 /* fild can use source AM if the operand is a signed 32bit integer */
3095 if (src_mode == mode_Is) {
3096 ia32_address_mode_t am;
3098 match_arguments(&am, src_block, NULL, op, NULL,
3099 match_am | match_try_am);
3100 if (am.op_type == ia32_AddrModeS) {
3101 ia32_address_t *addr = &am.addr;
3103 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3104 addr->index, addr->mem);
3105 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3108 set_am_attributes(fild, &am);
3109 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3111 fix_mem_proj(fild, &am);
3116 if(new_op == NULL) {
3117 new_op = be_transform_node(op);
3120 noreg = ia32_new_NoReg_gp(env_cg);
3121 nomem = new_NoMem();
3122 mode = get_irn_mode(op);
3124 /* first convert to 32 bit signed if necessary */
3125 src_bits = get_mode_size_bits(src_mode);
3126 if (src_bits == 8) {
3127 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3129 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3131 } else if (src_bits < 32) {
3132 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3134 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3138 assert(get_mode_size_bits(mode) == 32);
3141 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3144 set_ia32_use_frame(store);
3145 set_ia32_op_type(store, ia32_AddrModeD);
3146 set_ia32_ls_mode(store, mode_Iu);
3148 /* exception for 32bit unsigned, do a 64bit spill+load */
3149 if(!mode_is_signed(mode)) {
3152 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3154 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3155 get_irg_frame(irg), noreg, nomem,
3158 set_ia32_use_frame(zero_store);
3159 set_ia32_op_type(zero_store, ia32_AddrModeD);
3160 add_ia32_am_offs_int(zero_store, 4);
3161 set_ia32_ls_mode(zero_store, mode_Iu);
3166 store = new_rd_Sync(dbgi, irg, block, 2, in);
3167 store_mode = mode_Ls;
3169 store_mode = mode_Is;
3173 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3175 set_ia32_use_frame(fild);
3176 set_ia32_op_type(fild, ia32_AddrModeS);
3177 set_ia32_ls_mode(fild, store_mode);
3179 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3185 * Create a conversion from one integer mode into another one
3187 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3188 dbg_info *dbgi, ir_node *block, ir_node *op,
3191 ir_graph *irg = current_ir_graph;
3192 int src_bits = get_mode_size_bits(src_mode);
3193 int tgt_bits = get_mode_size_bits(tgt_mode);
3194 ir_node *new_block = be_transform_node(block);
3196 ir_mode *smaller_mode;
3198 ia32_address_mode_t am;
3199 ia32_address_t *addr = &am.addr;
3202 if (src_bits < tgt_bits) {
3203 smaller_mode = src_mode;
3204 smaller_bits = src_bits;
3206 smaller_mode = tgt_mode;
3207 smaller_bits = tgt_bits;
3210 #ifdef DEBUG_libfirm
3212 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3217 match_arguments(&am, block, NULL, op, NULL,
3218 match_8bit | match_16bit |
3219 match_am | match_8bit_am | match_16bit_am);
3220 if (smaller_bits == 8) {
3221 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3222 addr->index, addr->mem, am.new_op2,
3225 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3226 addr->index, addr->mem, am.new_op2,
3229 set_am_attributes(new_node, &am);
3230 /* match_arguments assume that out-mode = in-mode, this isn't true here
3232 set_ia32_ls_mode(new_node, smaller_mode);
3233 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3234 new_node = fix_mem_proj(new_node, &am);
3239 * Transforms a Conv node.
3241 * @return The created ia32 Conv node
3243 static ir_node *gen_Conv(ir_node *node) {
3244 ir_node *block = get_nodes_block(node);
3245 ir_node *new_block = be_transform_node(block);
3246 ir_node *op = get_Conv_op(node);
3247 ir_node *new_op = NULL;
3248 ir_graph *irg = current_ir_graph;
3249 dbg_info *dbgi = get_irn_dbg_info(node);
3250 ir_mode *src_mode = get_irn_mode(op);
3251 ir_mode *tgt_mode = get_irn_mode(node);
3252 int src_bits = get_mode_size_bits(src_mode);
3253 int tgt_bits = get_mode_size_bits(tgt_mode);
3254 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3255 ir_node *nomem = new_rd_NoMem(irg);
3256 ir_node *res = NULL;
3258 if (src_mode == mode_b) {
3259 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3260 /* nothing to do, we already model bools as 0/1 ints */
3261 return be_transform_node(op);
3264 if (src_mode == tgt_mode) {
3265 if (get_Conv_strict(node)) {
3266 if (ia32_cg_config.use_sse2) {
3267 /* when we are in SSE mode, we can kill all strict no-op conversion */
3268 return be_transform_node(op);
3271 /* this should be optimized already, but who knows... */
3272 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3273 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3274 return be_transform_node(op);
3278 if (mode_is_float(src_mode)) {
3279 new_op = be_transform_node(op);
3280 /* we convert from float ... */
3281 if (mode_is_float(tgt_mode)) {
3282 if(src_mode == mode_E && tgt_mode == mode_D
3283 && !get_Conv_strict(node)) {
3284 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3289 if (ia32_cg_config.use_sse2) {
3290 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3291 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3293 set_ia32_ls_mode(res, tgt_mode);
3295 if(get_Conv_strict(node)) {
3296 res = gen_x87_strict_conv(tgt_mode, new_op);
3297 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3300 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3305 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3306 if (ia32_cg_config.use_sse2) {
3307 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3309 set_ia32_ls_mode(res, src_mode);
3311 return gen_x87_fp_to_gp(node);
3315 /* we convert from int ... */
3316 if (mode_is_float(tgt_mode)) {
3318 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3319 if (ia32_cg_config.use_sse2) {
3320 new_op = be_transform_node(op);
3321 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3323 set_ia32_ls_mode(res, tgt_mode);
3325 res = gen_x87_gp_to_fp(node, src_mode);
3326 if(get_Conv_strict(node)) {
3327 /* The strict-Conv is only necessary, if the int mode has more bits
3328 * than the float mantissa */
3329 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3330 size_t float_mantissa;
3331 /* FIXME There is no way to get the mantissa size of a mode */
3332 switch (get_mode_size_bits(tgt_mode)) {
3333 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3334 case 64: float_mantissa = 52 + 1; break;
3336 case 96: float_mantissa = 64; break;
3337 default: float_mantissa = 0; break;
3339 if (float_mantissa < int_mantissa) {
3340 res = gen_x87_strict_conv(tgt_mode, res);
3341 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3346 } else if(tgt_mode == mode_b) {
3347 /* mode_b lowering already took care that we only have 0/1 values */
3348 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3349 src_mode, tgt_mode));
3350 return be_transform_node(op);
3353 if (src_bits == tgt_bits) {
3354 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3355 src_mode, tgt_mode));
3356 return be_transform_node(op);
3359 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3367 static ir_node *create_immediate_or_transform(ir_node *node,
3368 char immediate_constraint_type)
3370 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3371 if (new_node == NULL) {
3372 new_node = be_transform_node(node);
3378 * Transforms a FrameAddr into an ia32 Add.
3380 static ir_node *gen_be_FrameAddr(ir_node *node) {
3381 ir_node *block = be_transform_node(get_nodes_block(node));
3382 ir_node *op = be_get_FrameAddr_frame(node);
3383 ir_node *new_op = be_transform_node(op);
3384 ir_graph *irg = current_ir_graph;
3385 dbg_info *dbgi = get_irn_dbg_info(node);
3386 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3389 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3390 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3391 set_ia32_use_frame(new_node);
3393 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3399 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3401 static ir_node *gen_be_Return(ir_node *node) {
3402 ir_graph *irg = current_ir_graph;
3403 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3404 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3405 ir_entity *ent = get_irg_entity(irg);
3406 ir_type *tp = get_entity_type(ent);
3411 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3412 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3415 int pn_ret_val, pn_ret_mem, arity, i;
3417 assert(ret_val != NULL);
3418 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3419 return be_duplicate_node(node);
3422 res_type = get_method_res_type(tp, 0);
3424 if (! is_Primitive_type(res_type)) {
3425 return be_duplicate_node(node);
3428 mode = get_type_mode(res_type);
3429 if (! mode_is_float(mode)) {
3430 return be_duplicate_node(node);
3433 assert(get_method_n_ress(tp) == 1);
3435 pn_ret_val = get_Proj_proj(ret_val);
3436 pn_ret_mem = get_Proj_proj(ret_mem);
3438 /* get the Barrier */
3439 barrier = get_Proj_pred(ret_val);
3441 /* get result input of the Barrier */
3442 ret_val = get_irn_n(barrier, pn_ret_val);
3443 new_ret_val = be_transform_node(ret_val);
3445 /* get memory input of the Barrier */
3446 ret_mem = get_irn_n(barrier, pn_ret_mem);
3447 new_ret_mem = be_transform_node(ret_mem);
3449 frame = get_irg_frame(irg);
3451 dbgi = get_irn_dbg_info(barrier);
3452 block = be_transform_node(get_nodes_block(barrier));
3454 noreg = ia32_new_NoReg_gp(env_cg);
3456 /* store xmm0 onto stack */
3457 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3458 new_ret_mem, new_ret_val);
3459 set_ia32_ls_mode(sse_store, mode);
3460 set_ia32_op_type(sse_store, ia32_AddrModeD);
3461 set_ia32_use_frame(sse_store);
3463 /* load into x87 register */
3464 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3465 set_ia32_op_type(fld, ia32_AddrModeS);
3466 set_ia32_use_frame(fld);
3468 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3469 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3471 /* create a new barrier */
3472 arity = get_irn_arity(barrier);
3473 in = alloca(arity * sizeof(in[0]));
3474 for (i = 0; i < arity; ++i) {
3477 if (i == pn_ret_val) {
3479 } else if (i == pn_ret_mem) {
3482 ir_node *in = get_irn_n(barrier, i);
3483 new_in = be_transform_node(in);
3488 new_barrier = new_ir_node(dbgi, irg, block,
3489 get_irn_op(barrier), get_irn_mode(barrier),
3491 copy_node_attr(barrier, new_barrier);
3492 be_duplicate_deps(barrier, new_barrier);
3493 be_set_transformed_node(barrier, new_barrier);
3494 mark_irn_visited(barrier);
3496 /* transform normally */
3497 return be_duplicate_node(node);
3501 * Transform a be_AddSP into an ia32_SubSP.
3503 static ir_node *gen_be_AddSP(ir_node *node)
3505 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3506 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3508 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
3512 * Transform a be_SubSP into an ia32_AddSP
3514 static ir_node *gen_be_SubSP(ir_node *node)
3516 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3517 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3519 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
3523 * Change some phi modes
3525 static ir_node *gen_Phi(ir_node *node) {
3526 ir_node *block = be_transform_node(get_nodes_block(node));
3527 ir_graph *irg = current_ir_graph;
3528 dbg_info *dbgi = get_irn_dbg_info(node);
3529 ir_mode *mode = get_irn_mode(node);
3532 if(ia32_mode_needs_gp_reg(mode)) {
3533 /* we shouldn't have any 64bit stuff around anymore */
3534 assert(get_mode_size_bits(mode) <= 32);
3535 /* all integer operations are on 32bit registers now */
3537 } else if(mode_is_float(mode)) {
3538 if (ia32_cg_config.use_sse2) {
3545 /* phi nodes allow loops, so we use the old arguments for now
3546 * and fix this later */
3547 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3548 get_irn_in(node) + 1);
3549 copy_node_attr(node, phi);
3550 be_duplicate_deps(node, phi);
3552 be_set_transformed_node(node, phi);
3553 be_enqueue_preds(node);
3561 static ir_node *gen_IJmp(ir_node *node)
3563 ir_node *block = get_nodes_block(node);
3564 ir_node *new_block = be_transform_node(block);
3565 dbg_info *dbgi = get_irn_dbg_info(node);
3566 ir_node *op = get_IJmp_target(node);
3568 ia32_address_mode_t am;
3569 ia32_address_t *addr = &am.addr;
3571 assert(get_irn_mode(op) == mode_P);
3573 match_arguments(&am, block, NULL, op, NULL,
3574 match_am | match_8bit_am | match_16bit_am |
3575 match_immediate | match_8bit | match_16bit);
3577 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3578 addr->base, addr->index, addr->mem,
3580 set_am_attributes(new_node, &am);
3581 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3583 new_node = fix_mem_proj(new_node, &am);
3589 * Transform a Bound node.
3591 static ir_node *gen_Bound(ir_node *node)
3594 ir_node *lower = get_Bound_lower(node);
3595 dbg_info *dbgi = get_irn_dbg_info(node);
3597 if (is_Const_0(lower)) {
3598 /* typical case for Java */
3599 ir_node *sub, *res, *flags, *block;
3600 ir_graph *irg = current_ir_graph;
3602 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3603 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3605 block = get_nodes_block(res);
3606 if (! is_Proj(res)) {
3608 set_irn_mode(sub, mode_T);
3609 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3611 sub = get_Proj_pred(res);
3613 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3614 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3615 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3617 panic("generic Bound not supported in ia32 Backend");
3623 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3625 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3626 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3628 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3629 match_immediate | match_mode_neutral);
3632 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3634 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3635 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3636 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3640 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3642 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3643 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3644 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3648 static ir_node *gen_ia32_l_Add(ir_node *node) {
3649 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3650 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3651 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3652 match_commutative | match_am | match_immediate |
3653 match_mode_neutral);
3655 if(is_Proj(lowered)) {
3656 lowered = get_Proj_pred(lowered);
3658 assert(is_ia32_Add(lowered));
3659 set_irn_mode(lowered, mode_T);
3665 static ir_node *gen_ia32_l_Adc(ir_node *node)
3667 return gen_binop_flags(node, new_rd_ia32_Adc,
3668 match_commutative | match_am | match_immediate |
3669 match_mode_neutral);
3673 * Transforms a l_MulS into a "real" MulS node.
3675 * @return the created ia32 Mul node
3677 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3678 ir_node *left = get_binop_left(node);
3679 ir_node *right = get_binop_right(node);
3681 return gen_binop(node, left, right, new_rd_ia32_Mul,
3682 match_commutative | match_am | match_mode_neutral);
3686 * Transforms a l_IMulS into a "real" IMul1OPS node.
3688 * @return the created ia32 IMul1OP node
3690 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3691 ir_node *left = get_binop_left(node);
3692 ir_node *right = get_binop_right(node);
3694 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3695 match_commutative | match_am | match_mode_neutral);
3698 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3699 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3700 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3701 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3702 match_am | match_immediate | match_mode_neutral);
3704 if(is_Proj(lowered)) {
3705 lowered = get_Proj_pred(lowered);
3707 assert(is_ia32_Sub(lowered));
3708 set_irn_mode(lowered, mode_T);
3714 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3715 return gen_binop_flags(node, new_rd_ia32_Sbb,
3716 match_am | match_immediate | match_mode_neutral);
3720 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3721 * op1 - target to be shifted
3722 * op2 - contains bits to be shifted into target
3724 * Only op3 can be an immediate.
3726 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3727 ir_node *low, ir_node *count)
3729 ir_node *block = get_nodes_block(node);
3730 ir_node *new_block = be_transform_node(block);
3731 ir_graph *irg = current_ir_graph;
3732 dbg_info *dbgi = get_irn_dbg_info(node);
3733 ir_node *new_high = be_transform_node(high);
3734 ir_node *new_low = be_transform_node(low);
3738 /* the shift amount can be any mode that is bigger than 5 bits, since all
3739 * other bits are ignored anyway */
3740 while (is_Conv(count) &&
3741 get_irn_n_edges(count) == 1 &&
3742 mode_is_int(get_irn_mode(count))) {
3743 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3744 count = get_Conv_op(count);
3746 new_count = create_immediate_or_transform(count, 0);
3748 if (is_ia32_l_ShlD(node)) {
3749 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3752 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3755 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3760 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3762 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3763 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3764 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3765 return gen_lowered_64bit_shifts(node, high, low, count);
3768 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3770 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3771 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3772 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3773 return gen_lowered_64bit_shifts(node, high, low, count);
3776 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3777 ir_node *src_block = get_nodes_block(node);
3778 ir_node *block = be_transform_node(src_block);
3779 ir_graph *irg = current_ir_graph;
3780 dbg_info *dbgi = get_irn_dbg_info(node);
3781 ir_node *frame = get_irg_frame(irg);
3782 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3783 ir_node *nomem = new_NoMem();
3784 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3785 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3786 ir_node *new_val_low = be_transform_node(val_low);
3787 ir_node *new_val_high = be_transform_node(val_high);
3792 ir_node *store_high;
3794 if(!mode_is_signed(get_irn_mode(val_high))) {
3795 panic("unsigned long long -> float not supported yet (%+F)", node);
3799 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3801 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3803 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3804 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3806 set_ia32_use_frame(store_low);
3807 set_ia32_use_frame(store_high);
3808 set_ia32_op_type(store_low, ia32_AddrModeD);
3809 set_ia32_op_type(store_high, ia32_AddrModeD);
3810 set_ia32_ls_mode(store_low, mode_Iu);
3811 set_ia32_ls_mode(store_high, mode_Is);
3812 add_ia32_am_offs_int(store_high, 4);
3816 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3819 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3821 set_ia32_use_frame(fild);
3822 set_ia32_op_type(fild, ia32_AddrModeS);
3823 set_ia32_ls_mode(fild, mode_Ls);
3825 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3827 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3830 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3831 ir_node *src_block = get_nodes_block(node);
3832 ir_node *block = be_transform_node(src_block);
3833 ir_graph *irg = current_ir_graph;
3834 dbg_info *dbgi = get_irn_dbg_info(node);
3835 ir_node *frame = get_irg_frame(irg);
3836 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3837 ir_node *nomem = new_NoMem();
3838 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3839 ir_node *new_val = be_transform_node(val);
3840 ir_node *fist, *mem;
3842 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3843 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3844 set_ia32_use_frame(fist);
3845 set_ia32_op_type(fist, ia32_AddrModeD);
3846 set_ia32_ls_mode(fist, mode_Ls);
3852 * the BAD transformer.
3854 static ir_node *bad_transform(ir_node *node) {
3855 panic("No transform function for %+F available.", node);
3859 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
3860 ir_graph *irg = current_ir_graph;
3861 ir_node *block = be_transform_node(get_nodes_block(node));
3862 ir_node *pred = get_Proj_pred(node);
3863 ir_node *new_pred = be_transform_node(pred);
3864 ir_node *frame = get_irg_frame(irg);
3865 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3866 dbg_info *dbgi = get_irn_dbg_info(node);
3867 long pn = get_Proj_proj(node);
3872 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3873 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3874 set_ia32_use_frame(load);
3875 set_ia32_op_type(load, ia32_AddrModeS);
3876 set_ia32_ls_mode(load, mode_Iu);
3877 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3878 * 32 bit from it with this particular load */
3879 attr = get_ia32_attr(load);
3880 attr->data.need_64bit_stackent = 1;
3882 if (pn == pn_ia32_l_FloattoLL_res_high) {
3883 add_ia32_am_offs_int(load, 4);
3885 assert(pn == pn_ia32_l_FloattoLL_res_low);
3888 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3894 * Transform the Projs of an AddSP.
3896 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
3897 ir_node *block = be_transform_node(get_nodes_block(node));
3898 ir_node *pred = get_Proj_pred(node);
3899 ir_node *new_pred = be_transform_node(pred);
3900 ir_graph *irg = current_ir_graph;
3901 dbg_info *dbgi = get_irn_dbg_info(node);
3902 long proj = get_Proj_proj(node);
3904 if (proj == pn_be_AddSP_sp) {
3905 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3906 pn_ia32_SubSP_stack);
3907 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3909 } else if(proj == pn_be_AddSP_res) {
3910 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3911 pn_ia32_SubSP_addr);
3912 } else if (proj == pn_be_AddSP_M) {
3913 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3917 return new_rd_Unknown(irg, get_irn_mode(node));
3921 * Transform the Projs of a SubSP.
3923 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
3924 ir_node *block = be_transform_node(get_nodes_block(node));
3925 ir_node *pred = get_Proj_pred(node);
3926 ir_node *new_pred = be_transform_node(pred);
3927 ir_graph *irg = current_ir_graph;
3928 dbg_info *dbgi = get_irn_dbg_info(node);
3929 long proj = get_Proj_proj(node);
3931 if (proj == pn_be_SubSP_sp) {
3932 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3933 pn_ia32_AddSP_stack);
3934 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3936 } else if (proj == pn_be_SubSP_M) {
3937 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3941 return new_rd_Unknown(irg, get_irn_mode(node));
3945 * Transform and renumber the Projs from a Load.
3947 static ir_node *gen_Proj_Load(ir_node *node) {
3949 ir_node *block = be_transform_node(get_nodes_block(node));
3950 ir_node *pred = get_Proj_pred(node);
3951 ir_graph *irg = current_ir_graph;
3952 dbg_info *dbgi = get_irn_dbg_info(node);
3953 long proj = get_Proj_proj(node);
3955 /* loads might be part of source address mode matches, so we don't
3956 * transform the ProjMs yet (with the exception of loads whose result is
3959 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
3962 /* this is needed, because sometimes we have loops that are only
3963 reachable through the ProjM */
3964 be_enqueue_preds(node);
3965 /* do it in 2 steps, to silence firm verifier */
3966 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
3967 set_Proj_proj(res, pn_ia32_mem);
3971 /* renumber the proj */
3972 new_pred = be_transform_node(pred);
3973 if (is_ia32_Load(new_pred)) {
3976 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
3978 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
3979 case pn_Load_X_regular:
3980 return new_rd_Jmp(dbgi, irg, block);
3981 case pn_Load_X_except:
3982 /* This Load might raise an exception. Mark it. */
3983 set_ia32_exc_label(new_pred, 1);
3984 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
3988 } else if (is_ia32_Conv_I2I(new_pred) ||
3989 is_ia32_Conv_I2I8Bit(new_pred)) {
3990 set_irn_mode(new_pred, mode_T);
3991 if (proj == pn_Load_res) {
3992 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
3993 } else if (proj == pn_Load_M) {
3994 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
3996 } else if (is_ia32_xLoad(new_pred)) {
3999 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4001 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4002 case pn_Load_X_regular:
4003 return new_rd_Jmp(dbgi, irg, block);
4004 case pn_Load_X_except:
4005 /* This Load might raise an exception. Mark it. */
4006 set_ia32_exc_label(new_pred, 1);
4007 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4011 } else if (is_ia32_vfld(new_pred)) {
4014 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4016 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4017 case pn_Load_X_regular:
4018 return new_rd_Jmp(dbgi, irg, block);
4019 case pn_Load_X_except:
4020 /* This Load might raise an exception. Mark it. */
4021 set_ia32_exc_label(new_pred, 1);
4022 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4027 /* can happen for ProJMs when source address mode happened for the
4030 /* however it should not be the result proj, as that would mean the
4031 load had multiple users and should not have been used for
4033 if (proj != pn_Load_M) {
4034 panic("internal error: transformed node not a Load");
4036 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4040 return new_rd_Unknown(irg, get_irn_mode(node));
4044 * Transform and renumber the Projs from a DivMod like instruction.
4046 static ir_node *gen_Proj_DivMod(ir_node *node) {
4047 ir_node *block = be_transform_node(get_nodes_block(node));
4048 ir_node *pred = get_Proj_pred(node);
4049 ir_node *new_pred = be_transform_node(pred);
4050 ir_graph *irg = current_ir_graph;
4051 dbg_info *dbgi = get_irn_dbg_info(node);
4052 ir_mode *mode = get_irn_mode(node);
4053 long proj = get_Proj_proj(node);
4055 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4057 switch (get_irn_opcode(pred)) {
4061 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4063 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4064 case pn_Div_X_regular:
4065 return new_rd_Jmp(dbgi, irg, block);
4066 case pn_Div_X_except:
4067 set_ia32_exc_label(new_pred, 1);
4068 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4076 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4078 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4079 case pn_Mod_X_except:
4080 set_ia32_exc_label(new_pred, 1);
4081 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4089 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4090 case pn_DivMod_res_div:
4091 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4092 case pn_DivMod_res_mod:
4093 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4094 case pn_DivMod_X_regular:
4095 return new_rd_Jmp(dbgi, irg, block);
4096 case pn_DivMod_X_except:
4097 set_ia32_exc_label(new_pred, 1);
4098 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4108 return new_rd_Unknown(irg, mode);
4112 * Transform and renumber the Projs from a CopyB.
4114 static ir_node *gen_Proj_CopyB(ir_node *node) {
4115 ir_node *block = be_transform_node(get_nodes_block(node));
4116 ir_node *pred = get_Proj_pred(node);
4117 ir_node *new_pred = be_transform_node(pred);
4118 ir_graph *irg = current_ir_graph;
4119 dbg_info *dbgi = get_irn_dbg_info(node);
4120 ir_mode *mode = get_irn_mode(node);
4121 long proj = get_Proj_proj(node);
4124 case pn_CopyB_M_regular:
4125 if (is_ia32_CopyB_i(new_pred)) {
4126 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4127 } else if (is_ia32_CopyB(new_pred)) {
4128 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4136 return new_rd_Unknown(irg, mode);
4140 * Transform and renumber the Projs from a Quot.
4142 static ir_node *gen_Proj_Quot(ir_node *node) {
4143 ir_node *block = be_transform_node(get_nodes_block(node));
4144 ir_node *pred = get_Proj_pred(node);
4145 ir_node *new_pred = be_transform_node(pred);
4146 ir_graph *irg = current_ir_graph;
4147 dbg_info *dbgi = get_irn_dbg_info(node);
4148 ir_mode *mode = get_irn_mode(node);
4149 long proj = get_Proj_proj(node);
4153 if (is_ia32_xDiv(new_pred)) {
4154 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4155 } else if (is_ia32_vfdiv(new_pred)) {
4156 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4160 if (is_ia32_xDiv(new_pred)) {
4161 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4162 } else if (is_ia32_vfdiv(new_pred)) {
4163 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4166 case pn_Quot_X_regular:
4167 case pn_Quot_X_except:
4173 return new_rd_Unknown(irg, mode);
4176 static ir_node *gen_be_Call(ir_node *node) {
4177 ir_node *res = be_duplicate_node(node);
4180 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4182 /* Run the x87 simulator if the call returns a float value */
4183 call_tp = be_Call_get_type(node);
4184 if (get_method_n_ress(call_tp) > 0) {
4185 ir_type *const res_type = get_method_res_type(call_tp, 0);
4186 ir_mode *const res_mode = get_type_mode(res_type);
4188 if (res_mode != NULL && mode_is_float(res_mode)) {
4189 env_cg->do_x87_sim = 1;
4196 static ir_node *gen_be_IncSP(ir_node *node) {
4197 ir_node *res = be_duplicate_node(node);
4198 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4204 * Transform the Projs from a be_Call.
4206 static ir_node *gen_Proj_be_Call(ir_node *node) {
4207 ir_node *block = be_transform_node(get_nodes_block(node));
4208 ir_node *call = get_Proj_pred(node);
4209 ir_node *new_call = be_transform_node(call);
4210 ir_graph *irg = current_ir_graph;
4211 dbg_info *dbgi = get_irn_dbg_info(node);
4212 ir_type *method_type = be_Call_get_type(call);
4213 int n_res = get_method_n_ress(method_type);
4214 long proj = get_Proj_proj(node);
4215 ir_mode *mode = get_irn_mode(node);
4217 const arch_register_class_t *cls;
4219 /* The following is kinda tricky: If we're using SSE, then we have to
4220 * move the result value of the call in floating point registers to an
4221 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4222 * after the call, we have to make sure to correctly make the
4223 * MemProj and the result Proj use these 2 nodes
4225 if (proj == pn_be_Call_M_regular) {
4226 // get new node for result, are we doing the sse load/store hack?
4227 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4228 ir_node *call_res_new;
4229 ir_node *call_res_pred = NULL;
4231 if (call_res != NULL) {
4232 call_res_new = be_transform_node(call_res);
4233 call_res_pred = get_Proj_pred(call_res_new);
4236 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4237 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4238 pn_be_Call_M_regular);
4240 assert(is_ia32_xLoad(call_res_pred));
4241 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4245 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4246 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4248 ir_node *frame = get_irg_frame(irg);
4249 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4251 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4254 /* in case there is no memory output: create one to serialize the copy
4256 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4257 pn_be_Call_M_regular);
4258 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4259 pn_be_Call_first_res);
4261 /* store st(0) onto stack */
4262 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4264 set_ia32_op_type(fstp, ia32_AddrModeD);
4265 set_ia32_use_frame(fstp);
4267 /* load into SSE register */
4268 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4270 set_ia32_op_type(sse_load, ia32_AddrModeS);
4271 set_ia32_use_frame(sse_load);
4273 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4279 /* transform call modes */
4280 if (mode_is_data(mode)) {
4281 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4285 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4289 * Transform the Projs from a Cmp.
4291 static ir_node *gen_Proj_Cmp(ir_node *node)
4293 /* this probably means not all mode_b nodes were lowered... */
4294 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4299 * Transform the Projs from a Bound.
4301 static ir_node *gen_Proj_Bound(ir_node *node)
4303 ir_node *new_node, *block;
4304 ir_node *pred = get_Proj_pred(node);
4306 switch (get_Proj_proj(node)) {
4308 return be_transform_node(get_Bound_mem(pred));
4309 case pn_Bound_X_regular:
4310 new_node = be_transform_node(pred);
4311 block = get_nodes_block(new_node);
4312 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4313 case pn_Bound_X_except:
4314 new_node = be_transform_node(pred);
4315 block = get_nodes_block(new_node);
4316 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4318 return be_transform_node(get_Bound_index(pred));
4320 panic("unsupported Proj from Bound");
4324 static ir_node *gen_Proj_ASM(ir_node *node)
4330 if (get_irn_mode(node) != mode_M)
4331 return be_duplicate_node(node);
4333 pred = get_Proj_pred(node);
4334 new_pred = be_transform_node(pred);
4335 block = get_nodes_block(new_pred);
4336 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4337 get_ia32_n_res(new_pred) + 1);
4341 * Transform and potentially renumber Proj nodes.
4343 static ir_node *gen_Proj(ir_node *node) {
4344 ir_node *pred = get_Proj_pred(node);
4347 switch (get_irn_opcode(pred)) {
4349 proj = get_Proj_proj(node);
4350 if (proj == pn_Store_M) {
4351 return be_transform_node(pred);
4354 return new_r_Bad(current_ir_graph);
4357 return gen_Proj_Load(node);
4359 return gen_Proj_ASM(node);
4363 return gen_Proj_DivMod(node);
4365 return gen_Proj_CopyB(node);
4367 return gen_Proj_Quot(node);
4369 return gen_Proj_be_SubSP(node);
4371 return gen_Proj_be_AddSP(node);
4373 return gen_Proj_be_Call(node);
4375 return gen_Proj_Cmp(node);
4377 return gen_Proj_Bound(node);
4379 proj = get_Proj_proj(node);
4380 if (proj == pn_Start_X_initial_exec) {
4381 ir_node *block = get_nodes_block(pred);
4382 dbg_info *dbgi = get_irn_dbg_info(node);
4385 /* we exchange the ProjX with a jump */
4386 block = be_transform_node(block);
4387 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
4390 if (node == be_get_old_anchor(anchor_tls)) {
4391 return gen_Proj_tls(node);
4396 if (is_ia32_l_FloattoLL(pred)) {
4397 return gen_Proj_l_FloattoLL(node);
4399 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4403 ir_mode *mode = get_irn_mode(node);
4404 if (ia32_mode_needs_gp_reg(mode)) {
4405 ir_node *new_pred = be_transform_node(pred);
4406 ir_node *block = be_transform_node(get_nodes_block(node));
4407 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4408 mode_Iu, get_Proj_proj(node));
4409 #ifdef DEBUG_libfirm
4410 new_proj->node_nr = node->node_nr;
4416 return be_duplicate_node(node);
4420 * Enters all transform functions into the generic pointer
4422 static void register_transformers(void)
4426 /* first clear the generic function pointer for all ops */
4427 clear_irp_opcodes_generic_func();
4429 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4430 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4468 /* transform ops from intrinsic lowering */
4480 GEN(ia32_l_LLtoFloat);
4481 GEN(ia32_l_FloattoLL);
4487 /* we should never see these nodes */
4502 /* handle generic backend nodes */
4511 op_Mulh = get_op_Mulh();
4520 * Pre-transform all unknown and noreg nodes.
4522 static void ia32_pretransform_node(void *arch_cg) {
4523 ia32_code_gen_t *cg = arch_cg;
4525 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4526 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4527 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4528 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4529 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4530 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4535 * Walker, checks if all ia32 nodes producing more than one result have their
4536 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4538 static void add_missing_keep_walker(ir_node *node, void *data)
4541 unsigned found_projs = 0;
4542 const ir_edge_t *edge;
4543 ir_mode *mode = get_irn_mode(node);
4548 if(!is_ia32_irn(node))
4551 n_outs = get_ia32_n_res(node);
4554 if(is_ia32_SwitchJmp(node))
4557 assert(n_outs < (int) sizeof(unsigned) * 8);
4558 foreach_out_edge(node, edge) {
4559 ir_node *proj = get_edge_src_irn(edge);
4560 int pn = get_Proj_proj(proj);
4562 if (get_irn_mode(proj) == mode_M)
4565 assert(pn < n_outs);
4566 found_projs |= 1 << pn;
4570 /* are keeps missing? */
4572 for(i = 0; i < n_outs; ++i) {
4575 const arch_register_req_t *req;
4576 const arch_register_class_t *cls;
4578 if(found_projs & (1 << i)) {
4582 req = get_ia32_out_req(node, i);
4587 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4591 block = get_nodes_block(node);
4592 in[0] = new_r_Proj(current_ir_graph, block, node,
4593 arch_register_class_mode(cls), i);
4594 if(last_keep != NULL) {
4595 be_Keep_add_node(last_keep, cls, in[0]);
4597 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4598 if(sched_is_scheduled(node)) {
4599 sched_add_after(node, last_keep);
4606 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4609 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4611 ir_graph *irg = be_get_birg_irg(cg->birg);
4612 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4615 /* do the transformation */
4616 void ia32_transform_graph(ia32_code_gen_t *cg) {
4618 ir_graph *irg = cg->irg;
4620 register_transformers();
4622 initial_fpcw = NULL;
4624 BE_TIMER_PUSH(t_heights);
4625 heights = heights_new(irg);
4626 BE_TIMER_POP(t_heights);
4627 ia32_calculate_non_address_mode_nodes(cg->birg);
4629 /* the transform phase is not safe for CSE (yet) because several nodes get
4630 * attributes set after their creation */
4631 cse_last = get_opt_cse();
4634 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4636 set_opt_cse(cse_last);
4638 ia32_free_non_address_mode_nodes();
4639 heights_free(heights);
4643 void ia32_init_transform(void)
4645 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");