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 {
534 ia32_op_type_t op_type;
538 unsigned commutative : 1;
539 unsigned ins_permuted : 1;
542 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
546 /* construct load address */
547 memset(addr, 0, sizeof(addr[0]));
548 ia32_create_address_mode(addr, ptr, /*force=*/0);
550 noreg_gp = ia32_new_NoReg_gp(env_cg);
551 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
552 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
553 addr->mem = be_transform_node(mem);
556 static void build_address(ia32_address_mode_t *am, ir_node *node)
558 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
559 ia32_address_t *addr = &am->addr;
565 if (is_Const(node)) {
566 ir_entity *entity = create_float_const_entity(node);
567 addr->base = noreg_gp;
568 addr->index = noreg_gp;
569 addr->mem = new_NoMem();
570 addr->symconst_ent = entity;
572 am->ls_mode = get_type_mode(get_entity_type(entity));
573 am->pinned = op_pin_state_floats;
577 load = get_Proj_pred(node);
578 ptr = get_Load_ptr(load);
579 mem = get_Load_mem(load);
580 new_mem = be_transform_node(mem);
581 am->pinned = get_irn_pinned(load);
582 am->ls_mode = get_Load_mode(load);
583 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
586 /* construct load address */
587 ia32_create_address_mode(addr, ptr, /*force=*/0);
589 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
590 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
594 static void set_address(ir_node *node, const ia32_address_t *addr)
596 set_ia32_am_scale(node, addr->scale);
597 set_ia32_am_sc(node, addr->symconst_ent);
598 set_ia32_am_offs_int(node, addr->offset);
599 if(addr->symconst_sign)
600 set_ia32_am_sc_sign(node);
602 set_ia32_use_frame(node);
603 set_ia32_frame_ent(node, addr->frame_entity);
607 * Apply attributes of a given address mode to a node.
609 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
611 set_address(node, &am->addr);
613 set_ia32_op_type(node, am->op_type);
614 set_ia32_ls_mode(node, am->ls_mode);
615 if (am->pinned == op_pin_state_pinned) {
616 /* beware: some nodes are already pinned and did not allow to change the state */
617 if (get_irn_pinned(node) != op_pin_state_pinned)
618 set_irn_pinned(node, op_pin_state_pinned);
621 set_ia32_commutative(node);
625 * Check, if a given node is a Down-Conv, ie. a integer Conv
626 * from a mode with a mode with more bits to a mode with lesser bits.
627 * Moreover, we return only true if the node has not more than 1 user.
629 * @param node the node
630 * @return non-zero if node is a Down-Conv
632 static int is_downconv(const ir_node *node)
640 /* we only want to skip the conv when we're the only user
641 * (not optimal but for now...)
643 if(get_irn_n_edges(node) > 1)
646 src_mode = get_irn_mode(get_Conv_op(node));
647 dest_mode = get_irn_mode(node);
648 return ia32_mode_needs_gp_reg(src_mode)
649 && ia32_mode_needs_gp_reg(dest_mode)
650 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
653 /* Skip all Down-Conv's on a given node and return the resulting node. */
654 ir_node *ia32_skip_downconv(ir_node *node) {
655 while (is_downconv(node))
656 node = get_Conv_op(node);
661 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
663 ir_mode *mode = get_irn_mode(node);
668 if(mode_is_signed(mode)) {
673 block = get_nodes_block(node);
674 dbgi = get_irn_dbg_info(node);
676 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
680 * matches operands of a node into ia32 addressing/operand modes. This covers
681 * usage of source address mode, immediates, operations with non 32-bit modes,
683 * The resulting data is filled into the @p am struct. block is the block
684 * of the node whose arguments are matched. op1, op2 are the first and second
685 * input that are matched (op1 may be NULL). other_op is another unrelated
686 * input that is not matched! but which is needed sometimes to check if AM
687 * for op1/op2 is legal.
688 * @p flags describes the supported modes of the operation in detail.
690 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
691 ir_node *op1, ir_node *op2, ir_node *other_op,
694 ia32_address_t *addr = &am->addr;
695 ir_mode *mode = get_irn_mode(op2);
696 int mode_bits = get_mode_size_bits(mode);
697 ir_node *noreg_gp, *new_op1, *new_op2;
699 unsigned commutative;
700 int use_am_and_immediates;
703 memset(am, 0, sizeof(am[0]));
705 commutative = (flags & match_commutative) != 0;
706 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
707 use_am = (flags & match_am) != 0;
708 use_immediate = (flags & match_immediate) != 0;
709 assert(!use_am_and_immediates || use_immediate);
712 assert(!commutative || op1 != NULL);
713 assert(use_am || !(flags & match_8bit_am));
714 assert(use_am || !(flags & match_16bit_am));
716 if (mode_bits == 8) {
717 if (!(flags & match_8bit_am))
719 /* we don't automatically add upconvs yet */
720 assert((flags & match_mode_neutral) || (flags & match_8bit));
721 } else if (mode_bits == 16) {
722 if (!(flags & match_16bit_am))
724 /* we don't automatically add upconvs yet */
725 assert((flags & match_mode_neutral) || (flags & match_16bit));
728 /* we can simply skip downconvs for mode neutral nodes: the upper bits
729 * can be random for these operations */
730 if (flags & match_mode_neutral) {
731 op2 = ia32_skip_downconv(op2);
733 op1 = ia32_skip_downconv(op1);
737 /* match immediates. firm nodes are normalized: constants are always on the
740 if (!(flags & match_try_am) && use_immediate) {
741 new_op2 = try_create_Immediate(op2, 0);
744 noreg_gp = ia32_new_NoReg_gp(env_cg);
745 if (new_op2 == NULL &&
746 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
747 build_address(am, op2);
748 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
749 if (mode_is_float(mode)) {
750 new_op2 = ia32_new_NoReg_vfp(env_cg);
754 am->op_type = ia32_AddrModeS;
755 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
757 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
759 build_address(am, op1);
761 if (mode_is_float(mode)) {
762 noreg = ia32_new_NoReg_vfp(env_cg);
767 if (new_op2 != NULL) {
770 new_op1 = be_transform_node(op2);
772 am->ins_permuted = 1;
774 am->op_type = ia32_AddrModeS;
776 if (flags & match_try_am) {
779 am->op_type = ia32_Normal;
783 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
785 new_op2 = be_transform_node(op2);
786 am->op_type = ia32_Normal;
787 am->ls_mode = get_irn_mode(op2);
788 if (flags & match_mode_neutral)
789 am->ls_mode = mode_Iu;
791 if (addr->base == NULL)
792 addr->base = noreg_gp;
793 if (addr->index == NULL)
794 addr->index = noreg_gp;
795 if (addr->mem == NULL)
796 addr->mem = new_NoMem();
798 am->new_op1 = new_op1;
799 am->new_op2 = new_op2;
800 am->commutative = commutative;
803 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
808 if (am->mem_proj == NULL)
811 /* we have to create a mode_T so the old MemProj can attach to us */
812 mode = get_irn_mode(node);
813 load = get_Proj_pred(am->mem_proj);
815 mark_irn_visited(load);
816 be_set_transformed_node(load, node);
818 if (mode != mode_T) {
819 set_irn_mode(node, mode_T);
820 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
827 * Construct a standard binary operation, set AM and immediate if required.
829 * @param node The original node for which the binop is created
830 * @param op1 The first operand
831 * @param op2 The second operand
832 * @param func The node constructor function
833 * @return The constructed ia32 node.
835 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
836 construct_binop_func *func, match_flags_t flags)
839 ir_node *block, *new_block, *new_node;
840 ia32_address_mode_t am;
841 ia32_address_t *addr = &am.addr;
843 block = get_nodes_block(node);
844 match_arguments(&am, block, op1, op2, NULL, flags);
846 dbgi = get_irn_dbg_info(node);
847 new_block = be_transform_node(block);
848 new_node = func(dbgi, current_ir_graph, new_block,
849 addr->base, addr->index, addr->mem,
850 am.new_op1, am.new_op2);
851 set_am_attributes(new_node, &am);
852 /* we can't use source address mode anymore when using immediates */
853 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
854 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
855 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
857 new_node = fix_mem_proj(new_node, &am);
864 n_ia32_l_binop_right,
865 n_ia32_l_binop_eflags
867 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
868 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
869 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
870 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
871 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
872 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
875 * Construct a binary operation which also consumes the eflags.
877 * @param node The node to transform
878 * @param func The node constructor function
879 * @param flags The match flags
880 * @return The constructor ia32 node
882 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
885 ir_node *src_block = get_nodes_block(node);
886 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
887 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
888 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
890 ir_node *block, *new_node, *new_eflags;
891 ia32_address_mode_t am;
892 ia32_address_t *addr = &am.addr;
894 match_arguments(&am, src_block, op1, op2, eflags, flags);
896 dbgi = get_irn_dbg_info(node);
897 block = be_transform_node(src_block);
898 new_eflags = be_transform_node(eflags);
899 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
900 addr->mem, am.new_op1, am.new_op2, new_eflags);
901 set_am_attributes(new_node, &am);
902 /* we can't use source address mode anymore when using immediates */
903 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
904 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
905 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
907 new_node = fix_mem_proj(new_node, &am);
912 static ir_node *get_fpcw(void)
915 if (initial_fpcw != NULL)
918 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
919 &ia32_fp_cw_regs[REG_FPCW]);
920 initial_fpcw = be_transform_node(fpcw);
926 * Construct a standard binary operation, set AM and immediate if required.
928 * @param op1 The first operand
929 * @param op2 The second operand
930 * @param func The node constructor function
931 * @return The constructed ia32 node.
933 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
934 construct_binop_float_func *func,
937 ir_mode *mode = get_irn_mode(node);
939 ir_node *block, *new_block, *new_node;
940 ia32_address_mode_t am;
941 ia32_address_t *addr = &am.addr;
943 /* cannot use address mode with long double on x87 */
944 if (get_mode_size_bits(mode) > 64)
947 block = get_nodes_block(node);
948 match_arguments(&am, block, op1, op2, NULL, flags);
950 dbgi = get_irn_dbg_info(node);
951 new_block = be_transform_node(block);
952 new_node = func(dbgi, current_ir_graph, new_block,
953 addr->base, addr->index, addr->mem,
954 am.new_op1, am.new_op2, get_fpcw());
955 set_am_attributes(new_node, &am);
957 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
959 new_node = fix_mem_proj(new_node, &am);
965 * Construct a shift/rotate binary operation, sets AM and immediate if required.
967 * @param op1 The first operand
968 * @param op2 The second operand
969 * @param func The node constructor function
970 * @return The constructed ia32 node.
972 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
973 construct_shift_func *func,
977 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
979 assert(! mode_is_float(get_irn_mode(node)));
980 assert(flags & match_immediate);
981 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
983 if (flags & match_mode_neutral) {
984 op1 = ia32_skip_downconv(op1);
985 new_op1 = be_transform_node(op1);
986 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
987 new_op1 = create_upconv(op1, node);
989 new_op1 = be_transform_node(op1);
992 /* the shift amount can be any mode that is bigger than 5 bits, since all
993 * other bits are ignored anyway */
994 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
995 ir_node *const op = get_Conv_op(op2);
996 if (mode_is_float(get_irn_mode(op)))
999 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1001 new_op2 = create_immediate_or_transform(op2, 0);
1003 dbgi = get_irn_dbg_info(node);
1004 block = get_nodes_block(node);
1005 new_block = be_transform_node(block);
1006 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1007 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1009 /* lowered shift instruction may have a dependency operand, handle it here */
1010 if (get_irn_arity(node) == 3) {
1011 /* we have a dependency */
1012 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1013 add_irn_dep(new_node, new_dep);
1021 * Construct a standard unary operation, set AM and immediate if required.
1023 * @param op The operand
1024 * @param func The node constructor function
1025 * @return The constructed ia32 node.
1027 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1028 match_flags_t flags)
1031 ir_node *block, *new_block, *new_op, *new_node;
1033 assert(flags == 0 || flags == match_mode_neutral);
1034 if (flags & match_mode_neutral) {
1035 op = ia32_skip_downconv(op);
1038 new_op = be_transform_node(op);
1039 dbgi = get_irn_dbg_info(node);
1040 block = get_nodes_block(node);
1041 new_block = be_transform_node(block);
1042 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1044 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1049 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1050 ia32_address_t *addr)
1052 ir_node *base, *index, *res;
1056 base = ia32_new_NoReg_gp(env_cg);
1058 base = be_transform_node(base);
1061 index = addr->index;
1062 if (index == NULL) {
1063 index = ia32_new_NoReg_gp(env_cg);
1065 index = be_transform_node(index);
1068 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1069 set_address(res, addr);
1075 * Returns non-zero if a given address mode has a symbolic or
1076 * numerical offset != 0.
1078 static int am_has_immediates(const ia32_address_t *addr)
1080 return addr->offset != 0 || addr->symconst_ent != NULL
1081 || addr->frame_entity || addr->use_frame;
1085 * Creates an ia32 Add.
1087 * @return the created ia32 Add node
1089 static ir_node *gen_Add(ir_node *node) {
1090 ir_mode *mode = get_irn_mode(node);
1091 ir_node *op1 = get_Add_left(node);
1092 ir_node *op2 = get_Add_right(node);
1094 ir_node *block, *new_block, *new_node, *add_immediate_op;
1095 ia32_address_t addr;
1096 ia32_address_mode_t am;
1098 if (mode_is_float(mode)) {
1099 if (ia32_cg_config.use_sse2)
1100 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1101 match_commutative | match_am);
1103 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1104 match_commutative | match_am);
1107 ia32_mark_non_am(node);
1109 op2 = ia32_skip_downconv(op2);
1110 op1 = ia32_skip_downconv(op1);
1114 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1115 * 1. Add with immediate -> Lea
1116 * 2. Add with possible source address mode -> Add
1117 * 3. Otherwise -> Lea
1119 memset(&addr, 0, sizeof(addr));
1120 ia32_create_address_mode(&addr, node, /*force=*/1);
1121 add_immediate_op = NULL;
1123 dbgi = get_irn_dbg_info(node);
1124 block = get_nodes_block(node);
1125 new_block = be_transform_node(block);
1128 if(addr.base == NULL && addr.index == NULL) {
1129 ir_graph *irg = current_ir_graph;
1130 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1131 addr.symconst_sign, addr.offset);
1132 add_irn_dep(new_node, get_irg_frame(irg));
1133 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1136 /* add with immediate? */
1137 if(addr.index == NULL) {
1138 add_immediate_op = addr.base;
1139 } else if(addr.base == NULL && addr.scale == 0) {
1140 add_immediate_op = addr.index;
1143 if(add_immediate_op != NULL) {
1144 if(!am_has_immediates(&addr)) {
1145 #ifdef DEBUG_libfirm
1146 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1149 return be_transform_node(add_immediate_op);
1152 new_node = create_lea_from_address(dbgi, new_block, &addr);
1153 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1157 /* test if we can use source address mode */
1158 match_arguments(&am, block, op1, op2, NULL, match_commutative
1159 | match_mode_neutral | match_am | match_immediate | match_try_am);
1161 /* construct an Add with source address mode */
1162 if (am.op_type == ia32_AddrModeS) {
1163 ir_graph *irg = current_ir_graph;
1164 ia32_address_t *am_addr = &am.addr;
1165 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1166 am_addr->index, am_addr->mem, am.new_op1,
1168 set_am_attributes(new_node, &am);
1169 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1171 new_node = fix_mem_proj(new_node, &am);
1176 /* otherwise construct a lea */
1177 new_node = create_lea_from_address(dbgi, new_block, &addr);
1178 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1183 * Creates an ia32 Mul.
1185 * @return the created ia32 Mul node
1187 static ir_node *gen_Mul(ir_node *node) {
1188 ir_node *op1 = get_Mul_left(node);
1189 ir_node *op2 = get_Mul_right(node);
1190 ir_mode *mode = get_irn_mode(node);
1192 if (mode_is_float(mode)) {
1193 if (ia32_cg_config.use_sse2)
1194 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1195 match_commutative | match_am);
1197 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1198 match_commutative | match_am);
1200 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1201 match_commutative | match_am | match_mode_neutral |
1202 match_immediate | match_am_and_immediates);
1206 * Creates an ia32 Mulh.
1207 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1208 * this result while Mul returns the lower 32 bit.
1210 * @return the created ia32 Mulh node
1212 static ir_node *gen_Mulh(ir_node *node)
1214 ir_node *block = get_nodes_block(node);
1215 ir_node *new_block = be_transform_node(block);
1216 ir_graph *irg = current_ir_graph;
1217 dbg_info *dbgi = get_irn_dbg_info(node);
1218 ir_mode *mode = get_irn_mode(node);
1219 ir_node *op1 = get_Mulh_left(node);
1220 ir_node *op2 = get_Mulh_right(node);
1221 ir_node *proj_res_high;
1223 ia32_address_mode_t am;
1224 ia32_address_t *addr = &am.addr;
1226 assert(!mode_is_float(mode) && "Mulh with float not supported");
1227 assert(get_mode_size_bits(mode) == 32);
1229 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1231 if (mode_is_signed(mode)) {
1232 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1233 addr->index, addr->mem, am.new_op1,
1236 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1237 addr->index, addr->mem, am.new_op1,
1241 set_am_attributes(new_node, &am);
1242 /* we can't use source address mode anymore when using immediates */
1243 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1244 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1245 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1247 assert(get_irn_mode(new_node) == mode_T);
1249 fix_mem_proj(new_node, &am);
1251 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1252 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1253 mode_Iu, pn_ia32_IMul1OP_res_high);
1255 return proj_res_high;
1261 * Creates an ia32 And.
1263 * @return The created ia32 And node
1265 static ir_node *gen_And(ir_node *node) {
1266 ir_node *op1 = get_And_left(node);
1267 ir_node *op2 = get_And_right(node);
1268 assert(! mode_is_float(get_irn_mode(node)));
1270 /* is it a zero extension? */
1271 if (is_Const(op2)) {
1272 tarval *tv = get_Const_tarval(op2);
1273 long v = get_tarval_long(tv);
1275 if (v == 0xFF || v == 0xFFFF) {
1276 dbg_info *dbgi = get_irn_dbg_info(node);
1277 ir_node *block = get_nodes_block(node);
1284 assert(v == 0xFFFF);
1287 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1292 return gen_binop(node, op1, op2, new_rd_ia32_And,
1293 match_commutative | match_mode_neutral | match_am
1300 * Creates an ia32 Or.
1302 * @return The created ia32 Or node
1304 static ir_node *gen_Or(ir_node *node) {
1305 ir_node *op1 = get_Or_left(node);
1306 ir_node *op2 = get_Or_right(node);
1308 assert (! mode_is_float(get_irn_mode(node)));
1309 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1310 | match_mode_neutral | match_am | match_immediate);
1316 * Creates an ia32 Eor.
1318 * @return The created ia32 Eor node
1320 static ir_node *gen_Eor(ir_node *node) {
1321 ir_node *op1 = get_Eor_left(node);
1322 ir_node *op2 = get_Eor_right(node);
1324 assert(! mode_is_float(get_irn_mode(node)));
1325 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1326 | match_mode_neutral | match_am | match_immediate);
1331 * Creates an ia32 Sub.
1333 * @return The created ia32 Sub node
1335 static ir_node *gen_Sub(ir_node *node) {
1336 ir_node *op1 = get_Sub_left(node);
1337 ir_node *op2 = get_Sub_right(node);
1338 ir_mode *mode = get_irn_mode(node);
1340 if (mode_is_float(mode)) {
1341 if (ia32_cg_config.use_sse2)
1342 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1344 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1348 if (is_Const(op2)) {
1349 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1353 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1354 | match_am | match_immediate);
1357 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1358 ir_node *const src_val,
1359 ir_node *const src_mem,
1360 ir_node *const am_mem)
1362 if (is_NoMem(am_mem)) {
1363 return be_transform_node(src_mem);
1364 } else if (is_Proj(src_val) &&
1366 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1367 /* avoid memory loop */
1369 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1370 ir_node *const ptr_pred = get_Proj_pred(src_val);
1371 int const arity = get_Sync_n_preds(src_mem);
1376 NEW_ARR_A(ir_node*, ins, arity + 1);
1378 for (i = arity - 1; i >= 0; --i) {
1379 ir_node *const pred = get_Sync_pred(src_mem, i);
1381 /* avoid memory loop */
1382 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1385 ins[n++] = be_transform_node(pred);
1390 return new_r_Sync(irg, block, n, ins);
1394 ins[0] = be_transform_node(src_mem);
1396 return new_r_Sync(irg, block, 2, ins);
1401 * Generates an ia32 DivMod with additional infrastructure for the
1402 * register allocator if needed.
1404 static ir_node *create_Div(ir_node *node)
1406 ir_graph *irg = current_ir_graph;
1407 dbg_info *dbgi = get_irn_dbg_info(node);
1408 ir_node *block = get_nodes_block(node);
1409 ir_node *new_block = be_transform_node(block);
1416 ir_node *sign_extension;
1417 ia32_address_mode_t am;
1418 ia32_address_t *addr = &am.addr;
1420 /* the upper bits have random contents for smaller modes */
1421 switch (get_irn_opcode(node)) {
1423 op1 = get_Div_left(node);
1424 op2 = get_Div_right(node);
1425 mem = get_Div_mem(node);
1426 mode = get_Div_resmode(node);
1429 op1 = get_Mod_left(node);
1430 op2 = get_Mod_right(node);
1431 mem = get_Mod_mem(node);
1432 mode = get_Mod_resmode(node);
1435 op1 = get_DivMod_left(node);
1436 op2 = get_DivMod_right(node);
1437 mem = get_DivMod_mem(node);
1438 mode = get_DivMod_resmode(node);
1441 panic("invalid divmod node %+F", node);
1444 match_arguments(&am, block, op1, op2, NULL, match_am);
1446 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1447 is the memory of the consumed address. We can have only the second op as address
1448 in Div nodes, so check only op2. */
1449 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1451 if (mode_is_signed(mode)) {
1452 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1453 add_irn_dep(produceval, get_irg_frame(irg));
1454 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1457 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1458 addr->index, new_mem, am.new_op2,
1459 am.new_op1, sign_extension);
1461 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1462 add_irn_dep(sign_extension, get_irg_frame(irg));
1464 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1465 addr->index, new_mem, am.new_op2,
1466 am.new_op1, sign_extension);
1469 set_irn_pinned(new_node, get_irn_pinned(node));
1471 set_am_attributes(new_node, &am);
1472 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1474 new_node = fix_mem_proj(new_node, &am);
1480 static ir_node *gen_Mod(ir_node *node) {
1481 return create_Div(node);
1484 static ir_node *gen_Div(ir_node *node) {
1485 return create_Div(node);
1488 static ir_node *gen_DivMod(ir_node *node) {
1489 return create_Div(node);
1495 * Creates an ia32 floating Div.
1497 * @return The created ia32 xDiv node
1499 static ir_node *gen_Quot(ir_node *node)
1501 ir_node *op1 = get_Quot_left(node);
1502 ir_node *op2 = get_Quot_right(node);
1504 if (ia32_cg_config.use_sse2) {
1505 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1507 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1513 * Creates an ia32 Shl.
1515 * @return The created ia32 Shl node
1517 static ir_node *gen_Shl(ir_node *node) {
1518 ir_node *left = get_Shl_left(node);
1519 ir_node *right = get_Shl_right(node);
1521 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1522 match_mode_neutral | match_immediate);
1526 * Creates an ia32 Shr.
1528 * @return The created ia32 Shr node
1530 static ir_node *gen_Shr(ir_node *node) {
1531 ir_node *left = get_Shr_left(node);
1532 ir_node *right = get_Shr_right(node);
1534 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1540 * Creates an ia32 Sar.
1542 * @return The created ia32 Shrs node
1544 static ir_node *gen_Shrs(ir_node *node) {
1545 ir_node *left = get_Shrs_left(node);
1546 ir_node *right = get_Shrs_right(node);
1547 ir_mode *mode = get_irn_mode(node);
1549 if(is_Const(right) && mode == mode_Is) {
1550 tarval *tv = get_Const_tarval(right);
1551 long val = get_tarval_long(tv);
1553 /* this is a sign extension */
1554 ir_graph *irg = current_ir_graph;
1555 dbg_info *dbgi = get_irn_dbg_info(node);
1556 ir_node *block = be_transform_node(get_nodes_block(node));
1558 ir_node *new_op = be_transform_node(op);
1559 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1560 add_irn_dep(pval, get_irg_frame(irg));
1562 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1566 /* 8 or 16 bit sign extension? */
1567 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1568 ir_node *shl_left = get_Shl_left(left);
1569 ir_node *shl_right = get_Shl_right(left);
1570 if(is_Const(shl_right)) {
1571 tarval *tv1 = get_Const_tarval(right);
1572 tarval *tv2 = get_Const_tarval(shl_right);
1573 if(tv1 == tv2 && tarval_is_long(tv1)) {
1574 long val = get_tarval_long(tv1);
1575 if(val == 16 || val == 24) {
1576 dbg_info *dbgi = get_irn_dbg_info(node);
1577 ir_node *block = get_nodes_block(node);
1587 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1596 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1602 * Creates an ia32 Rol.
1604 * @param op1 The first operator
1605 * @param op2 The second operator
1606 * @return The created ia32 RotL node
1608 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1609 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1615 * Creates an ia32 Ror.
1616 * NOTE: There is no RotR with immediate because this would always be a RotL
1617 * "imm-mode_size_bits" which can be pre-calculated.
1619 * @param op1 The first operator
1620 * @param op2 The second operator
1621 * @return The created ia32 RotR node
1623 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1624 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1630 * Creates an ia32 RotR or RotL (depending on the found pattern).
1632 * @return The created ia32 RotL or RotR node
1634 static ir_node *gen_Rotl(ir_node *node) {
1635 ir_node *rotate = NULL;
1636 ir_node *op1 = get_Rotl_left(node);
1637 ir_node *op2 = get_Rotl_right(node);
1639 /* Firm has only RotL, so we are looking for a right (op2)
1640 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1641 that means we can create a RotR instead of an Add and a RotL */
1645 ir_node *left = get_Add_left(add);
1646 ir_node *right = get_Add_right(add);
1647 if (is_Const(right)) {
1648 tarval *tv = get_Const_tarval(right);
1649 ir_mode *mode = get_irn_mode(node);
1650 long bits = get_mode_size_bits(mode);
1652 if (is_Minus(left) &&
1653 tarval_is_long(tv) &&
1654 get_tarval_long(tv) == bits &&
1657 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1658 rotate = gen_Ror(node, op1, get_Minus_op(left));
1663 if (rotate == NULL) {
1664 rotate = gen_Rol(node, op1, op2);
1673 * Transforms a Minus node.
1675 * @return The created ia32 Minus node
1677 static ir_node *gen_Minus(ir_node *node)
1679 ir_node *op = get_Minus_op(node);
1680 ir_node *block = be_transform_node(get_nodes_block(node));
1681 ir_graph *irg = current_ir_graph;
1682 dbg_info *dbgi = get_irn_dbg_info(node);
1683 ir_mode *mode = get_irn_mode(node);
1688 if (mode_is_float(mode)) {
1689 ir_node *new_op = be_transform_node(op);
1690 if (ia32_cg_config.use_sse2) {
1691 /* TODO: non-optimal... if we have many xXors, then we should
1692 * rather create a load for the const and use that instead of
1693 * several AM nodes... */
1694 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1695 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1696 ir_node *nomem = new_rd_NoMem(irg);
1698 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1699 nomem, new_op, noreg_xmm);
1701 size = get_mode_size_bits(mode);
1702 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1704 set_ia32_am_sc(new_node, ent);
1705 set_ia32_op_type(new_node, ia32_AddrModeS);
1706 set_ia32_ls_mode(new_node, mode);
1708 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1711 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1714 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1720 * Transforms a Not node.
1722 * @return The created ia32 Not node
1724 static ir_node *gen_Not(ir_node *node) {
1725 ir_node *op = get_Not_op(node);
1727 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1728 assert (! mode_is_float(get_irn_mode(node)));
1730 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1736 * Transforms an Abs node.
1738 * @return The created ia32 Abs node
1740 static ir_node *gen_Abs(ir_node *node)
1742 ir_node *block = get_nodes_block(node);
1743 ir_node *new_block = be_transform_node(block);
1744 ir_node *op = get_Abs_op(node);
1745 ir_graph *irg = current_ir_graph;
1746 dbg_info *dbgi = get_irn_dbg_info(node);
1747 ir_mode *mode = get_irn_mode(node);
1748 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1749 ir_node *nomem = new_NoMem();
1755 if (mode_is_float(mode)) {
1756 new_op = be_transform_node(op);
1758 if (ia32_cg_config.use_sse2) {
1759 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1760 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1761 nomem, new_op, noreg_fp);
1763 size = get_mode_size_bits(mode);
1764 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1766 set_ia32_am_sc(new_node, ent);
1768 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1770 set_ia32_op_type(new_node, ia32_AddrModeS);
1771 set_ia32_ls_mode(new_node, mode);
1773 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1774 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1777 ir_node *xor, *pval, *sign_extension;
1779 if (get_mode_size_bits(mode) == 32) {
1780 new_op = be_transform_node(op);
1782 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1785 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1786 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1789 add_irn_dep(pval, get_irg_frame(irg));
1790 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1792 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1793 nomem, new_op, sign_extension);
1794 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1796 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1797 nomem, xor, sign_extension);
1798 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1805 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1807 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1808 dbg_info *dbgi = get_irn_dbg_info(cmp);
1809 ir_node *block = get_nodes_block(cmp);
1810 ir_node *new_block = be_transform_node(block);
1811 ir_node *op1 = be_transform_node(x);
1812 ir_node *op2 = be_transform_node(n);
1814 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1818 * Transform a node returning a "flag" result.
1820 * @param node the node to transform
1821 * @param pnc_out the compare mode to use
1823 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1832 /* we have a Cmp as input */
1833 if (is_Proj(node)) {
1834 ir_node *pred = get_Proj_pred(node);
1836 pn_Cmp pnc = get_Proj_proj(node);
1837 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1838 ir_node *l = get_Cmp_left(pred);
1839 ir_node *r = get_Cmp_right(pred);
1841 ir_node *la = get_And_left(l);
1842 ir_node *ra = get_And_right(l);
1844 ir_node *c = get_Shl_left(la);
1845 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1846 /* (1 << n) & ra) */
1847 ir_node *n = get_Shl_right(la);
1848 flags = gen_bt(pred, ra, n);
1849 /* we must generate a Jc/Jnc jump */
1850 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1853 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1858 ir_node *c = get_Shl_left(ra);
1859 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1860 /* la & (1 << n)) */
1861 ir_node *n = get_Shl_right(ra);
1862 flags = gen_bt(pred, la, n);
1863 /* we must generate a Jc/Jnc jump */
1864 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1867 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1873 flags = be_transform_node(pred);
1879 /* a mode_b value, we have to compare it against 0 */
1880 dbgi = get_irn_dbg_info(node);
1881 new_block = be_transform_node(get_nodes_block(node));
1882 new_op = be_transform_node(node);
1883 noreg = ia32_new_NoReg_gp(env_cg);
1884 nomem = new_NoMem();
1885 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1886 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1887 *pnc_out = pn_Cmp_Lg;
1892 * Transforms a Load.
1894 * @return the created ia32 Load node
1896 static ir_node *gen_Load(ir_node *node) {
1897 ir_node *old_block = get_nodes_block(node);
1898 ir_node *block = be_transform_node(old_block);
1899 ir_node *ptr = get_Load_ptr(node);
1900 ir_node *mem = get_Load_mem(node);
1901 ir_node *new_mem = be_transform_node(mem);
1904 ir_graph *irg = current_ir_graph;
1905 dbg_info *dbgi = get_irn_dbg_info(node);
1906 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1907 ir_mode *mode = get_Load_mode(node);
1910 ia32_address_t addr;
1912 /* construct load address */
1913 memset(&addr, 0, sizeof(addr));
1914 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1921 base = be_transform_node(base);
1927 index = be_transform_node(index);
1930 if (mode_is_float(mode)) {
1931 if (ia32_cg_config.use_sse2) {
1932 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1934 res_mode = mode_xmm;
1936 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1938 res_mode = mode_vfp;
1941 assert(mode != mode_b);
1943 /* create a conv node with address mode for smaller modes */
1944 if(get_mode_size_bits(mode) < 32) {
1945 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1946 new_mem, noreg, mode);
1948 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1953 set_irn_pinned(new_node, get_irn_pinned(node));
1954 set_ia32_op_type(new_node, ia32_AddrModeS);
1955 set_ia32_ls_mode(new_node, mode);
1956 set_address(new_node, &addr);
1958 if(get_irn_pinned(node) == op_pin_state_floats) {
1959 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1962 /* make sure we are scheduled behind the initial IncSP/Barrier
1963 * to avoid spills being placed before it
1965 if (block == get_irg_start_block(irg)) {
1966 add_irn_dep(new_node, get_irg_frame(irg));
1969 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1974 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1975 ir_node *ptr, ir_node *other)
1982 /* we only use address mode if we're the only user of the load */
1983 if (get_irn_n_edges(node) > 1)
1986 load = get_Proj_pred(node);
1989 if (get_nodes_block(load) != block)
1992 /* store should have the same pointer as the load */
1993 if (get_Load_ptr(load) != ptr)
1996 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1997 if (other != NULL &&
1998 get_nodes_block(other) == block &&
1999 heights_reachable_in_block(heights, other, load)) {
2006 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
2007 ir_node *const pred = get_Sync_pred(mem, i);
2009 if (is_Proj(pred) && get_Proj_pred(pred) == load)
2012 if (get_nodes_block(pred) == block &&
2013 heights_reachable_in_block(heights, pred, load)) {
2018 /* Store should be attached to the load */
2019 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
2026 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
2028 mark_irn_visited(old_node);
2029 be_set_transformed_node(old_node, new_node);
2032 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2033 ir_node *mem, ir_node *ptr, ir_mode *mode,
2034 construct_binop_dest_func *func,
2035 construct_binop_dest_func *func8bit,
2036 match_flags_t flags)
2038 ir_node *src_block = get_nodes_block(node);
2040 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2041 ir_graph *irg = current_ir_graph;
2048 ia32_address_mode_t am;
2049 ia32_address_t *addr = &am.addr;
2050 memset(&am, 0, sizeof(am));
2052 assert(flags & match_dest_am);
2053 assert(flags & match_immediate); /* there is no destam node without... */
2054 commutative = (flags & match_commutative) != 0;
2056 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2057 build_address(&am, op1);
2058 new_op = create_immediate_or_transform(op2, 0);
2059 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2060 build_address(&am, op2);
2061 new_op = create_immediate_or_transform(op1, 0);
2066 if(addr->base == NULL)
2067 addr->base = noreg_gp;
2068 if(addr->index == NULL)
2069 addr->index = noreg_gp;
2070 if(addr->mem == NULL)
2071 addr->mem = new_NoMem();
2073 dbgi = get_irn_dbg_info(node);
2074 block = be_transform_node(src_block);
2075 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2077 if(get_mode_size_bits(mode) == 8) {
2078 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2081 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
2084 set_address(new_node, addr);
2085 set_ia32_op_type(new_node, ia32_AddrModeD);
2086 set_ia32_ls_mode(new_node, mode);
2087 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2089 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2090 mem_proj = be_transform_node(am.mem_proj);
2091 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2096 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2097 ir_node *ptr, ir_mode *mode,
2098 construct_unop_dest_func *func)
2100 ir_graph *irg = current_ir_graph;
2101 ir_node *src_block = get_nodes_block(node);
2107 ia32_address_mode_t am;
2108 ia32_address_t *addr = &am.addr;
2109 memset(&am, 0, sizeof(am));
2111 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2114 build_address(&am, op);
2116 dbgi = get_irn_dbg_info(node);
2117 block = be_transform_node(src_block);
2118 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2119 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2120 set_address(new_node, addr);
2121 set_ia32_op_type(new_node, ia32_AddrModeD);
2122 set_ia32_ls_mode(new_node, mode);
2123 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2125 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2126 mem_proj = be_transform_node(am.mem_proj);
2127 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2132 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2133 ir_mode *mode = get_irn_mode(node);
2134 ir_node *mux_true = get_Mux_true(node);
2135 ir_node *mux_false = get_Mux_false(node);
2146 ia32_address_t addr;
2148 if(get_mode_size_bits(mode) != 8)
2151 if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2153 } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2159 build_address_ptr(&addr, ptr, mem);
2161 irg = current_ir_graph;
2162 dbgi = get_irn_dbg_info(node);
2163 block = get_nodes_block(node);
2164 new_block = be_transform_node(block);
2165 cond = get_Mux_sel(node);
2166 flags = get_flags_node(cond, &pnc);
2167 new_mem = be_transform_node(mem);
2168 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2169 addr.index, addr.mem, flags, pnc, negated);
2170 set_address(new_node, &addr);
2171 set_ia32_op_type(new_node, ia32_AddrModeD);
2172 set_ia32_ls_mode(new_node, mode);
2173 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2178 static ir_node *try_create_dest_am(ir_node *node) {
2179 ir_node *val = get_Store_value(node);
2180 ir_node *mem = get_Store_mem(node);
2181 ir_node *ptr = get_Store_ptr(node);
2182 ir_mode *mode = get_irn_mode(val);
2183 unsigned bits = get_mode_size_bits(mode);
2188 /* handle only GP modes for now... */
2189 if(!ia32_mode_needs_gp_reg(mode))
2193 /* store must be the only user of the val node */
2194 if(get_irn_n_edges(val) > 1)
2196 /* skip pointless convs */
2198 ir_node *conv_op = get_Conv_op(val);
2199 ir_mode *pred_mode = get_irn_mode(conv_op);
2200 if (!ia32_mode_needs_gp_reg(pred_mode))
2202 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2210 /* value must be in the same block */
2211 if(get_nodes_block(node) != get_nodes_block(val))
2214 switch (get_irn_opcode(val)) {
2216 op1 = get_Add_left(val);
2217 op2 = get_Add_right(val);
2218 if(is_Const_1(op2)) {
2219 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2220 new_rd_ia32_IncMem);
2222 } else if(is_Const_Minus_1(op2)) {
2223 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2224 new_rd_ia32_DecMem);
2227 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2228 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2229 match_dest_am | match_commutative |
2233 op1 = get_Sub_left(val);
2234 op2 = get_Sub_right(val);
2235 if (is_Const(op2)) {
2236 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2238 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2239 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2240 match_dest_am | match_immediate |
2244 op1 = get_And_left(val);
2245 op2 = get_And_right(val);
2246 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2247 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2248 match_dest_am | match_commutative |
2252 op1 = get_Or_left(val);
2253 op2 = get_Or_right(val);
2254 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2255 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2256 match_dest_am | match_commutative |
2260 op1 = get_Eor_left(val);
2261 op2 = get_Eor_right(val);
2262 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2263 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2264 match_dest_am | match_commutative |
2268 op1 = get_Shl_left(val);
2269 op2 = get_Shl_right(val);
2270 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2271 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2272 match_dest_am | match_immediate);
2275 op1 = get_Shr_left(val);
2276 op2 = get_Shr_right(val);
2277 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2278 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2279 match_dest_am | match_immediate);
2282 op1 = get_Shrs_left(val);
2283 op2 = get_Shrs_right(val);
2284 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2285 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2286 match_dest_am | match_immediate);
2289 op1 = get_Rotl_left(val);
2290 op2 = get_Rotl_right(val);
2291 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2292 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2293 match_dest_am | match_immediate);
2295 /* TODO: match ROR patterns... */
2297 new_node = try_create_SetMem(val, ptr, mem);
2300 op1 = get_Minus_op(val);
2301 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2304 /* should be lowered already */
2305 assert(mode != mode_b);
2306 op1 = get_Not_op(val);
2307 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2313 if(new_node != NULL) {
2314 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2315 get_irn_pinned(node) == op_pin_state_pinned) {
2316 set_irn_pinned(new_node, op_pin_state_pinned);
2323 static int is_float_to_int32_conv(const ir_node *node)
2325 ir_mode *mode = get_irn_mode(node);
2329 if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode))
2331 /* don't report unsigned as conv to 32bit, because we really need to do
2332 * a vfist with 64bit signed in this case */
2333 if(!mode_is_signed(mode))
2338 conv_op = get_Conv_op(node);
2339 conv_mode = get_irn_mode(conv_op);
2341 if(!mode_is_float(conv_mode))
2348 * Transform a Store(floatConst).
2350 * @return the created ia32 Store node
2352 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2354 ir_mode *mode = get_irn_mode(cns);
2355 unsigned size = get_mode_size_bytes(mode);
2356 tarval *tv = get_Const_tarval(cns);
2357 ir_node *block = get_nodes_block(node);
2358 ir_node *new_block = be_transform_node(block);
2359 ir_node *ptr = get_Store_ptr(node);
2360 ir_node *mem = get_Store_mem(node);
2361 ir_graph *irg = current_ir_graph;
2362 dbg_info *dbgi = get_irn_dbg_info(node);
2366 ia32_address_t addr;
2368 assert(size % 4 == 0);
2371 build_address_ptr(&addr, ptr, mem);
2375 get_tarval_sub_bits(tv, ofs) |
2376 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2377 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2378 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2379 ir_node *imm = create_Immediate(NULL, 0, val);
2381 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2382 addr.index, addr.mem, imm);
2384 set_irn_pinned(new_node, get_irn_pinned(node));
2385 set_ia32_op_type(new_node, ia32_AddrModeD);
2386 set_ia32_ls_mode(new_node, mode_Iu);
2387 set_address(new_node, &addr);
2388 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2390 ins[i++] = new_node;
2395 } while (size != 0);
2397 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2401 * Generate a vfist or vfisttp instruction.
2403 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2404 ir_node *mem, ir_node *val, ir_node **fist)
2408 if (ia32_cg_config.use_fisttp) {
2409 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2410 if other users exists */
2411 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2412 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2413 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2414 be_new_Keep(reg_class, irg, block, 1, &value);
2416 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2419 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2422 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2428 * Transforms a normal Store.
2430 * @return the created ia32 Store node
2432 static ir_node *gen_normal_Store(ir_node *node)
2434 ir_node *val = get_Store_value(node);
2435 ir_mode *mode = get_irn_mode(val);
2436 ir_node *block = get_nodes_block(node);
2437 ir_node *new_block = be_transform_node(block);
2438 ir_node *ptr = get_Store_ptr(node);
2439 ir_node *mem = get_Store_mem(node);
2440 ir_graph *irg = current_ir_graph;
2441 dbg_info *dbgi = get_irn_dbg_info(node);
2442 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2443 ir_node *new_val, *new_node, *store;
2444 ia32_address_t addr;
2446 /* check for destination address mode */
2447 new_node = try_create_dest_am(node);
2448 if (new_node != NULL)
2451 /* construct store address */
2452 memset(&addr, 0, sizeof(addr));
2453 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2455 if (addr.base == NULL) {
2458 addr.base = be_transform_node(addr.base);
2461 if (addr.index == NULL) {
2464 addr.index = be_transform_node(addr.index);
2466 addr.mem = be_transform_node(mem);
2468 if (mode_is_float(mode)) {
2469 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2471 while (is_Conv(val) && mode == get_irn_mode(val)) {
2472 ir_node *op = get_Conv_op(val);
2473 if (!mode_is_float(get_irn_mode(op)))
2477 new_val = be_transform_node(val);
2478 if (ia32_cg_config.use_sse2) {
2479 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2480 addr.index, addr.mem, new_val);
2482 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2483 addr.index, addr.mem, new_val, mode);
2486 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2487 val = get_Conv_op(val);
2489 /* TODO: is this optimisation still necessary at all (middleend)? */
2490 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2491 while (is_Conv(val)) {
2492 ir_node *op = get_Conv_op(val);
2493 if (!mode_is_float(get_irn_mode(op)))
2495 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2499 new_val = be_transform_node(val);
2500 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2502 new_val = create_immediate_or_transform(val, 0);
2503 assert(mode != mode_b);
2505 if (get_mode_size_bits(mode) == 8) {
2506 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2507 addr.index, addr.mem, new_val);
2509 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2510 addr.index, addr.mem, new_val);
2515 set_irn_pinned(store, get_irn_pinned(node));
2516 set_ia32_op_type(store, ia32_AddrModeD);
2517 set_ia32_ls_mode(store, mode);
2519 set_address(store, &addr);
2520 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2526 * Transforms a Store.
2528 * @return the created ia32 Store node
2530 static ir_node *gen_Store(ir_node *node)
2532 ir_node *val = get_Store_value(node);
2533 ir_mode *mode = get_irn_mode(val);
2535 if (mode_is_float(mode) && is_Const(val)) {
2538 /* we are storing a floating point constant */
2539 if (ia32_cg_config.use_sse2) {
2540 transform = !is_simple_sse_Const(val);
2542 transform = !is_simple_x87_Const(val);
2545 return gen_float_const_Store(node, val);
2547 return gen_normal_Store(node);
2551 * Transforms a Switch.
2553 * @return the created ia32 SwitchJmp node
2555 static ir_node *create_Switch(ir_node *node)
2557 ir_graph *irg = current_ir_graph;
2558 dbg_info *dbgi = get_irn_dbg_info(node);
2559 ir_node *block = be_transform_node(get_nodes_block(node));
2560 ir_node *sel = get_Cond_selector(node);
2561 ir_node *new_sel = be_transform_node(sel);
2562 int switch_min = INT_MAX;
2563 int switch_max = INT_MIN;
2564 long default_pn = get_Cond_defaultProj(node);
2566 const ir_edge_t *edge;
2568 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2570 /* determine the smallest switch case value */
2571 foreach_out_edge(node, edge) {
2572 ir_node *proj = get_edge_src_irn(edge);
2573 long pn = get_Proj_proj(proj);
2574 if(pn == default_pn)
2583 if((unsigned) (switch_max - switch_min) > 256000) {
2584 panic("Size of switch %+F bigger than 256000", node);
2587 if (switch_min != 0) {
2588 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2590 /* if smallest switch case is not 0 we need an additional sub */
2591 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2592 add_ia32_am_offs_int(new_sel, -switch_min);
2593 set_ia32_op_type(new_sel, ia32_AddrModeS);
2595 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2598 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2599 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2605 * Transform a Cond node.
2607 static ir_node *gen_Cond(ir_node *node) {
2608 ir_node *block = get_nodes_block(node);
2609 ir_node *new_block = be_transform_node(block);
2610 ir_graph *irg = current_ir_graph;
2611 dbg_info *dbgi = get_irn_dbg_info(node);
2612 ir_node *sel = get_Cond_selector(node);
2613 ir_mode *sel_mode = get_irn_mode(sel);
2614 ir_node *flags = NULL;
2618 if (sel_mode != mode_b) {
2619 return create_Switch(node);
2622 /* we get flags from a Cmp */
2623 flags = get_flags_node(sel, &pnc);
2625 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2626 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2631 static ir_node *gen_be_Copy(ir_node *node)
2633 ir_node *new_node = be_duplicate_node(node);
2634 ir_mode *mode = get_irn_mode(new_node);
2636 if (ia32_mode_needs_gp_reg(mode)) {
2637 set_irn_mode(new_node, mode_Iu);
2643 static ir_node *create_Fucom(ir_node *node)
2645 ir_graph *irg = current_ir_graph;
2646 dbg_info *dbgi = get_irn_dbg_info(node);
2647 ir_node *block = get_nodes_block(node);
2648 ir_node *new_block = be_transform_node(block);
2649 ir_node *left = get_Cmp_left(node);
2650 ir_node *new_left = be_transform_node(left);
2651 ir_node *right = get_Cmp_right(node);
2655 if(ia32_cg_config.use_fucomi) {
2656 new_right = be_transform_node(right);
2657 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2659 set_ia32_commutative(new_node);
2660 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2662 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2663 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2666 new_right = be_transform_node(right);
2667 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2671 set_ia32_commutative(new_node);
2673 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2675 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2676 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2682 static ir_node *create_Ucomi(ir_node *node)
2684 ir_graph *irg = current_ir_graph;
2685 dbg_info *dbgi = get_irn_dbg_info(node);
2686 ir_node *src_block = get_nodes_block(node);
2687 ir_node *new_block = be_transform_node(src_block);
2688 ir_node *left = get_Cmp_left(node);
2689 ir_node *right = get_Cmp_right(node);
2691 ia32_address_mode_t am;
2692 ia32_address_t *addr = &am.addr;
2694 match_arguments(&am, src_block, left, right, NULL,
2695 match_commutative | match_am);
2697 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2698 addr->mem, am.new_op1, am.new_op2,
2700 set_am_attributes(new_node, &am);
2702 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2704 new_node = fix_mem_proj(new_node, &am);
2710 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2711 * to fold an and into a test node
2713 static int can_fold_test_and(ir_node *node)
2715 const ir_edge_t *edge;
2717 /** we can only have eq and lg projs */
2718 foreach_out_edge(node, edge) {
2719 ir_node *proj = get_edge_src_irn(edge);
2720 pn_Cmp pnc = get_Proj_proj(proj);
2721 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2729 * Generate code for a Cmp.
2731 static ir_node *gen_Cmp(ir_node *node)
2733 ir_graph *irg = current_ir_graph;
2734 dbg_info *dbgi = get_irn_dbg_info(node);
2735 ir_node *block = get_nodes_block(node);
2736 ir_node *new_block = be_transform_node(block);
2737 ir_node *left = get_Cmp_left(node);
2738 ir_node *right = get_Cmp_right(node);
2739 ir_mode *cmp_mode = get_irn_mode(left);
2741 ia32_address_mode_t am;
2742 ia32_address_t *addr = &am.addr;
2745 if(mode_is_float(cmp_mode)) {
2746 if (ia32_cg_config.use_sse2) {
2747 return create_Ucomi(node);
2749 return create_Fucom(node);
2753 assert(ia32_mode_needs_gp_reg(cmp_mode));
2755 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2756 cmp_unsigned = !mode_is_signed(cmp_mode);
2757 if (is_Const_0(right) &&
2759 get_irn_n_edges(left) == 1 &&
2760 can_fold_test_and(node)) {
2761 /* Test(and_left, and_right) */
2762 ir_node *and_left = get_And_left(left);
2763 ir_node *and_right = get_And_right(left);
2764 ir_mode *mode = get_irn_mode(and_left);
2766 match_arguments(&am, block, and_left, and_right, NULL,
2768 match_am | match_8bit_am | match_16bit_am |
2769 match_am_and_immediates | match_immediate |
2770 match_8bit | match_16bit);
2771 if (get_mode_size_bits(mode) == 8) {
2772 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2773 addr->index, addr->mem, am.new_op1,
2774 am.new_op2, am.ins_permuted,
2777 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2778 addr->index, addr->mem, am.new_op1,
2779 am.new_op2, am.ins_permuted, cmp_unsigned);
2782 /* Cmp(left, right) */
2783 match_arguments(&am, block, left, right, NULL,
2784 match_commutative | match_am | match_8bit_am |
2785 match_16bit_am | match_am_and_immediates |
2786 match_immediate | match_8bit | match_16bit);
2787 if (get_mode_size_bits(cmp_mode) == 8) {
2788 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2789 addr->index, addr->mem, am.new_op1,
2790 am.new_op2, am.ins_permuted,
2793 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2794 addr->index, addr->mem, am.new_op1,
2795 am.new_op2, am.ins_permuted, cmp_unsigned);
2798 set_am_attributes(new_node, &am);
2799 set_ia32_ls_mode(new_node, cmp_mode);
2801 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2803 new_node = fix_mem_proj(new_node, &am);
2808 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2811 ir_graph *irg = current_ir_graph;
2812 dbg_info *dbgi = get_irn_dbg_info(node);
2813 ir_node *block = get_nodes_block(node);
2814 ir_node *new_block = be_transform_node(block);
2815 ir_node *val_true = get_Mux_true(node);
2816 ir_node *val_false = get_Mux_false(node);
2818 match_flags_t match_flags;
2819 ia32_address_mode_t am;
2820 ia32_address_t *addr;
2822 assert(ia32_cg_config.use_cmov);
2823 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2827 match_flags = match_commutative | match_am | match_16bit_am |
2830 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2832 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2833 addr->mem, am.new_op1, am.new_op2, new_flags,
2834 am.ins_permuted, pnc);
2835 set_am_attributes(new_node, &am);
2837 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2839 new_node = fix_mem_proj(new_node, &am);
2845 * Creates a ia32 Setcc instruction.
2847 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2848 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2851 ir_graph *irg = current_ir_graph;
2852 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2853 ir_node *nomem = new_NoMem();
2854 ir_mode *mode = get_irn_mode(orig_node);
2857 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2858 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2860 /* we might need to conv the result up */
2861 if (get_mode_size_bits(mode) > 8) {
2862 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2863 nomem, new_node, mode_Bu);
2864 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2871 * Create instruction for an unsigned Difference or Zero.
2873 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2874 ir_graph *irg = current_ir_graph;
2875 ir_mode *mode = get_irn_mode(psi);
2876 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2879 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2880 match_mode_neutral | match_am | match_immediate | match_two_users);
2882 block = get_nodes_block(new_node);
2884 if (is_Proj(new_node)) {
2885 sub = get_Proj_pred(new_node);
2886 assert(is_ia32_Sub(sub));
2889 set_irn_mode(sub, mode_T);
2890 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2892 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2894 dbgi = get_irn_dbg_info(psi);
2895 noreg = ia32_new_NoReg_gp(env_cg);
2896 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2897 nomem = new_NoMem();
2898 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2900 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2901 set_ia32_commutative(new_node);
2906 * Transforms a Mux node into CMov.
2908 * @return The transformed node.
2910 static ir_node *gen_Mux(ir_node *node)
2912 dbg_info *dbgi = get_irn_dbg_info(node);
2913 ir_node *block = get_nodes_block(node);
2914 ir_node *new_block = be_transform_node(block);
2915 ir_node *mux_true = get_Mux_true(node);
2916 ir_node *mux_false = get_Mux_false(node);
2917 ir_node *cond = get_Mux_sel(node);
2918 ir_mode *mode = get_irn_mode(node);
2921 assert(get_irn_mode(cond) == mode_b);
2923 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2924 if (mode_is_float(mode)) {
2925 ir_node *cmp = get_Proj_pred(cond);
2926 ir_node *cmp_left = get_Cmp_left(cmp);
2927 ir_node *cmp_right = get_Cmp_right(cmp);
2928 pn_Cmp pnc = get_Proj_proj(cond);
2930 if (ia32_cg_config.use_sse2) {
2931 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2932 if (cmp_left == mux_true && cmp_right == mux_false) {
2933 /* Mux(a <= b, a, b) => MIN */
2934 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2935 match_commutative | match_am | match_two_users);
2936 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2937 /* Mux(a <= b, b, a) => MAX */
2938 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2939 match_commutative | match_am | match_two_users);
2941 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2942 if (cmp_left == mux_true && cmp_right == mux_false) {
2943 /* Mux(a >= b, a, b) => MAX */
2944 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2945 match_commutative | match_am | match_two_users);
2946 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2947 /* Mux(a >= b, b, a) => MIN */
2948 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2949 match_commutative | match_am | match_two_users);
2953 panic("cannot transform floating point Mux");
2959 assert(ia32_mode_needs_gp_reg(mode));
2961 if (is_Proj(cond)) {
2962 ir_node *cmp = get_Proj_pred(cond);
2964 ir_node *cmp_left = get_Cmp_left(cmp);
2965 ir_node *cmp_right = get_Cmp_right(cmp);
2966 pn_Cmp pnc = get_Proj_proj(cond);
2968 /* check for unsigned Doz first */
2969 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2970 is_Const_0(mux_false) && is_Sub(mux_true) &&
2971 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2972 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2973 return create_Doz(node, cmp_left, cmp_right);
2974 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2975 is_Const_0(mux_true) && is_Sub(mux_false) &&
2976 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2977 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2978 return create_Doz(node, cmp_left, cmp_right);
2983 flags = get_flags_node(cond, &pnc);
2985 if (is_Const(mux_true) && is_Const(mux_false)) {
2986 /* both are const, good */
2987 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2988 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2989 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2990 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2992 /* Not that simple. */
2997 new_node = create_CMov(node, cond, flags, pnc);
3005 * Create a conversion from x87 state register to general purpose.
3007 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3008 ir_node *block = be_transform_node(get_nodes_block(node));
3009 ir_node *op = get_Conv_op(node);
3010 ir_node *new_op = be_transform_node(op);
3011 ia32_code_gen_t *cg = env_cg;
3012 ir_graph *irg = current_ir_graph;
3013 dbg_info *dbgi = get_irn_dbg_info(node);
3014 ir_node *noreg = ia32_new_NoReg_gp(cg);
3015 ir_mode *mode = get_irn_mode(node);
3016 ir_node *fist, *load, *mem;
3018 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3019 set_irn_pinned(fist, op_pin_state_floats);
3020 set_ia32_use_frame(fist);
3021 set_ia32_op_type(fist, ia32_AddrModeD);
3023 assert(get_mode_size_bits(mode) <= 32);
3024 /* exception we can only store signed 32 bit integers, so for unsigned
3025 we store a 64bit (signed) integer and load the lower bits */
3026 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3027 set_ia32_ls_mode(fist, mode_Ls);
3029 set_ia32_ls_mode(fist, mode_Is);
3031 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3034 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3036 set_irn_pinned(load, op_pin_state_floats);
3037 set_ia32_use_frame(load);
3038 set_ia32_op_type(load, ia32_AddrModeS);
3039 set_ia32_ls_mode(load, mode_Is);
3040 if(get_ia32_ls_mode(fist) == mode_Ls) {
3041 ia32_attr_t *attr = get_ia32_attr(load);
3042 attr->data.need_64bit_stackent = 1;
3044 ia32_attr_t *attr = get_ia32_attr(load);
3045 attr->data.need_32bit_stackent = 1;
3047 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3049 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3053 * Creates a x87 strict Conv by placing a Store and a Load
3055 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3057 ir_node *block = get_nodes_block(node);
3058 ir_graph *irg = current_ir_graph;
3059 dbg_info *dbgi = get_irn_dbg_info(node);
3060 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3061 ir_node *nomem = new_NoMem();
3062 ir_node *frame = get_irg_frame(irg);
3063 ir_node *store, *load;
3066 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3068 set_ia32_use_frame(store);
3069 set_ia32_op_type(store, ia32_AddrModeD);
3070 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3072 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3074 set_ia32_use_frame(load);
3075 set_ia32_op_type(load, ia32_AddrModeS);
3076 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3078 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3083 * Create a conversion from general purpose to x87 register
3085 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3086 ir_node *src_block = get_nodes_block(node);
3087 ir_node *block = be_transform_node(src_block);
3088 ir_graph *irg = current_ir_graph;
3089 dbg_info *dbgi = get_irn_dbg_info(node);
3090 ir_node *op = get_Conv_op(node);
3091 ir_node *new_op = NULL;
3095 ir_mode *store_mode;
3101 /* fild can use source AM if the operand is a signed 32bit integer */
3102 if (src_mode == mode_Is) {
3103 ia32_address_mode_t am;
3105 match_arguments(&am, src_block, NULL, op, NULL,
3106 match_am | match_try_am);
3107 if (am.op_type == ia32_AddrModeS) {
3108 ia32_address_t *addr = &am.addr;
3110 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3111 addr->index, addr->mem);
3112 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3115 set_am_attributes(fild, &am);
3116 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3118 fix_mem_proj(fild, &am);
3123 if(new_op == NULL) {
3124 new_op = be_transform_node(op);
3127 noreg = ia32_new_NoReg_gp(env_cg);
3128 nomem = new_NoMem();
3129 mode = get_irn_mode(op);
3131 /* first convert to 32 bit signed if necessary */
3132 src_bits = get_mode_size_bits(src_mode);
3133 if (src_bits == 8) {
3134 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3136 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3138 } else if (src_bits < 32) {
3139 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3141 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3145 assert(get_mode_size_bits(mode) == 32);
3148 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3151 set_ia32_use_frame(store);
3152 set_ia32_op_type(store, ia32_AddrModeD);
3153 set_ia32_ls_mode(store, mode_Iu);
3155 /* exception for 32bit unsigned, do a 64bit spill+load */
3156 if(!mode_is_signed(mode)) {
3159 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3161 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3162 get_irg_frame(irg), noreg, nomem,
3165 set_ia32_use_frame(zero_store);
3166 set_ia32_op_type(zero_store, ia32_AddrModeD);
3167 add_ia32_am_offs_int(zero_store, 4);
3168 set_ia32_ls_mode(zero_store, mode_Iu);
3173 store = new_rd_Sync(dbgi, irg, block, 2, in);
3174 store_mode = mode_Ls;
3176 store_mode = mode_Is;
3180 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3182 set_ia32_use_frame(fild);
3183 set_ia32_op_type(fild, ia32_AddrModeS);
3184 set_ia32_ls_mode(fild, store_mode);
3186 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3192 * Create a conversion from one integer mode into another one
3194 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3195 dbg_info *dbgi, ir_node *block, ir_node *op,
3198 ir_graph *irg = current_ir_graph;
3199 int src_bits = get_mode_size_bits(src_mode);
3200 int tgt_bits = get_mode_size_bits(tgt_mode);
3201 ir_node *new_block = be_transform_node(block);
3203 ir_mode *smaller_mode;
3205 ia32_address_mode_t am;
3206 ia32_address_t *addr = &am.addr;
3209 if (src_bits < tgt_bits) {
3210 smaller_mode = src_mode;
3211 smaller_bits = src_bits;
3213 smaller_mode = tgt_mode;
3214 smaller_bits = tgt_bits;
3217 #ifdef DEBUG_libfirm
3219 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3224 match_arguments(&am, block, NULL, op, NULL,
3225 match_8bit | match_16bit |
3226 match_am | match_8bit_am | match_16bit_am);
3227 if (smaller_bits == 8) {
3228 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3229 addr->index, addr->mem, am.new_op2,
3232 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3233 addr->index, addr->mem, am.new_op2,
3236 set_am_attributes(new_node, &am);
3237 /* match_arguments assume that out-mode = in-mode, this isn't true here
3239 set_ia32_ls_mode(new_node, smaller_mode);
3240 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3241 new_node = fix_mem_proj(new_node, &am);
3246 * Transforms a Conv node.
3248 * @return The created ia32 Conv node
3250 static ir_node *gen_Conv(ir_node *node) {
3251 ir_node *block = get_nodes_block(node);
3252 ir_node *new_block = be_transform_node(block);
3253 ir_node *op = get_Conv_op(node);
3254 ir_node *new_op = NULL;
3255 ir_graph *irg = current_ir_graph;
3256 dbg_info *dbgi = get_irn_dbg_info(node);
3257 ir_mode *src_mode = get_irn_mode(op);
3258 ir_mode *tgt_mode = get_irn_mode(node);
3259 int src_bits = get_mode_size_bits(src_mode);
3260 int tgt_bits = get_mode_size_bits(tgt_mode);
3261 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3262 ir_node *nomem = new_rd_NoMem(irg);
3263 ir_node *res = NULL;
3265 if (src_mode == mode_b) {
3266 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3267 /* nothing to do, we already model bools as 0/1 ints */
3268 return be_transform_node(op);
3271 if (src_mode == tgt_mode) {
3272 if (get_Conv_strict(node)) {
3273 if (ia32_cg_config.use_sse2) {
3274 /* when we are in SSE mode, we can kill all strict no-op conversion */
3275 return be_transform_node(op);
3278 /* this should be optimized already, but who knows... */
3279 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3280 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3281 return be_transform_node(op);
3285 if (mode_is_float(src_mode)) {
3286 new_op = be_transform_node(op);
3287 /* we convert from float ... */
3288 if (mode_is_float(tgt_mode)) {
3289 if(src_mode == mode_E && tgt_mode == mode_D
3290 && !get_Conv_strict(node)) {
3291 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3296 if (ia32_cg_config.use_sse2) {
3297 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3298 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3300 set_ia32_ls_mode(res, tgt_mode);
3302 if(get_Conv_strict(node)) {
3303 res = gen_x87_strict_conv(tgt_mode, new_op);
3304 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3307 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3312 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3313 if (ia32_cg_config.use_sse2) {
3314 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3316 set_ia32_ls_mode(res, src_mode);
3318 return gen_x87_fp_to_gp(node);
3322 /* we convert from int ... */
3323 if (mode_is_float(tgt_mode)) {
3325 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3326 if (ia32_cg_config.use_sse2) {
3327 new_op = be_transform_node(op);
3328 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3330 set_ia32_ls_mode(res, tgt_mode);
3332 res = gen_x87_gp_to_fp(node, src_mode);
3333 if(get_Conv_strict(node)) {
3334 /* The strict-Conv is only necessary, if the int mode has more bits
3335 * than the float mantissa */
3336 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3337 size_t float_mantissa;
3338 /* FIXME There is no way to get the mantissa size of a mode */
3339 switch (get_mode_size_bits(tgt_mode)) {
3340 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3341 case 64: float_mantissa = 52 + 1; break;
3343 case 96: float_mantissa = 64; break;
3344 default: float_mantissa = 0; break;
3346 if (float_mantissa < int_mantissa) {
3347 res = gen_x87_strict_conv(tgt_mode, res);
3348 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3353 } else if(tgt_mode == mode_b) {
3354 /* mode_b lowering already took care that we only have 0/1 values */
3355 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3356 src_mode, tgt_mode));
3357 return be_transform_node(op);
3360 if (src_bits == tgt_bits) {
3361 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3362 src_mode, tgt_mode));
3363 return be_transform_node(op);
3366 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3374 static ir_node *create_immediate_or_transform(ir_node *node,
3375 char immediate_constraint_type)
3377 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3378 if (new_node == NULL) {
3379 new_node = be_transform_node(node);
3385 * Transforms a FrameAddr into an ia32 Add.
3387 static ir_node *gen_be_FrameAddr(ir_node *node) {
3388 ir_node *block = be_transform_node(get_nodes_block(node));
3389 ir_node *op = be_get_FrameAddr_frame(node);
3390 ir_node *new_op = be_transform_node(op);
3391 ir_graph *irg = current_ir_graph;
3392 dbg_info *dbgi = get_irn_dbg_info(node);
3393 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3396 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3397 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3398 set_ia32_use_frame(new_node);
3400 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3406 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3408 static ir_node *gen_be_Return(ir_node *node) {
3409 ir_graph *irg = current_ir_graph;
3410 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3411 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3412 ir_entity *ent = get_irg_entity(irg);
3413 ir_type *tp = get_entity_type(ent);
3418 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3419 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3422 int pn_ret_val, pn_ret_mem, arity, i;
3424 assert(ret_val != NULL);
3425 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3426 return be_duplicate_node(node);
3429 res_type = get_method_res_type(tp, 0);
3431 if (! is_Primitive_type(res_type)) {
3432 return be_duplicate_node(node);
3435 mode = get_type_mode(res_type);
3436 if (! mode_is_float(mode)) {
3437 return be_duplicate_node(node);
3440 assert(get_method_n_ress(tp) == 1);
3442 pn_ret_val = get_Proj_proj(ret_val);
3443 pn_ret_mem = get_Proj_proj(ret_mem);
3445 /* get the Barrier */
3446 barrier = get_Proj_pred(ret_val);
3448 /* get result input of the Barrier */
3449 ret_val = get_irn_n(barrier, pn_ret_val);
3450 new_ret_val = be_transform_node(ret_val);
3452 /* get memory input of the Barrier */
3453 ret_mem = get_irn_n(barrier, pn_ret_mem);
3454 new_ret_mem = be_transform_node(ret_mem);
3456 frame = get_irg_frame(irg);
3458 dbgi = get_irn_dbg_info(barrier);
3459 block = be_transform_node(get_nodes_block(barrier));
3461 noreg = ia32_new_NoReg_gp(env_cg);
3463 /* store xmm0 onto stack */
3464 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3465 new_ret_mem, new_ret_val);
3466 set_ia32_ls_mode(sse_store, mode);
3467 set_ia32_op_type(sse_store, ia32_AddrModeD);
3468 set_ia32_use_frame(sse_store);
3470 /* load into x87 register */
3471 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3472 set_ia32_op_type(fld, ia32_AddrModeS);
3473 set_ia32_use_frame(fld);
3475 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3476 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3478 /* create a new barrier */
3479 arity = get_irn_arity(barrier);
3480 in = alloca(arity * sizeof(in[0]));
3481 for (i = 0; i < arity; ++i) {
3484 if (i == pn_ret_val) {
3486 } else if (i == pn_ret_mem) {
3489 ir_node *in = get_irn_n(barrier, i);
3490 new_in = be_transform_node(in);
3495 new_barrier = new_ir_node(dbgi, irg, block,
3496 get_irn_op(barrier), get_irn_mode(barrier),
3498 copy_node_attr(barrier, new_barrier);
3499 be_duplicate_deps(barrier, new_barrier);
3500 be_set_transformed_node(barrier, new_barrier);
3501 mark_irn_visited(barrier);
3503 /* transform normally */
3504 return be_duplicate_node(node);
3508 * Transform a be_AddSP into an ia32_SubSP.
3510 static ir_node *gen_be_AddSP(ir_node *node)
3512 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3513 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3515 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
3519 * Transform a be_SubSP into an ia32_AddSP
3521 static ir_node *gen_be_SubSP(ir_node *node)
3523 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3524 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3526 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
3530 * Change some phi modes
3532 static ir_node *gen_Phi(ir_node *node) {
3533 ir_node *block = be_transform_node(get_nodes_block(node));
3534 ir_graph *irg = current_ir_graph;
3535 dbg_info *dbgi = get_irn_dbg_info(node);
3536 ir_mode *mode = get_irn_mode(node);
3539 if(ia32_mode_needs_gp_reg(mode)) {
3540 /* we shouldn't have any 64bit stuff around anymore */
3541 assert(get_mode_size_bits(mode) <= 32);
3542 /* all integer operations are on 32bit registers now */
3544 } else if(mode_is_float(mode)) {
3545 if (ia32_cg_config.use_sse2) {
3552 /* phi nodes allow loops, so we use the old arguments for now
3553 * and fix this later */
3554 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3555 get_irn_in(node) + 1);
3556 copy_node_attr(node, phi);
3557 be_duplicate_deps(node, phi);
3559 be_set_transformed_node(node, phi);
3560 be_enqueue_preds(node);
3568 static ir_node *gen_IJmp(ir_node *node)
3570 ir_node *block = get_nodes_block(node);
3571 ir_node *new_block = be_transform_node(block);
3572 dbg_info *dbgi = get_irn_dbg_info(node);
3573 ir_node *op = get_IJmp_target(node);
3575 ia32_address_mode_t am;
3576 ia32_address_t *addr = &am.addr;
3578 assert(get_irn_mode(op) == mode_P);
3580 match_arguments(&am, block, NULL, op, NULL,
3581 match_am | match_8bit_am | match_16bit_am |
3582 match_immediate | match_8bit | match_16bit);
3584 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3585 addr->base, addr->index, addr->mem,
3587 set_am_attributes(new_node, &am);
3588 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3590 new_node = fix_mem_proj(new_node, &am);
3596 * Transform a Bound node.
3598 static ir_node *gen_Bound(ir_node *node)
3601 ir_node *lower = get_Bound_lower(node);
3602 dbg_info *dbgi = get_irn_dbg_info(node);
3604 if (is_Const_0(lower)) {
3605 /* typical case for Java */
3606 ir_node *sub, *res, *flags, *block;
3607 ir_graph *irg = current_ir_graph;
3609 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3610 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3612 block = get_nodes_block(res);
3613 if (! is_Proj(res)) {
3615 set_irn_mode(sub, mode_T);
3616 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3618 sub = get_Proj_pred(res);
3620 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3621 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3622 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3624 panic("generic Bound not supported in ia32 Backend");
3630 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3632 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3633 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3635 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3636 match_immediate | match_mode_neutral);
3639 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3641 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3642 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3643 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3647 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3649 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3650 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3651 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3655 static ir_node *gen_ia32_l_Add(ir_node *node) {
3656 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3657 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3658 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3659 match_commutative | match_am | match_immediate |
3660 match_mode_neutral);
3662 if(is_Proj(lowered)) {
3663 lowered = get_Proj_pred(lowered);
3665 assert(is_ia32_Add(lowered));
3666 set_irn_mode(lowered, mode_T);
3672 static ir_node *gen_ia32_l_Adc(ir_node *node)
3674 return gen_binop_flags(node, new_rd_ia32_Adc,
3675 match_commutative | match_am | match_immediate |
3676 match_mode_neutral);
3680 * Transforms a l_MulS into a "real" MulS node.
3682 * @return the created ia32 Mul node
3684 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3685 ir_node *left = get_binop_left(node);
3686 ir_node *right = get_binop_right(node);
3688 return gen_binop(node, left, right, new_rd_ia32_Mul,
3689 match_commutative | match_am | match_mode_neutral);
3693 * Transforms a l_IMulS into a "real" IMul1OPS node.
3695 * @return the created ia32 IMul1OP node
3697 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3698 ir_node *left = get_binop_left(node);
3699 ir_node *right = get_binop_right(node);
3701 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3702 match_commutative | match_am | match_mode_neutral);
3705 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3706 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3707 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3708 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3709 match_am | match_immediate | match_mode_neutral);
3711 if(is_Proj(lowered)) {
3712 lowered = get_Proj_pred(lowered);
3714 assert(is_ia32_Sub(lowered));
3715 set_irn_mode(lowered, mode_T);
3721 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3722 return gen_binop_flags(node, new_rd_ia32_Sbb,
3723 match_am | match_immediate | match_mode_neutral);
3727 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3728 * op1 - target to be shifted
3729 * op2 - contains bits to be shifted into target
3731 * Only op3 can be an immediate.
3733 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3734 ir_node *low, ir_node *count)
3736 ir_node *block = get_nodes_block(node);
3737 ir_node *new_block = be_transform_node(block);
3738 ir_graph *irg = current_ir_graph;
3739 dbg_info *dbgi = get_irn_dbg_info(node);
3740 ir_node *new_high = be_transform_node(high);
3741 ir_node *new_low = be_transform_node(low);
3745 /* the shift amount can be any mode that is bigger than 5 bits, since all
3746 * other bits are ignored anyway */
3747 while (is_Conv(count) &&
3748 get_irn_n_edges(count) == 1 &&
3749 mode_is_int(get_irn_mode(count))) {
3750 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3751 count = get_Conv_op(count);
3753 new_count = create_immediate_or_transform(count, 0);
3755 if (is_ia32_l_ShlD(node)) {
3756 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3759 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3762 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3767 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3769 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3770 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3771 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3772 return gen_lowered_64bit_shifts(node, high, low, count);
3775 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3777 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3778 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3779 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3780 return gen_lowered_64bit_shifts(node, high, low, count);
3783 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3784 ir_node *src_block = get_nodes_block(node);
3785 ir_node *block = be_transform_node(src_block);
3786 ir_graph *irg = current_ir_graph;
3787 dbg_info *dbgi = get_irn_dbg_info(node);
3788 ir_node *frame = get_irg_frame(irg);
3789 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3790 ir_node *nomem = new_NoMem();
3791 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3792 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3793 ir_node *new_val_low = be_transform_node(val_low);
3794 ir_node *new_val_high = be_transform_node(val_high);
3799 ir_node *store_high;
3801 if(!mode_is_signed(get_irn_mode(val_high))) {
3802 panic("unsigned long long -> float not supported yet (%+F)", node);
3806 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3808 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3810 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3811 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3813 set_ia32_use_frame(store_low);
3814 set_ia32_use_frame(store_high);
3815 set_ia32_op_type(store_low, ia32_AddrModeD);
3816 set_ia32_op_type(store_high, ia32_AddrModeD);
3817 set_ia32_ls_mode(store_low, mode_Iu);
3818 set_ia32_ls_mode(store_high, mode_Is);
3819 add_ia32_am_offs_int(store_high, 4);
3823 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3826 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3828 set_ia32_use_frame(fild);
3829 set_ia32_op_type(fild, ia32_AddrModeS);
3830 set_ia32_ls_mode(fild, mode_Ls);
3832 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3834 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3837 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3838 ir_node *src_block = get_nodes_block(node);
3839 ir_node *block = be_transform_node(src_block);
3840 ir_graph *irg = current_ir_graph;
3841 dbg_info *dbgi = get_irn_dbg_info(node);
3842 ir_node *frame = get_irg_frame(irg);
3843 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3844 ir_node *nomem = new_NoMem();
3845 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3846 ir_node *new_val = be_transform_node(val);
3847 ir_node *fist, *mem;
3849 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3850 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3851 set_ia32_use_frame(fist);
3852 set_ia32_op_type(fist, ia32_AddrModeD);
3853 set_ia32_ls_mode(fist, mode_Ls);
3859 * the BAD transformer.
3861 static ir_node *bad_transform(ir_node *node) {
3862 panic("No transform function for %+F available.", node);
3866 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
3867 ir_graph *irg = current_ir_graph;
3868 ir_node *block = be_transform_node(get_nodes_block(node));
3869 ir_node *pred = get_Proj_pred(node);
3870 ir_node *new_pred = be_transform_node(pred);
3871 ir_node *frame = get_irg_frame(irg);
3872 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3873 dbg_info *dbgi = get_irn_dbg_info(node);
3874 long pn = get_Proj_proj(node);
3879 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3880 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3881 set_ia32_use_frame(load);
3882 set_ia32_op_type(load, ia32_AddrModeS);
3883 set_ia32_ls_mode(load, mode_Iu);
3884 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3885 * 32 bit from it with this particular load */
3886 attr = get_ia32_attr(load);
3887 attr->data.need_64bit_stackent = 1;
3889 if (pn == pn_ia32_l_FloattoLL_res_high) {
3890 add_ia32_am_offs_int(load, 4);
3892 assert(pn == pn_ia32_l_FloattoLL_res_low);
3895 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3901 * Transform the Projs of an AddSP.
3903 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
3904 ir_node *block = be_transform_node(get_nodes_block(node));
3905 ir_node *pred = get_Proj_pred(node);
3906 ir_node *new_pred = be_transform_node(pred);
3907 ir_graph *irg = current_ir_graph;
3908 dbg_info *dbgi = get_irn_dbg_info(node);
3909 long proj = get_Proj_proj(node);
3911 if (proj == pn_be_AddSP_sp) {
3912 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3913 pn_ia32_SubSP_stack);
3914 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3916 } else if(proj == pn_be_AddSP_res) {
3917 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3918 pn_ia32_SubSP_addr);
3919 } else if (proj == pn_be_AddSP_M) {
3920 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3924 return new_rd_Unknown(irg, get_irn_mode(node));
3928 * Transform the Projs of a SubSP.
3930 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
3931 ir_node *block = be_transform_node(get_nodes_block(node));
3932 ir_node *pred = get_Proj_pred(node);
3933 ir_node *new_pred = be_transform_node(pred);
3934 ir_graph *irg = current_ir_graph;
3935 dbg_info *dbgi = get_irn_dbg_info(node);
3936 long proj = get_Proj_proj(node);
3938 if (proj == pn_be_SubSP_sp) {
3939 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3940 pn_ia32_AddSP_stack);
3941 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3943 } else if (proj == pn_be_SubSP_M) {
3944 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3948 return new_rd_Unknown(irg, get_irn_mode(node));
3952 * Transform and renumber the Projs from a Load.
3954 static ir_node *gen_Proj_Load(ir_node *node) {
3956 ir_node *block = be_transform_node(get_nodes_block(node));
3957 ir_node *pred = get_Proj_pred(node);
3958 ir_graph *irg = current_ir_graph;
3959 dbg_info *dbgi = get_irn_dbg_info(node);
3960 long proj = get_Proj_proj(node);
3962 /* loads might be part of source address mode matches, so we don't
3963 * transform the ProjMs yet (with the exception of loads whose result is
3966 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
3969 /* this is needed, because sometimes we have loops that are only
3970 reachable through the ProjM */
3971 be_enqueue_preds(node);
3972 /* do it in 2 steps, to silence firm verifier */
3973 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
3974 set_Proj_proj(res, pn_ia32_mem);
3978 /* renumber the proj */
3979 new_pred = be_transform_node(pred);
3980 if (is_ia32_Load(new_pred)) {
3983 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
3985 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
3986 case pn_Load_X_regular:
3987 return new_rd_Jmp(dbgi, irg, block);
3988 case pn_Load_X_except:
3989 /* This Load might raise an exception. Mark it. */
3990 set_ia32_exc_label(new_pred, 1);
3991 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
3995 } else if (is_ia32_Conv_I2I(new_pred) ||
3996 is_ia32_Conv_I2I8Bit(new_pred)) {
3997 set_irn_mode(new_pred, mode_T);
3998 if (proj == pn_Load_res) {
3999 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4000 } else if (proj == pn_Load_M) {
4001 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4003 } else if (is_ia32_xLoad(new_pred)) {
4006 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4008 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4009 case pn_Load_X_regular:
4010 return new_rd_Jmp(dbgi, irg, block);
4011 case pn_Load_X_except:
4012 /* This Load might raise an exception. Mark it. */
4013 set_ia32_exc_label(new_pred, 1);
4014 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4018 } else if (is_ia32_vfld(new_pred)) {
4021 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4023 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4024 case pn_Load_X_regular:
4025 return new_rd_Jmp(dbgi, irg, block);
4026 case pn_Load_X_except:
4027 /* This Load might raise an exception. Mark it. */
4028 set_ia32_exc_label(new_pred, 1);
4029 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4034 /* can happen for ProJMs when source address mode happened for the
4037 /* however it should not be the result proj, as that would mean the
4038 load had multiple users and should not have been used for
4040 if (proj != pn_Load_M) {
4041 panic("internal error: transformed node not a Load");
4043 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4047 return new_rd_Unknown(irg, get_irn_mode(node));
4051 * Transform and renumber the Projs from a DivMod like instruction.
4053 static ir_node *gen_Proj_DivMod(ir_node *node) {
4054 ir_node *block = be_transform_node(get_nodes_block(node));
4055 ir_node *pred = get_Proj_pred(node);
4056 ir_node *new_pred = be_transform_node(pred);
4057 ir_graph *irg = current_ir_graph;
4058 dbg_info *dbgi = get_irn_dbg_info(node);
4059 ir_mode *mode = get_irn_mode(node);
4060 long proj = get_Proj_proj(node);
4062 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4064 switch (get_irn_opcode(pred)) {
4068 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4070 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4071 case pn_Div_X_regular:
4072 return new_rd_Jmp(dbgi, irg, block);
4073 case pn_Div_X_except:
4074 set_ia32_exc_label(new_pred, 1);
4075 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4083 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4085 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4086 case pn_Mod_X_except:
4087 set_ia32_exc_label(new_pred, 1);
4088 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4096 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4097 case pn_DivMod_res_div:
4098 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4099 case pn_DivMod_res_mod:
4100 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4101 case pn_DivMod_X_regular:
4102 return new_rd_Jmp(dbgi, irg, block);
4103 case pn_DivMod_X_except:
4104 set_ia32_exc_label(new_pred, 1);
4105 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4115 return new_rd_Unknown(irg, mode);
4119 * Transform and renumber the Projs from a CopyB.
4121 static ir_node *gen_Proj_CopyB(ir_node *node) {
4122 ir_node *block = be_transform_node(get_nodes_block(node));
4123 ir_node *pred = get_Proj_pred(node);
4124 ir_node *new_pred = be_transform_node(pred);
4125 ir_graph *irg = current_ir_graph;
4126 dbg_info *dbgi = get_irn_dbg_info(node);
4127 ir_mode *mode = get_irn_mode(node);
4128 long proj = get_Proj_proj(node);
4131 case pn_CopyB_M_regular:
4132 if (is_ia32_CopyB_i(new_pred)) {
4133 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4134 } else if (is_ia32_CopyB(new_pred)) {
4135 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4143 return new_rd_Unknown(irg, mode);
4147 * Transform and renumber the Projs from a Quot.
4149 static ir_node *gen_Proj_Quot(ir_node *node) {
4150 ir_node *block = be_transform_node(get_nodes_block(node));
4151 ir_node *pred = get_Proj_pred(node);
4152 ir_node *new_pred = be_transform_node(pred);
4153 ir_graph *irg = current_ir_graph;
4154 dbg_info *dbgi = get_irn_dbg_info(node);
4155 ir_mode *mode = get_irn_mode(node);
4156 long proj = get_Proj_proj(node);
4160 if (is_ia32_xDiv(new_pred)) {
4161 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4162 } else if (is_ia32_vfdiv(new_pred)) {
4163 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4167 if (is_ia32_xDiv(new_pred)) {
4168 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4169 } else if (is_ia32_vfdiv(new_pred)) {
4170 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4173 case pn_Quot_X_regular:
4174 case pn_Quot_X_except:
4180 return new_rd_Unknown(irg, mode);
4183 static ir_node *gen_be_Call(ir_node *node) {
4184 ir_node *res = be_duplicate_node(node);
4187 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4189 /* Run the x87 simulator if the call returns a float value */
4190 call_tp = be_Call_get_type(node);
4191 if (get_method_n_ress(call_tp) > 0) {
4192 ir_type *const res_type = get_method_res_type(call_tp, 0);
4193 ir_mode *const res_mode = get_type_mode(res_type);
4195 if (res_mode != NULL && mode_is_float(res_mode)) {
4196 env_cg->do_x87_sim = 1;
4203 static ir_node *gen_be_IncSP(ir_node *node) {
4204 ir_node *res = be_duplicate_node(node);
4205 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4211 * Transform the Projs from a be_Call.
4213 static ir_node *gen_Proj_be_Call(ir_node *node) {
4214 ir_node *block = be_transform_node(get_nodes_block(node));
4215 ir_node *call = get_Proj_pred(node);
4216 ir_node *new_call = be_transform_node(call);
4217 ir_graph *irg = current_ir_graph;
4218 dbg_info *dbgi = get_irn_dbg_info(node);
4219 ir_type *method_type = be_Call_get_type(call);
4220 int n_res = get_method_n_ress(method_type);
4221 long proj = get_Proj_proj(node);
4222 ir_mode *mode = get_irn_mode(node);
4224 const arch_register_class_t *cls;
4226 /* The following is kinda tricky: If we're using SSE, then we have to
4227 * move the result value of the call in floating point registers to an
4228 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4229 * after the call, we have to make sure to correctly make the
4230 * MemProj and the result Proj use these 2 nodes
4232 if (proj == pn_be_Call_M_regular) {
4233 // get new node for result, are we doing the sse load/store hack?
4234 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4235 ir_node *call_res_new;
4236 ir_node *call_res_pred = NULL;
4238 if (call_res != NULL) {
4239 call_res_new = be_transform_node(call_res);
4240 call_res_pred = get_Proj_pred(call_res_new);
4243 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4244 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4245 pn_be_Call_M_regular);
4247 assert(is_ia32_xLoad(call_res_pred));
4248 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4252 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4253 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4255 ir_node *frame = get_irg_frame(irg);
4256 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4258 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4261 /* in case there is no memory output: create one to serialize the copy
4263 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4264 pn_be_Call_M_regular);
4265 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4266 pn_be_Call_first_res);
4268 /* store st(0) onto stack */
4269 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4271 set_ia32_op_type(fstp, ia32_AddrModeD);
4272 set_ia32_use_frame(fstp);
4274 /* load into SSE register */
4275 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4277 set_ia32_op_type(sse_load, ia32_AddrModeS);
4278 set_ia32_use_frame(sse_load);
4280 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4286 /* transform call modes */
4287 if (mode_is_data(mode)) {
4288 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4292 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4296 * Transform the Projs from a Cmp.
4298 static ir_node *gen_Proj_Cmp(ir_node *node)
4300 /* this probably means not all mode_b nodes were lowered... */
4301 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4306 * Transform the Projs from a Bound.
4308 static ir_node *gen_Proj_Bound(ir_node *node)
4310 ir_node *new_node, *block;
4311 ir_node *pred = get_Proj_pred(node);
4313 switch (get_Proj_proj(node)) {
4315 return be_transform_node(get_Bound_mem(pred));
4316 case pn_Bound_X_regular:
4317 new_node = be_transform_node(pred);
4318 block = get_nodes_block(new_node);
4319 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4320 case pn_Bound_X_except:
4321 new_node = be_transform_node(pred);
4322 block = get_nodes_block(new_node);
4323 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4325 return be_transform_node(get_Bound_index(pred));
4327 panic("unsupported Proj from Bound");
4331 static ir_node *gen_Proj_ASM(ir_node *node)
4337 if (get_irn_mode(node) != mode_M)
4338 return be_duplicate_node(node);
4340 pred = get_Proj_pred(node);
4341 new_pred = be_transform_node(pred);
4342 block = get_nodes_block(new_pred);
4343 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4344 get_ia32_n_res(new_pred) + 1);
4348 * Transform and potentially renumber Proj nodes.
4350 static ir_node *gen_Proj(ir_node *node) {
4351 ir_node *pred = get_Proj_pred(node);
4354 switch (get_irn_opcode(pred)) {
4356 proj = get_Proj_proj(node);
4357 if (proj == pn_Store_M) {
4358 return be_transform_node(pred);
4361 return new_r_Bad(current_ir_graph);
4364 return gen_Proj_Load(node);
4366 return gen_Proj_ASM(node);
4370 return gen_Proj_DivMod(node);
4372 return gen_Proj_CopyB(node);
4374 return gen_Proj_Quot(node);
4376 return gen_Proj_be_SubSP(node);
4378 return gen_Proj_be_AddSP(node);
4380 return gen_Proj_be_Call(node);
4382 return gen_Proj_Cmp(node);
4384 return gen_Proj_Bound(node);
4386 proj = get_Proj_proj(node);
4387 if (proj == pn_Start_X_initial_exec) {
4388 ir_node *block = get_nodes_block(pred);
4389 dbg_info *dbgi = get_irn_dbg_info(node);
4392 /* we exchange the ProjX with a jump */
4393 block = be_transform_node(block);
4394 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
4397 if (node == be_get_old_anchor(anchor_tls)) {
4398 return gen_Proj_tls(node);
4403 if (is_ia32_l_FloattoLL(pred)) {
4404 return gen_Proj_l_FloattoLL(node);
4406 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4410 ir_mode *mode = get_irn_mode(node);
4411 if (ia32_mode_needs_gp_reg(mode)) {
4412 ir_node *new_pred = be_transform_node(pred);
4413 ir_node *block = be_transform_node(get_nodes_block(node));
4414 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4415 mode_Iu, get_Proj_proj(node));
4416 #ifdef DEBUG_libfirm
4417 new_proj->node_nr = node->node_nr;
4423 return be_duplicate_node(node);
4427 * Enters all transform functions into the generic pointer
4429 static void register_transformers(void)
4433 /* first clear the generic function pointer for all ops */
4434 clear_irp_opcodes_generic_func();
4436 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4437 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4475 /* transform ops from intrinsic lowering */
4487 GEN(ia32_l_LLtoFloat);
4488 GEN(ia32_l_FloattoLL);
4494 /* we should never see these nodes */
4509 /* handle generic backend nodes */
4518 op_Mulh = get_op_Mulh();
4527 * Pre-transform all unknown and noreg nodes.
4529 static void ia32_pretransform_node(void *arch_cg) {
4530 ia32_code_gen_t *cg = arch_cg;
4532 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4533 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4534 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4535 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4536 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4537 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4542 * Walker, checks if all ia32 nodes producing more than one result have their
4543 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4545 static void add_missing_keep_walker(ir_node *node, void *data)
4548 unsigned found_projs = 0;
4549 const ir_edge_t *edge;
4550 ir_mode *mode = get_irn_mode(node);
4555 if(!is_ia32_irn(node))
4558 n_outs = get_ia32_n_res(node);
4561 if(is_ia32_SwitchJmp(node))
4564 assert(n_outs < (int) sizeof(unsigned) * 8);
4565 foreach_out_edge(node, edge) {
4566 ir_node *proj = get_edge_src_irn(edge);
4567 int pn = get_Proj_proj(proj);
4569 if (get_irn_mode(proj) == mode_M)
4572 assert(pn < n_outs);
4573 found_projs |= 1 << pn;
4577 /* are keeps missing? */
4579 for(i = 0; i < n_outs; ++i) {
4582 const arch_register_req_t *req;
4583 const arch_register_class_t *cls;
4585 if(found_projs & (1 << i)) {
4589 req = get_ia32_out_req(node, i);
4594 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4598 block = get_nodes_block(node);
4599 in[0] = new_r_Proj(current_ir_graph, block, node,
4600 arch_register_class_mode(cls), i);
4601 if(last_keep != NULL) {
4602 be_Keep_add_node(last_keep, cls, in[0]);
4604 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4605 if(sched_is_scheduled(node)) {
4606 sched_add_after(node, last_keep);
4613 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4616 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4618 ir_graph *irg = be_get_birg_irg(cg->birg);
4619 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4622 /* do the transformation */
4623 void ia32_transform_graph(ia32_code_gen_t *cg) {
4625 ir_graph *irg = cg->irg;
4627 register_transformers();
4629 initial_fpcw = NULL;
4631 BE_TIMER_PUSH(t_heights);
4632 heights = heights_new(irg);
4633 BE_TIMER_POP(t_heights);
4634 ia32_calculate_non_address_mode_nodes(cg->birg);
4636 /* the transform phase is not safe for CSE (yet) because several nodes get
4637 * attributes set after their creation */
4638 cse_last = get_opt_cse();
4641 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4643 set_opt_cse(cse_last);
4645 ia32_free_non_address_mode_nodes();
4646 heights_free(heights);
4650 void ia32_init_transform(void)
4652 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");