2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
36 #include "irgraph_t.h"
41 #include "iredges_t.h"
53 #include "../benode_t.h"
54 #include "../besched.h"
56 #include "../beutil.h"
57 #include "../beirg_t.h"
58 #include "../betranshlp.h"
61 #include "bearch_ia32_t.h"
62 #include "ia32_common_transform.h"
63 #include "ia32_nodes_attr.h"
64 #include "ia32_transform.h"
65 #include "ia32_new_nodes.h"
66 #include "ia32_map_regs.h"
67 #include "ia32_dbg_stat.h"
68 #include "ia32_optimize.h"
69 #include "ia32_util.h"
70 #include "ia32_address_mode.h"
71 #include "ia32_architecture.h"
73 #include "gen_ia32_regalloc_if.h"
75 #define SFP_SIGN "0x80000000"
76 #define DFP_SIGN "0x8000000000000000"
77 #define SFP_ABS "0x7FFFFFFF"
78 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
79 #define DFP_INTMAX "9223372036854775807"
81 #define TP_SFP_SIGN "ia32_sfp_sign"
82 #define TP_DFP_SIGN "ia32_dfp_sign"
83 #define TP_SFP_ABS "ia32_sfp_abs"
84 #define TP_DFP_ABS "ia32_dfp_abs"
85 #define TP_INT_MAX "ia32_int_max"
87 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
88 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
89 #define ENT_SFP_ABS "IA32_SFP_ABS"
90 #define ENT_DFP_ABS "IA32_DFP_ABS"
91 #define ENT_INT_MAX "IA32_INT_MAX"
93 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
94 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
96 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
98 static ir_node *initial_fpcw = NULL;
100 extern ir_op *get_op_Mulh(void);
102 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
103 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
104 ir_node *op1, ir_node *op2);
106 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
107 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
108 ir_node *op1, ir_node *op2, ir_node *flags);
110 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
111 ir_node *block, ir_node *op1, ir_node *op2);
113 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
114 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
117 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
118 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
120 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
121 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
122 ir_node *op1, ir_node *op2, ir_node *fpcw);
124 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
125 ir_node *block, ir_node *op);
127 static ir_node *create_immediate_or_transform(ir_node *node,
128 char immediate_constraint_type);
130 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
131 dbg_info *dbgi, ir_node *block,
132 ir_node *op, ir_node *orig_node);
134 /** Return non-zero is a node represents the 0 constant. */
135 static bool is_Const_0(ir_node *node) {
136 return is_Const(node) && is_Const_null(node);
139 /** Return non-zero is a node represents the 1 constant. */
140 static bool is_Const_1(ir_node *node) {
141 return is_Const(node) && is_Const_one(node);
144 /** Return non-zero is a node represents the -1 constant. */
145 static bool is_Const_Minus_1(ir_node *node) {
146 return is_Const(node) && is_Const_all_one(node);
150 * returns true if constant can be created with a simple float command
152 static bool is_simple_x87_Const(ir_node *node)
154 tarval *tv = get_Const_tarval(node);
155 if (tarval_is_null(tv) || tarval_is_one(tv))
158 /* TODO: match all the other float constants */
163 * returns true if constant can be created with a simple float command
165 static bool is_simple_sse_Const(ir_node *node)
167 tarval *tv = get_Const_tarval(node);
168 ir_mode *mode = get_tarval_mode(tv);
173 if (tarval_is_null(tv) || tarval_is_one(tv))
176 if (mode == mode_D) {
177 unsigned val = get_tarval_sub_bits(tv, 0) |
178 (get_tarval_sub_bits(tv, 1) << 8) |
179 (get_tarval_sub_bits(tv, 2) << 16) |
180 (get_tarval_sub_bits(tv, 3) << 24);
182 /* lower 32bit are zero, really a 32bit constant */
186 /* TODO: match all the other float constants */
191 * Transforms a Const.
193 static ir_node *gen_Const(ir_node *node) {
194 ir_graph *irg = current_ir_graph;
195 ir_node *old_block = get_nodes_block(node);
196 ir_node *block = be_transform_node(old_block);
197 dbg_info *dbgi = get_irn_dbg_info(node);
198 ir_mode *mode = get_irn_mode(node);
200 assert(is_Const(node));
202 if (mode_is_float(mode)) {
204 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
205 ir_node *nomem = new_NoMem();
209 if (ia32_cg_config.use_sse2) {
210 tarval *tv = get_Const_tarval(node);
211 if (tarval_is_null(tv)) {
212 load = new_rd_ia32_xZero(dbgi, irg, block);
213 set_ia32_ls_mode(load, mode);
215 } else if (tarval_is_one(tv)) {
216 int cnst = mode == mode_F ? 26 : 55;
217 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
218 ir_node *imm2 = create_Immediate(NULL, 0, 2);
219 ir_node *pslld, *psrld;
221 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
222 set_ia32_ls_mode(load, mode);
223 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
224 set_ia32_ls_mode(pslld, mode);
225 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
226 set_ia32_ls_mode(psrld, mode);
228 } else if (mode == mode_F) {
229 /* we can place any 32bit constant by using a movd gp, sse */
230 unsigned val = get_tarval_sub_bits(tv, 0) |
231 (get_tarval_sub_bits(tv, 1) << 8) |
232 (get_tarval_sub_bits(tv, 2) << 16) |
233 (get_tarval_sub_bits(tv, 3) << 24);
234 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
235 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
236 set_ia32_ls_mode(load, mode);
239 if (mode == mode_D) {
240 unsigned val = get_tarval_sub_bits(tv, 0) |
241 (get_tarval_sub_bits(tv, 1) << 8) |
242 (get_tarval_sub_bits(tv, 2) << 16) |
243 (get_tarval_sub_bits(tv, 3) << 24);
245 ir_node *imm32 = create_Immediate(NULL, 0, 32);
246 ir_node *cnst, *psllq;
248 /* fine, lower 32bit are zero, produce 32bit value */
249 val = get_tarval_sub_bits(tv, 4) |
250 (get_tarval_sub_bits(tv, 5) << 8) |
251 (get_tarval_sub_bits(tv, 6) << 16) |
252 (get_tarval_sub_bits(tv, 7) << 24);
253 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
254 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
255 set_ia32_ls_mode(load, mode);
256 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
257 set_ia32_ls_mode(psllq, mode);
262 floatent = create_float_const_entity(node);
264 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
266 set_ia32_op_type(load, ia32_AddrModeS);
267 set_ia32_am_sc(load, floatent);
268 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
269 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
272 if (is_Const_null(node)) {
273 load = new_rd_ia32_vfldz(dbgi, irg, block);
275 set_ia32_ls_mode(load, mode);
276 } else if (is_Const_one(node)) {
277 load = new_rd_ia32_vfld1(dbgi, irg, block);
279 set_ia32_ls_mode(load, mode);
281 floatent = create_float_const_entity(node);
283 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
284 set_ia32_op_type(load, ia32_AddrModeS);
285 set_ia32_am_sc(load, floatent);
286 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
287 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
288 /* take the mode from the entity */
289 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
293 /* Const Nodes before the initial IncSP are a bad idea, because
294 * they could be spilled and we have no SP ready at that point yet.
295 * So add a dependency to the initial frame pointer calculation to
296 * avoid that situation.
298 if (get_irg_start_block(irg) == block) {
299 add_irn_dep(load, get_irg_frame(irg));
302 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
304 } else { /* non-float mode */
306 tarval *tv = get_Const_tarval(node);
309 tv = tarval_convert_to(tv, mode_Iu);
311 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
313 panic("couldn't convert constant tarval (%+F)", node);
315 val = get_tarval_long(tv);
317 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
318 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
321 if (get_irg_start_block(irg) == block) {
322 add_irn_dep(cnst, get_irg_frame(irg));
330 * Transforms a SymConst.
332 static ir_node *gen_SymConst(ir_node *node) {
333 ir_graph *irg = current_ir_graph;
334 ir_node *old_block = get_nodes_block(node);
335 ir_node *block = be_transform_node(old_block);
336 dbg_info *dbgi = get_irn_dbg_info(node);
337 ir_mode *mode = get_irn_mode(node);
340 if (mode_is_float(mode)) {
341 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
342 ir_node *nomem = new_NoMem();
344 if (ia32_cg_config.use_sse2)
345 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
347 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
348 set_ia32_am_sc(cnst, get_SymConst_entity(node));
349 set_ia32_use_frame(cnst);
353 if(get_SymConst_kind(node) != symconst_addr_ent) {
354 panic("backend only support symconst_addr_ent (at %+F)", node);
356 entity = get_SymConst_entity(node);
357 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
360 /* Const Nodes before the initial IncSP are a bad idea, because
361 * they could be spilled and we have no SP ready at that point yet
363 if (get_irg_start_block(irg) == block) {
364 add_irn_dep(cnst, get_irg_frame(irg));
367 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
372 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
373 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
374 static const struct {
376 const char *ent_name;
377 const char *cnst_str;
380 } names [ia32_known_const_max] = {
381 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
382 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
383 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
384 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
385 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
387 static ir_entity *ent_cache[ia32_known_const_max];
389 const char *tp_name, *ent_name, *cnst_str;
397 ent_name = names[kct].ent_name;
398 if (! ent_cache[kct]) {
399 tp_name = names[kct].tp_name;
400 cnst_str = names[kct].cnst_str;
402 switch (names[kct].mode) {
403 case 0: mode = mode_Iu; break;
404 case 1: mode = mode_Lu; break;
405 default: mode = mode_F; break;
407 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
408 tp = new_type_primitive(new_id_from_str(tp_name), mode);
409 /* set the specified alignment */
410 set_type_alignment_bytes(tp, names[kct].align);
412 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
414 set_entity_ld_ident(ent, get_entity_ident(ent));
415 set_entity_visibility(ent, visibility_local);
416 set_entity_variability(ent, variability_constant);
417 set_entity_allocation(ent, allocation_static);
419 /* we create a new entity here: It's initialization must resist on the
421 rem = current_ir_graph;
422 current_ir_graph = get_const_code_irg();
423 cnst = new_Const(mode, tv);
424 current_ir_graph = rem;
426 set_atomic_ent_value(ent, cnst);
428 /* cache the entry */
429 ent_cache[kct] = ent;
432 return ent_cache[kct];
435 static int prevents_AM(ir_node *const block, ir_node *const am_candidate,
436 ir_node *const other)
438 if (get_nodes_block(other) != block)
441 if (is_Sync(other)) {
444 for (i = get_Sync_n_preds(other) - 1; i >= 0; --i) {
445 ir_node *const pred = get_Sync_pred(other, i);
447 if (get_nodes_block(pred) != block)
450 /* Do not block ourselves from getting eaten */
451 if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate)
454 if (!heights_reachable_in_block(heights, pred, am_candidate))
462 /* Do not block ourselves from getting eaten */
463 if (is_Proj(other) && get_Proj_pred(other) == am_candidate)
466 if (!heights_reachable_in_block(heights, other, am_candidate))
474 * return true if the node is a Proj(Load) and could be used in source address
475 * mode for another node. Will return only true if the @p other node is not
476 * dependent on the memory of the Load (for binary operations use the other
477 * input here, for unary operations use NULL).
479 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
480 ir_node *other, ir_node *other2, match_flags_t flags)
485 /* float constants are always available */
486 if (is_Const(node)) {
487 ir_mode *mode = get_irn_mode(node);
488 if (mode_is_float(mode)) {
489 if (ia32_cg_config.use_sse2) {
490 if (is_simple_sse_Const(node))
493 if (is_simple_x87_Const(node))
496 if (get_irn_n_edges(node) > 1)
504 load = get_Proj_pred(node);
505 pn = get_Proj_proj(node);
506 if (!is_Load(load) || pn != pn_Load_res)
508 if (get_nodes_block(load) != block)
510 /* we only use address mode if we're the only user of the load */
511 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
513 /* in some edge cases with address mode we might reach the load normally
514 * and through some AM sequence, if it is already materialized then we
515 * can't create an AM node from it */
516 if (be_is_transformed(node))
519 /* don't do AM if other node inputs depend on the load (via mem-proj) */
520 if (other != NULL && prevents_AM(block, load, other))
523 if (other2 != NULL && prevents_AM(block, load, other2))
529 typedef struct ia32_address_mode_t ia32_address_mode_t;
530 struct ia32_address_mode_t {
535 ia32_op_type_t op_type;
539 unsigned commutative : 1;
540 unsigned ins_permuted : 1;
543 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
547 /* construct load address */
548 memset(addr, 0, sizeof(addr[0]));
549 ia32_create_address_mode(addr, ptr, /*force=*/0);
551 noreg_gp = ia32_new_NoReg_gp(env_cg);
552 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
553 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
554 addr->mem = be_transform_node(mem);
557 static void build_address(ia32_address_mode_t *am, ir_node *node)
559 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
560 ia32_address_t *addr = &am->addr;
566 if (is_Const(node)) {
567 ir_entity *entity = create_float_const_entity(node);
568 addr->base = noreg_gp;
569 addr->index = noreg_gp;
570 addr->mem = new_NoMem();
571 addr->symconst_ent = entity;
573 am->ls_mode = get_type_mode(get_entity_type(entity));
574 am->pinned = op_pin_state_floats;
578 load = get_Proj_pred(node);
579 ptr = get_Load_ptr(load);
580 mem = get_Load_mem(load);
581 new_mem = be_transform_node(mem);
582 am->pinned = get_irn_pinned(load);
583 am->ls_mode = get_Load_mode(load);
584 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
587 /* construct load address */
588 ia32_create_address_mode(addr, ptr, /*force=*/0);
590 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
591 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
595 static void set_address(ir_node *node, const ia32_address_t *addr)
597 set_ia32_am_scale(node, addr->scale);
598 set_ia32_am_sc(node, addr->symconst_ent);
599 set_ia32_am_offs_int(node, addr->offset);
600 if(addr->symconst_sign)
601 set_ia32_am_sc_sign(node);
603 set_ia32_use_frame(node);
604 set_ia32_frame_ent(node, addr->frame_entity);
608 * Apply attributes of a given address mode to a node.
610 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
612 set_address(node, &am->addr);
614 set_ia32_op_type(node, am->op_type);
615 set_ia32_ls_mode(node, am->ls_mode);
616 if (am->pinned == op_pin_state_pinned) {
617 /* beware: some nodes are already pinned and did not allow to change the state */
618 if (get_irn_pinned(node) != op_pin_state_pinned)
619 set_irn_pinned(node, op_pin_state_pinned);
622 set_ia32_commutative(node);
626 * Check, if a given node is a Down-Conv, ie. a integer Conv
627 * from a mode with a mode with more bits to a mode with lesser bits.
628 * Moreover, we return only true if the node has not more than 1 user.
630 * @param node the node
631 * @return non-zero if node is a Down-Conv
633 static int is_downconv(const ir_node *node)
641 /* we only want to skip the conv when we're the only user
642 * (not optimal but for now...)
644 if(get_irn_n_edges(node) > 1)
647 src_mode = get_irn_mode(get_Conv_op(node));
648 dest_mode = get_irn_mode(node);
649 return ia32_mode_needs_gp_reg(src_mode)
650 && ia32_mode_needs_gp_reg(dest_mode)
651 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
654 /* Skip all Down-Conv's on a given node and return the resulting node. */
655 ir_node *ia32_skip_downconv(ir_node *node) {
656 while (is_downconv(node))
657 node = get_Conv_op(node);
662 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
664 ir_mode *mode = get_irn_mode(node);
669 if(mode_is_signed(mode)) {
674 block = get_nodes_block(node);
675 dbgi = get_irn_dbg_info(node);
677 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
681 * matches operands of a node into ia32 addressing/operand modes. This covers
682 * usage of source address mode, immediates, operations with non 32-bit modes,
684 * The resulting data is filled into the @p am struct. block is the block
685 * of the node whose arguments are matched. op1, op2 are the first and second
686 * input that are matched (op1 may be NULL). other_op is another unrelated
687 * input that is not matched! but which is needed sometimes to check if AM
688 * for op1/op2 is legal.
689 * @p flags describes the supported modes of the operation in detail.
691 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
692 ir_node *op1, ir_node *op2, ir_node *other_op,
695 ia32_address_t *addr = &am->addr;
696 ir_mode *mode = get_irn_mode(op2);
697 int mode_bits = get_mode_size_bits(mode);
698 ir_node *noreg_gp, *new_op1, *new_op2;
700 unsigned commutative;
701 int use_am_and_immediates;
704 memset(am, 0, sizeof(am[0]));
706 commutative = (flags & match_commutative) != 0;
707 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
708 use_am = (flags & match_am) != 0;
709 use_immediate = (flags & match_immediate) != 0;
710 assert(!use_am_and_immediates || use_immediate);
713 assert(!commutative || op1 != NULL);
714 assert(use_am || !(flags & match_8bit_am));
715 assert(use_am || !(flags & match_16bit_am));
717 if (mode_bits == 8) {
718 if (!(flags & match_8bit_am))
720 /* we don't automatically add upconvs yet */
721 assert((flags & match_mode_neutral) || (flags & match_8bit));
722 } else if (mode_bits == 16) {
723 if (!(flags & match_16bit_am))
725 /* we don't automatically add upconvs yet */
726 assert((flags & match_mode_neutral) || (flags & match_16bit));
729 /* we can simply skip downconvs for mode neutral nodes: the upper bits
730 * can be random for these operations */
731 if (flags & match_mode_neutral) {
732 op2 = ia32_skip_downconv(op2);
734 op1 = ia32_skip_downconv(op1);
738 /* match immediates. firm nodes are normalized: constants are always on the
741 if (!(flags & match_try_am) && use_immediate) {
742 new_op2 = try_create_Immediate(op2, 0);
745 noreg_gp = ia32_new_NoReg_gp(env_cg);
746 if (new_op2 == NULL &&
747 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
748 build_address(am, op2);
749 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
750 if (mode_is_float(mode)) {
751 new_op2 = ia32_new_NoReg_vfp(env_cg);
755 am->op_type = ia32_AddrModeS;
756 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
758 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
760 build_address(am, op1);
762 if (mode_is_float(mode)) {
763 noreg = ia32_new_NoReg_vfp(env_cg);
768 if (new_op2 != NULL) {
771 new_op1 = be_transform_node(op2);
773 am->ins_permuted = 1;
775 am->op_type = ia32_AddrModeS;
777 if (flags & match_try_am) {
780 am->op_type = ia32_Normal;
784 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
786 new_op2 = be_transform_node(op2);
787 am->op_type = ia32_Normal;
788 am->ls_mode = get_irn_mode(op2);
789 if (flags & match_mode_neutral)
790 am->ls_mode = mode_Iu;
792 if (addr->base == NULL)
793 addr->base = noreg_gp;
794 if (addr->index == NULL)
795 addr->index = noreg_gp;
796 if (addr->mem == NULL)
797 addr->mem = new_NoMem();
799 am->new_op1 = new_op1;
800 am->new_op2 = new_op2;
801 am->commutative = commutative;
804 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
806 mark_irn_visited(old_node);
807 be_set_transformed_node(old_node, new_node);
810 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
815 if (am->mem_proj == NULL)
818 /* we have to create a mode_T so the old MemProj can attach to us */
819 mode = get_irn_mode(node);
820 load = get_Proj_pred(am->mem_proj);
822 set_transformed_and_mark(load, node);
824 if (mode != mode_T) {
825 set_irn_mode(node, mode_T);
826 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
833 * Construct a standard binary operation, set AM and immediate if required.
835 * @param node The original node for which the binop is created
836 * @param op1 The first operand
837 * @param op2 The second operand
838 * @param func The node constructor function
839 * @return The constructed ia32 node.
841 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
842 construct_binop_func *func, match_flags_t flags)
845 ir_node *block, *new_block, *new_node;
846 ia32_address_mode_t am;
847 ia32_address_t *addr = &am.addr;
849 block = get_nodes_block(node);
850 match_arguments(&am, block, op1, op2, NULL, flags);
852 dbgi = get_irn_dbg_info(node);
853 new_block = be_transform_node(block);
854 new_node = func(dbgi, current_ir_graph, new_block,
855 addr->base, addr->index, addr->mem,
856 am.new_op1, am.new_op2);
857 set_am_attributes(new_node, &am);
858 /* we can't use source address mode anymore when using immediates */
859 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
860 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
861 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
863 new_node = fix_mem_proj(new_node, &am);
870 n_ia32_l_binop_right,
871 n_ia32_l_binop_eflags
873 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
874 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
875 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
876 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
877 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
878 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
881 * Construct a binary operation which also consumes the eflags.
883 * @param node The node to transform
884 * @param func The node constructor function
885 * @param flags The match flags
886 * @return The constructor ia32 node
888 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
891 ir_node *src_block = get_nodes_block(node);
892 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
893 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
894 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
896 ir_node *block, *new_node, *new_eflags;
897 ia32_address_mode_t am;
898 ia32_address_t *addr = &am.addr;
900 match_arguments(&am, src_block, op1, op2, eflags, flags);
902 dbgi = get_irn_dbg_info(node);
903 block = be_transform_node(src_block);
904 new_eflags = be_transform_node(eflags);
905 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
906 addr->mem, am.new_op1, am.new_op2, new_eflags);
907 set_am_attributes(new_node, &am);
908 /* we can't use source address mode anymore when using immediates */
909 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
910 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
911 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
913 new_node = fix_mem_proj(new_node, &am);
918 static ir_node *get_fpcw(void)
921 if (initial_fpcw != NULL)
924 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
925 &ia32_fp_cw_regs[REG_FPCW]);
926 initial_fpcw = be_transform_node(fpcw);
932 * Construct a standard binary operation, set AM and immediate if required.
934 * @param op1 The first operand
935 * @param op2 The second operand
936 * @param func The node constructor function
937 * @return The constructed ia32 node.
939 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
940 construct_binop_float_func *func,
943 ir_mode *mode = get_irn_mode(node);
945 ir_node *block, *new_block, *new_node;
946 ia32_address_mode_t am;
947 ia32_address_t *addr = &am.addr;
949 /* cannot use address mode with long double on x87 */
950 if (get_mode_size_bits(mode) > 64)
953 block = get_nodes_block(node);
954 match_arguments(&am, block, op1, op2, NULL, flags);
956 dbgi = get_irn_dbg_info(node);
957 new_block = be_transform_node(block);
958 new_node = func(dbgi, current_ir_graph, new_block,
959 addr->base, addr->index, addr->mem,
960 am.new_op1, am.new_op2, get_fpcw());
961 set_am_attributes(new_node, &am);
963 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
965 new_node = fix_mem_proj(new_node, &am);
971 * Construct a shift/rotate binary operation, sets AM and immediate if required.
973 * @param op1 The first operand
974 * @param op2 The second operand
975 * @param func The node constructor function
976 * @return The constructed ia32 node.
978 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
979 construct_shift_func *func,
983 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
985 assert(! mode_is_float(get_irn_mode(node)));
986 assert(flags & match_immediate);
987 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
989 if (flags & match_mode_neutral) {
990 op1 = ia32_skip_downconv(op1);
991 new_op1 = be_transform_node(op1);
992 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
993 new_op1 = create_upconv(op1, node);
995 new_op1 = be_transform_node(op1);
998 /* the shift amount can be any mode that is bigger than 5 bits, since all
999 * other bits are ignored anyway */
1000 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1001 ir_node *const op = get_Conv_op(op2);
1002 if (mode_is_float(get_irn_mode(op)))
1005 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1007 new_op2 = create_immediate_or_transform(op2, 0);
1009 dbgi = get_irn_dbg_info(node);
1010 block = get_nodes_block(node);
1011 new_block = be_transform_node(block);
1012 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1013 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1015 /* lowered shift instruction may have a dependency operand, handle it here */
1016 if (get_irn_arity(node) == 3) {
1017 /* we have a dependency */
1018 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1019 add_irn_dep(new_node, new_dep);
1027 * Construct a standard unary operation, set AM and immediate if required.
1029 * @param op The operand
1030 * @param func The node constructor function
1031 * @return The constructed ia32 node.
1033 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1034 match_flags_t flags)
1037 ir_node *block, *new_block, *new_op, *new_node;
1039 assert(flags == 0 || flags == match_mode_neutral);
1040 if (flags & match_mode_neutral) {
1041 op = ia32_skip_downconv(op);
1044 new_op = be_transform_node(op);
1045 dbgi = get_irn_dbg_info(node);
1046 block = get_nodes_block(node);
1047 new_block = be_transform_node(block);
1048 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1050 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1055 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1056 ia32_address_t *addr)
1058 ir_node *base, *index, *res;
1062 base = ia32_new_NoReg_gp(env_cg);
1064 base = be_transform_node(base);
1067 index = addr->index;
1068 if (index == NULL) {
1069 index = ia32_new_NoReg_gp(env_cg);
1071 index = be_transform_node(index);
1074 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1075 set_address(res, addr);
1081 * Returns non-zero if a given address mode has a symbolic or
1082 * numerical offset != 0.
1084 static int am_has_immediates(const ia32_address_t *addr)
1086 return addr->offset != 0 || addr->symconst_ent != NULL
1087 || addr->frame_entity || addr->use_frame;
1091 * Creates an ia32 Add.
1093 * @return the created ia32 Add node
1095 static ir_node *gen_Add(ir_node *node) {
1096 ir_mode *mode = get_irn_mode(node);
1097 ir_node *op1 = get_Add_left(node);
1098 ir_node *op2 = get_Add_right(node);
1100 ir_node *block, *new_block, *new_node, *add_immediate_op;
1101 ia32_address_t addr;
1102 ia32_address_mode_t am;
1104 if (mode_is_float(mode)) {
1105 if (ia32_cg_config.use_sse2)
1106 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1107 match_commutative | match_am);
1109 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1110 match_commutative | match_am);
1113 ia32_mark_non_am(node);
1115 op2 = ia32_skip_downconv(op2);
1116 op1 = ia32_skip_downconv(op1);
1120 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1121 * 1. Add with immediate -> Lea
1122 * 2. Add with possible source address mode -> Add
1123 * 3. Otherwise -> Lea
1125 memset(&addr, 0, sizeof(addr));
1126 ia32_create_address_mode(&addr, node, /*force=*/1);
1127 add_immediate_op = NULL;
1129 dbgi = get_irn_dbg_info(node);
1130 block = get_nodes_block(node);
1131 new_block = be_transform_node(block);
1134 if(addr.base == NULL && addr.index == NULL) {
1135 ir_graph *irg = current_ir_graph;
1136 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1137 addr.symconst_sign, addr.offset);
1138 add_irn_dep(new_node, get_irg_frame(irg));
1139 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1142 /* add with immediate? */
1143 if(addr.index == NULL) {
1144 add_immediate_op = addr.base;
1145 } else if(addr.base == NULL && addr.scale == 0) {
1146 add_immediate_op = addr.index;
1149 if(add_immediate_op != NULL) {
1150 if(!am_has_immediates(&addr)) {
1151 #ifdef DEBUG_libfirm
1152 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1155 return be_transform_node(add_immediate_op);
1158 new_node = create_lea_from_address(dbgi, new_block, &addr);
1159 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1163 /* test if we can use source address mode */
1164 match_arguments(&am, block, op1, op2, NULL, match_commutative
1165 | match_mode_neutral | match_am | match_immediate | match_try_am);
1167 /* construct an Add with source address mode */
1168 if (am.op_type == ia32_AddrModeS) {
1169 ir_graph *irg = current_ir_graph;
1170 ia32_address_t *am_addr = &am.addr;
1171 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1172 am_addr->index, am_addr->mem, am.new_op1,
1174 set_am_attributes(new_node, &am);
1175 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1177 new_node = fix_mem_proj(new_node, &am);
1182 /* otherwise construct a lea */
1183 new_node = create_lea_from_address(dbgi, new_block, &addr);
1184 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1189 * Creates an ia32 Mul.
1191 * @return the created ia32 Mul node
1193 static ir_node *gen_Mul(ir_node *node) {
1194 ir_node *op1 = get_Mul_left(node);
1195 ir_node *op2 = get_Mul_right(node);
1196 ir_mode *mode = get_irn_mode(node);
1198 if (mode_is_float(mode)) {
1199 if (ia32_cg_config.use_sse2)
1200 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1201 match_commutative | match_am);
1203 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1204 match_commutative | match_am);
1206 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1207 match_commutative | match_am | match_mode_neutral |
1208 match_immediate | match_am_and_immediates);
1212 * Creates an ia32 Mulh.
1213 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1214 * this result while Mul returns the lower 32 bit.
1216 * @return the created ia32 Mulh node
1218 static ir_node *gen_Mulh(ir_node *node)
1220 ir_node *block = get_nodes_block(node);
1221 ir_node *new_block = be_transform_node(block);
1222 ir_graph *irg = current_ir_graph;
1223 dbg_info *dbgi = get_irn_dbg_info(node);
1224 ir_mode *mode = get_irn_mode(node);
1225 ir_node *op1 = get_Mulh_left(node);
1226 ir_node *op2 = get_Mulh_right(node);
1227 ir_node *proj_res_high;
1229 ia32_address_mode_t am;
1230 ia32_address_t *addr = &am.addr;
1232 assert(!mode_is_float(mode) && "Mulh with float not supported");
1233 assert(get_mode_size_bits(mode) == 32);
1235 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1237 if (mode_is_signed(mode)) {
1238 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1239 addr->index, addr->mem, am.new_op1,
1242 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1243 addr->index, addr->mem, am.new_op1,
1247 set_am_attributes(new_node, &am);
1248 /* we can't use source address mode anymore when using immediates */
1249 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1250 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1251 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1253 assert(get_irn_mode(new_node) == mode_T);
1255 fix_mem_proj(new_node, &am);
1257 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1258 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1259 mode_Iu, pn_ia32_IMul1OP_res_high);
1261 return proj_res_high;
1267 * Creates an ia32 And.
1269 * @return The created ia32 And node
1271 static ir_node *gen_And(ir_node *node) {
1272 ir_node *op1 = get_And_left(node);
1273 ir_node *op2 = get_And_right(node);
1274 assert(! mode_is_float(get_irn_mode(node)));
1276 /* is it a zero extension? */
1277 if (is_Const(op2)) {
1278 tarval *tv = get_Const_tarval(op2);
1279 long v = get_tarval_long(tv);
1281 if (v == 0xFF || v == 0xFFFF) {
1282 dbg_info *dbgi = get_irn_dbg_info(node);
1283 ir_node *block = get_nodes_block(node);
1290 assert(v == 0xFFFF);
1293 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1298 return gen_binop(node, op1, op2, new_rd_ia32_And,
1299 match_commutative | match_mode_neutral | match_am
1306 * Creates an ia32 Or.
1308 * @return The created ia32 Or node
1310 static ir_node *gen_Or(ir_node *node) {
1311 ir_node *op1 = get_Or_left(node);
1312 ir_node *op2 = get_Or_right(node);
1314 assert (! mode_is_float(get_irn_mode(node)));
1315 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1316 | match_mode_neutral | match_am | match_immediate);
1322 * Creates an ia32 Eor.
1324 * @return The created ia32 Eor node
1326 static ir_node *gen_Eor(ir_node *node) {
1327 ir_node *op1 = get_Eor_left(node);
1328 ir_node *op2 = get_Eor_right(node);
1330 assert(! mode_is_float(get_irn_mode(node)));
1331 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1332 | match_mode_neutral | match_am | match_immediate);
1337 * Creates an ia32 Sub.
1339 * @return The created ia32 Sub node
1341 static ir_node *gen_Sub(ir_node *node) {
1342 ir_node *op1 = get_Sub_left(node);
1343 ir_node *op2 = get_Sub_right(node);
1344 ir_mode *mode = get_irn_mode(node);
1346 if (mode_is_float(mode)) {
1347 if (ia32_cg_config.use_sse2)
1348 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1350 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1354 if (is_Const(op2)) {
1355 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1359 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1360 | match_am | match_immediate);
1363 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1364 ir_node *const src_val,
1365 ir_node *const src_mem,
1366 ir_node *const am_mem)
1368 if (is_NoMem(am_mem)) {
1369 return be_transform_node(src_mem);
1370 } else if (is_Proj(src_val) &&
1372 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1373 /* avoid memory loop */
1375 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1376 ir_node *const ptr_pred = get_Proj_pred(src_val);
1377 int const arity = get_Sync_n_preds(src_mem);
1382 NEW_ARR_A(ir_node*, ins, arity + 1);
1384 for (i = arity - 1; i >= 0; --i) {
1385 ir_node *const pred = get_Sync_pred(src_mem, i);
1387 /* avoid memory loop */
1388 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1391 ins[n++] = be_transform_node(pred);
1396 return new_r_Sync(irg, block, n, ins);
1400 ins[0] = be_transform_node(src_mem);
1402 return new_r_Sync(irg, block, 2, ins);
1407 * Generates an ia32 DivMod with additional infrastructure for the
1408 * register allocator if needed.
1410 static ir_node *create_Div(ir_node *node)
1412 ir_graph *irg = current_ir_graph;
1413 dbg_info *dbgi = get_irn_dbg_info(node);
1414 ir_node *block = get_nodes_block(node);
1415 ir_node *new_block = be_transform_node(block);
1422 ir_node *sign_extension;
1423 ia32_address_mode_t am;
1424 ia32_address_t *addr = &am.addr;
1426 /* the upper bits have random contents for smaller modes */
1427 switch (get_irn_opcode(node)) {
1429 op1 = get_Div_left(node);
1430 op2 = get_Div_right(node);
1431 mem = get_Div_mem(node);
1432 mode = get_Div_resmode(node);
1435 op1 = get_Mod_left(node);
1436 op2 = get_Mod_right(node);
1437 mem = get_Mod_mem(node);
1438 mode = get_Mod_resmode(node);
1441 op1 = get_DivMod_left(node);
1442 op2 = get_DivMod_right(node);
1443 mem = get_DivMod_mem(node);
1444 mode = get_DivMod_resmode(node);
1447 panic("invalid divmod node %+F", node);
1450 match_arguments(&am, block, op1, op2, NULL, match_am);
1452 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1453 is the memory of the consumed address. We can have only the second op as address
1454 in Div nodes, so check only op2. */
1455 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1457 if (mode_is_signed(mode)) {
1458 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1459 add_irn_dep(produceval, get_irg_frame(irg));
1460 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1463 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1464 addr->index, new_mem, am.new_op2,
1465 am.new_op1, sign_extension);
1467 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1468 add_irn_dep(sign_extension, get_irg_frame(irg));
1470 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1471 addr->index, new_mem, am.new_op2,
1472 am.new_op1, sign_extension);
1475 set_irn_pinned(new_node, get_irn_pinned(node));
1477 set_am_attributes(new_node, &am);
1478 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1480 new_node = fix_mem_proj(new_node, &am);
1486 static ir_node *gen_Mod(ir_node *node) {
1487 return create_Div(node);
1490 static ir_node *gen_Div(ir_node *node) {
1491 return create_Div(node);
1494 static ir_node *gen_DivMod(ir_node *node) {
1495 return create_Div(node);
1501 * Creates an ia32 floating Div.
1503 * @return The created ia32 xDiv node
1505 static ir_node *gen_Quot(ir_node *node)
1507 ir_node *op1 = get_Quot_left(node);
1508 ir_node *op2 = get_Quot_right(node);
1510 if (ia32_cg_config.use_sse2) {
1511 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1513 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1519 * Creates an ia32 Shl.
1521 * @return The created ia32 Shl node
1523 static ir_node *gen_Shl(ir_node *node) {
1524 ir_node *left = get_Shl_left(node);
1525 ir_node *right = get_Shl_right(node);
1527 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1528 match_mode_neutral | match_immediate);
1532 * Creates an ia32 Shr.
1534 * @return The created ia32 Shr node
1536 static ir_node *gen_Shr(ir_node *node) {
1537 ir_node *left = get_Shr_left(node);
1538 ir_node *right = get_Shr_right(node);
1540 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1546 * Creates an ia32 Sar.
1548 * @return The created ia32 Shrs node
1550 static ir_node *gen_Shrs(ir_node *node) {
1551 ir_node *left = get_Shrs_left(node);
1552 ir_node *right = get_Shrs_right(node);
1553 ir_mode *mode = get_irn_mode(node);
1555 if(is_Const(right) && mode == mode_Is) {
1556 tarval *tv = get_Const_tarval(right);
1557 long val = get_tarval_long(tv);
1559 /* this is a sign extension */
1560 ir_graph *irg = current_ir_graph;
1561 dbg_info *dbgi = get_irn_dbg_info(node);
1562 ir_node *block = be_transform_node(get_nodes_block(node));
1564 ir_node *new_op = be_transform_node(op);
1565 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1566 add_irn_dep(pval, get_irg_frame(irg));
1568 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1572 /* 8 or 16 bit sign extension? */
1573 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1574 ir_node *shl_left = get_Shl_left(left);
1575 ir_node *shl_right = get_Shl_right(left);
1576 if(is_Const(shl_right)) {
1577 tarval *tv1 = get_Const_tarval(right);
1578 tarval *tv2 = get_Const_tarval(shl_right);
1579 if(tv1 == tv2 && tarval_is_long(tv1)) {
1580 long val = get_tarval_long(tv1);
1581 if(val == 16 || val == 24) {
1582 dbg_info *dbgi = get_irn_dbg_info(node);
1583 ir_node *block = get_nodes_block(node);
1593 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1602 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1608 * Creates an ia32 Rol.
1610 * @param op1 The first operator
1611 * @param op2 The second operator
1612 * @return The created ia32 RotL node
1614 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1615 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1621 * Creates an ia32 Ror.
1622 * NOTE: There is no RotR with immediate because this would always be a RotL
1623 * "imm-mode_size_bits" which can be pre-calculated.
1625 * @param op1 The first operator
1626 * @param op2 The second operator
1627 * @return The created ia32 RotR node
1629 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1630 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1636 * Creates an ia32 RotR or RotL (depending on the found pattern).
1638 * @return The created ia32 RotL or RotR node
1640 static ir_node *gen_Rotl(ir_node *node) {
1641 ir_node *rotate = NULL;
1642 ir_node *op1 = get_Rotl_left(node);
1643 ir_node *op2 = get_Rotl_right(node);
1645 /* Firm has only RotL, so we are looking for a right (op2)
1646 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1647 that means we can create a RotR instead of an Add and a RotL */
1651 ir_node *left = get_Add_left(add);
1652 ir_node *right = get_Add_right(add);
1653 if (is_Const(right)) {
1654 tarval *tv = get_Const_tarval(right);
1655 ir_mode *mode = get_irn_mode(node);
1656 long bits = get_mode_size_bits(mode);
1658 if (is_Minus(left) &&
1659 tarval_is_long(tv) &&
1660 get_tarval_long(tv) == bits &&
1663 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1664 rotate = gen_Ror(node, op1, get_Minus_op(left));
1669 if (rotate == NULL) {
1670 rotate = gen_Rol(node, op1, op2);
1679 * Transforms a Minus node.
1681 * @return The created ia32 Minus node
1683 static ir_node *gen_Minus(ir_node *node)
1685 ir_node *op = get_Minus_op(node);
1686 ir_node *block = be_transform_node(get_nodes_block(node));
1687 ir_graph *irg = current_ir_graph;
1688 dbg_info *dbgi = get_irn_dbg_info(node);
1689 ir_mode *mode = get_irn_mode(node);
1694 if (mode_is_float(mode)) {
1695 ir_node *new_op = be_transform_node(op);
1696 if (ia32_cg_config.use_sse2) {
1697 /* TODO: non-optimal... if we have many xXors, then we should
1698 * rather create a load for the const and use that instead of
1699 * several AM nodes... */
1700 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1701 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1702 ir_node *nomem = new_rd_NoMem(irg);
1704 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1705 nomem, new_op, noreg_xmm);
1707 size = get_mode_size_bits(mode);
1708 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1710 set_ia32_am_sc(new_node, ent);
1711 set_ia32_op_type(new_node, ia32_AddrModeS);
1712 set_ia32_ls_mode(new_node, mode);
1714 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1717 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1720 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1726 * Transforms a Not node.
1728 * @return The created ia32 Not node
1730 static ir_node *gen_Not(ir_node *node) {
1731 ir_node *op = get_Not_op(node);
1733 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1734 assert (! mode_is_float(get_irn_mode(node)));
1736 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1742 * Transforms an Abs node.
1744 * @return The created ia32 Abs node
1746 static ir_node *gen_Abs(ir_node *node)
1748 ir_node *block = get_nodes_block(node);
1749 ir_node *new_block = be_transform_node(block);
1750 ir_node *op = get_Abs_op(node);
1751 ir_graph *irg = current_ir_graph;
1752 dbg_info *dbgi = get_irn_dbg_info(node);
1753 ir_mode *mode = get_irn_mode(node);
1754 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1755 ir_node *nomem = new_NoMem();
1761 if (mode_is_float(mode)) {
1762 new_op = be_transform_node(op);
1764 if (ia32_cg_config.use_sse2) {
1765 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1766 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1767 nomem, new_op, noreg_fp);
1769 size = get_mode_size_bits(mode);
1770 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1772 set_ia32_am_sc(new_node, ent);
1774 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1776 set_ia32_op_type(new_node, ia32_AddrModeS);
1777 set_ia32_ls_mode(new_node, mode);
1779 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1780 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1783 ir_node *xor, *pval, *sign_extension;
1785 if (get_mode_size_bits(mode) == 32) {
1786 new_op = be_transform_node(op);
1788 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1791 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1792 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1795 add_irn_dep(pval, get_irg_frame(irg));
1796 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1798 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1799 nomem, new_op, sign_extension);
1800 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1802 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1803 nomem, xor, sign_extension);
1804 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1811 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1813 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1814 dbg_info *dbgi = get_irn_dbg_info(cmp);
1815 ir_node *block = get_nodes_block(cmp);
1816 ir_node *new_block = be_transform_node(block);
1817 ir_node *op1 = be_transform_node(x);
1818 ir_node *op2 = be_transform_node(n);
1820 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1824 * Transform a node returning a "flag" result.
1826 * @param node the node to transform
1827 * @param pnc_out the compare mode to use
1829 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1838 /* we have a Cmp as input */
1839 if (is_Proj(node)) {
1840 ir_node *pred = get_Proj_pred(node);
1842 pn_Cmp pnc = get_Proj_proj(node);
1843 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1844 ir_node *l = get_Cmp_left(pred);
1845 ir_node *r = get_Cmp_right(pred);
1847 ir_node *la = get_And_left(l);
1848 ir_node *ra = get_And_right(l);
1850 ir_node *c = get_Shl_left(la);
1851 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1852 /* (1 << n) & ra) */
1853 ir_node *n = get_Shl_right(la);
1854 flags = gen_bt(pred, ra, n);
1855 /* we must generate a Jc/Jnc jump */
1856 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1859 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1864 ir_node *c = get_Shl_left(ra);
1865 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1866 /* la & (1 << n)) */
1867 ir_node *n = get_Shl_right(ra);
1868 flags = gen_bt(pred, la, n);
1869 /* we must generate a Jc/Jnc jump */
1870 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1873 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1879 flags = be_transform_node(pred);
1885 /* a mode_b value, we have to compare it against 0 */
1886 dbgi = get_irn_dbg_info(node);
1887 new_block = be_transform_node(get_nodes_block(node));
1888 new_op = be_transform_node(node);
1889 noreg = ia32_new_NoReg_gp(env_cg);
1890 nomem = new_NoMem();
1891 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1892 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1893 *pnc_out = pn_Cmp_Lg;
1898 * Transforms a Load.
1900 * @return the created ia32 Load node
1902 static ir_node *gen_Load(ir_node *node) {
1903 ir_node *old_block = get_nodes_block(node);
1904 ir_node *block = be_transform_node(old_block);
1905 ir_node *ptr = get_Load_ptr(node);
1906 ir_node *mem = get_Load_mem(node);
1907 ir_node *new_mem = be_transform_node(mem);
1910 ir_graph *irg = current_ir_graph;
1911 dbg_info *dbgi = get_irn_dbg_info(node);
1912 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1913 ir_mode *mode = get_Load_mode(node);
1916 ia32_address_t addr;
1918 /* construct load address */
1919 memset(&addr, 0, sizeof(addr));
1920 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1927 base = be_transform_node(base);
1933 index = be_transform_node(index);
1936 if (mode_is_float(mode)) {
1937 if (ia32_cg_config.use_sse2) {
1938 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1940 res_mode = mode_xmm;
1942 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1944 res_mode = mode_vfp;
1947 assert(mode != mode_b);
1949 /* create a conv node with address mode for smaller modes */
1950 if(get_mode_size_bits(mode) < 32) {
1951 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1952 new_mem, noreg, mode);
1954 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1959 set_irn_pinned(new_node, get_irn_pinned(node));
1960 set_ia32_op_type(new_node, ia32_AddrModeS);
1961 set_ia32_ls_mode(new_node, mode);
1962 set_address(new_node, &addr);
1964 if(get_irn_pinned(node) == op_pin_state_floats) {
1965 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1968 /* make sure we are scheduled behind the initial IncSP/Barrier
1969 * to avoid spills being placed before it
1971 if (block == get_irg_start_block(irg)) {
1972 add_irn_dep(new_node, get_irg_frame(irg));
1975 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1980 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1981 ir_node *ptr, ir_node *other)
1988 /* we only use address mode if we're the only user of the load */
1989 if (get_irn_n_edges(node) > 1)
1992 load = get_Proj_pred(node);
1995 if (get_nodes_block(load) != block)
1998 /* store should have the same pointer as the load */
1999 if (get_Load_ptr(load) != ptr)
2002 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2003 if (other != NULL &&
2004 get_nodes_block(other) == block &&
2005 heights_reachable_in_block(heights, other, load)) {
2012 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
2013 ir_node *const pred = get_Sync_pred(mem, i);
2015 if (is_Proj(pred) && get_Proj_pred(pred) == load)
2018 if (get_nodes_block(pred) == block &&
2019 heights_reachable_in_block(heights, pred, load)) {
2024 /* Store should be attached to the load */
2025 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
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 bool 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 * returns true if it is assured, that the upper bits of a node are "clean"
2730 * which means for a 16 or 8 bit value, that the upper bits in the register
2731 * are 0 for unsigned and a copy of the last significant bit for unsigned
2734 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2736 assert(ia32_mode_needs_gp_reg(mode));
2737 if (get_mode_size_bits(mode) >= 32)
2740 if (is_ia32_Conv_I2I(transformed_node)
2741 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2742 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2743 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2745 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2751 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2752 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2753 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2754 const ia32_immediate_attr_t *attr
2755 = get_ia32_immediate_attr_const(right);
2756 if (attr->symconst == 0
2757 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2763 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2764 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2765 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2766 const ia32_immediate_attr_t *attr
2767 = get_ia32_immediate_attr_const(right);
2768 if (attr->symconst == 0
2769 && (unsigned) attr->offset
2770 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2776 if (is_ia32_Immediate(transformed_node)
2777 || is_ia32_Const(transformed_node)) {
2778 const ia32_immediate_attr_t *attr
2779 = get_ia32_immediate_attr_const(transformed_node);
2780 if (mode_is_signed(mode)) {
2781 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2782 if (shifted == 0 || shifted == -1)
2785 unsigned long shifted = (unsigned long) attr->offset;
2786 shifted >>= get_mode_size_bits(mode);
2796 * Generate code for a Cmp.
2798 static ir_node *gen_Cmp(ir_node *node)
2800 ir_graph *irg = current_ir_graph;
2801 dbg_info *dbgi = get_irn_dbg_info(node);
2802 ir_node *block = get_nodes_block(node);
2803 ir_node *new_block = be_transform_node(block);
2804 ir_node *left = get_Cmp_left(node);
2805 ir_node *right = get_Cmp_right(node);
2806 ir_mode *cmp_mode = get_irn_mode(left);
2808 ia32_address_mode_t am;
2809 ia32_address_t *addr = &am.addr;
2812 if(mode_is_float(cmp_mode)) {
2813 if (ia32_cg_config.use_sse2) {
2814 return create_Ucomi(node);
2816 return create_Fucom(node);
2820 assert(ia32_mode_needs_gp_reg(cmp_mode));
2822 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2823 cmp_unsigned = !mode_is_signed(cmp_mode);
2824 if (is_Const_0(right) &&
2826 get_irn_n_edges(left) == 1 &&
2827 can_fold_test_and(node)) {
2828 /* Test(and_left, and_right) */
2829 ir_node *and_left = get_And_left(left);
2830 ir_node *and_right = get_And_right(left);
2831 ir_mode *mode = get_irn_mode(and_left);
2833 /* matze: code here used mode instead of cmd_mode, I think it is always
2834 * the same as cmp_mode, but I leave this here to see if this is really
2837 assert(mode == cmp_mode);
2839 match_arguments(&am, block, and_left, and_right, NULL,
2841 match_am | match_8bit_am | match_16bit_am |
2842 match_am_and_immediates | match_immediate |
2843 match_8bit | match_16bit);
2845 /* use 32bit compare mode if possible since the opcode is smaller */
2846 if (upper_bits_clean(am.new_op1, cmp_mode)
2847 && upper_bits_clean(am.new_op2, cmp_mode)) {
2848 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2851 if (get_mode_size_bits(cmp_mode) == 8) {
2852 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2853 addr->index, addr->mem, am.new_op1,
2854 am.new_op2, am.ins_permuted,
2857 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2858 addr->index, addr->mem, am.new_op1,
2859 am.new_op2, am.ins_permuted,
2863 /* Cmp(left, right) */
2864 match_arguments(&am, block, left, right, NULL,
2865 match_commutative | match_am | match_8bit_am |
2866 match_16bit_am | match_am_and_immediates |
2867 match_immediate | match_8bit | match_16bit);
2868 /* use 32bit compare mode if possible since the opcode is smaller */
2869 if (upper_bits_clean(am.new_op1, cmp_mode)
2870 && upper_bits_clean(am.new_op2, cmp_mode)) {
2871 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2874 if (get_mode_size_bits(cmp_mode) == 8) {
2875 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2876 addr->index, addr->mem, am.new_op1,
2877 am.new_op2, am.ins_permuted,
2880 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2881 addr->index, addr->mem, am.new_op1,
2882 am.new_op2, am.ins_permuted, cmp_unsigned);
2885 set_am_attributes(new_node, &am);
2886 set_ia32_ls_mode(new_node, cmp_mode);
2888 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2890 new_node = fix_mem_proj(new_node, &am);
2895 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2898 ir_graph *irg = current_ir_graph;
2899 dbg_info *dbgi = get_irn_dbg_info(node);
2900 ir_node *block = get_nodes_block(node);
2901 ir_node *new_block = be_transform_node(block);
2902 ir_node *val_true = get_Mux_true(node);
2903 ir_node *val_false = get_Mux_false(node);
2905 match_flags_t match_flags;
2906 ia32_address_mode_t am;
2907 ia32_address_t *addr;
2909 assert(ia32_cg_config.use_cmov);
2910 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2914 match_flags = match_commutative | match_am | match_16bit_am |
2917 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2919 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2920 addr->mem, am.new_op1, am.new_op2, new_flags,
2921 am.ins_permuted, pnc);
2922 set_am_attributes(new_node, &am);
2924 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2926 new_node = fix_mem_proj(new_node, &am);
2932 * Creates a ia32 Setcc instruction.
2934 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2935 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2938 ir_graph *irg = current_ir_graph;
2939 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2940 ir_node *nomem = new_NoMem();
2941 ir_mode *mode = get_irn_mode(orig_node);
2944 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2945 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2947 /* we might need to conv the result up */
2948 if (get_mode_size_bits(mode) > 8) {
2949 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2950 nomem, new_node, mode_Bu);
2951 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2958 * Create instruction for an unsigned Difference or Zero.
2960 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2961 ir_graph *irg = current_ir_graph;
2962 ir_mode *mode = get_irn_mode(psi);
2963 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2966 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2967 match_mode_neutral | match_am | match_immediate | match_two_users);
2969 block = get_nodes_block(new_node);
2971 if (is_Proj(new_node)) {
2972 sub = get_Proj_pred(new_node);
2973 assert(is_ia32_Sub(sub));
2976 set_irn_mode(sub, mode_T);
2977 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2979 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2981 dbgi = get_irn_dbg_info(psi);
2982 noreg = ia32_new_NoReg_gp(env_cg);
2983 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2984 nomem = new_NoMem();
2985 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2987 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2988 set_ia32_commutative(new_node);
2993 * Transforms a Mux node into CMov.
2995 * @return The transformed node.
2997 static ir_node *gen_Mux(ir_node *node)
2999 dbg_info *dbgi = get_irn_dbg_info(node);
3000 ir_node *block = get_nodes_block(node);
3001 ir_node *new_block = be_transform_node(block);
3002 ir_node *mux_true = get_Mux_true(node);
3003 ir_node *mux_false = get_Mux_false(node);
3004 ir_node *cond = get_Mux_sel(node);
3005 ir_mode *mode = get_irn_mode(node);
3008 assert(get_irn_mode(cond) == mode_b);
3010 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3011 if (mode_is_float(mode)) {
3012 ir_node *cmp = get_Proj_pred(cond);
3013 ir_node *cmp_left = get_Cmp_left(cmp);
3014 ir_node *cmp_right = get_Cmp_right(cmp);
3015 pn_Cmp pnc = get_Proj_proj(cond);
3017 if (ia32_cg_config.use_sse2) {
3018 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3019 if (cmp_left == mux_true && cmp_right == mux_false) {
3020 /* Mux(a <= b, a, b) => MIN */
3021 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3022 match_commutative | match_am | match_two_users);
3023 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3024 /* Mux(a <= b, b, a) => MAX */
3025 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3026 match_commutative | match_am | match_two_users);
3028 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3029 if (cmp_left == mux_true && cmp_right == mux_false) {
3030 /* Mux(a >= b, a, b) => MAX */
3031 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3032 match_commutative | match_am | match_two_users);
3033 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3034 /* Mux(a >= b, b, a) => MIN */
3035 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3036 match_commutative | match_am | match_two_users);
3040 panic("cannot transform floating point Mux");
3046 assert(ia32_mode_needs_gp_reg(mode));
3048 if (is_Proj(cond)) {
3049 ir_node *cmp = get_Proj_pred(cond);
3051 ir_node *cmp_left = get_Cmp_left(cmp);
3052 ir_node *cmp_right = get_Cmp_right(cmp);
3053 pn_Cmp pnc = get_Proj_proj(cond);
3055 /* check for unsigned Doz first */
3056 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3057 is_Const_0(mux_false) && is_Sub(mux_true) &&
3058 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3059 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3060 return create_Doz(node, cmp_left, cmp_right);
3061 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3062 is_Const_0(mux_true) && is_Sub(mux_false) &&
3063 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3064 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3065 return create_Doz(node, cmp_left, cmp_right);
3070 flags = get_flags_node(cond, &pnc);
3072 if (is_Const(mux_true) && is_Const(mux_false)) {
3073 /* both are const, good */
3074 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3075 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3076 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3077 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3079 /* Not that simple. */
3084 new_node = create_CMov(node, cond, flags, pnc);
3092 * Create a conversion from x87 state register to general purpose.
3094 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3095 ir_node *block = be_transform_node(get_nodes_block(node));
3096 ir_node *op = get_Conv_op(node);
3097 ir_node *new_op = be_transform_node(op);
3098 ia32_code_gen_t *cg = env_cg;
3099 ir_graph *irg = current_ir_graph;
3100 dbg_info *dbgi = get_irn_dbg_info(node);
3101 ir_node *noreg = ia32_new_NoReg_gp(cg);
3102 ir_mode *mode = get_irn_mode(node);
3103 ir_node *fist, *load, *mem;
3105 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3106 set_irn_pinned(fist, op_pin_state_floats);
3107 set_ia32_use_frame(fist);
3108 set_ia32_op_type(fist, ia32_AddrModeD);
3110 assert(get_mode_size_bits(mode) <= 32);
3111 /* exception we can only store signed 32 bit integers, so for unsigned
3112 we store a 64bit (signed) integer and load the lower bits */
3113 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3114 set_ia32_ls_mode(fist, mode_Ls);
3116 set_ia32_ls_mode(fist, mode_Is);
3118 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3121 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3123 set_irn_pinned(load, op_pin_state_floats);
3124 set_ia32_use_frame(load);
3125 set_ia32_op_type(load, ia32_AddrModeS);
3126 set_ia32_ls_mode(load, mode_Is);
3127 if(get_ia32_ls_mode(fist) == mode_Ls) {
3128 ia32_attr_t *attr = get_ia32_attr(load);
3129 attr->data.need_64bit_stackent = 1;
3131 ia32_attr_t *attr = get_ia32_attr(load);
3132 attr->data.need_32bit_stackent = 1;
3134 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3136 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3140 * Creates a x87 strict Conv by placing a Store and a Load
3142 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3144 ir_node *block = get_nodes_block(node);
3145 ir_graph *irg = current_ir_graph;
3146 dbg_info *dbgi = get_irn_dbg_info(node);
3147 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3148 ir_node *nomem = new_NoMem();
3149 ir_node *frame = get_irg_frame(irg);
3150 ir_node *store, *load;
3153 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3155 set_ia32_use_frame(store);
3156 set_ia32_op_type(store, ia32_AddrModeD);
3157 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3159 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3161 set_ia32_use_frame(load);
3162 set_ia32_op_type(load, ia32_AddrModeS);
3163 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3165 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3170 * Create a conversion from general purpose to x87 register
3172 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3173 ir_node *src_block = get_nodes_block(node);
3174 ir_node *block = be_transform_node(src_block);
3175 ir_graph *irg = current_ir_graph;
3176 dbg_info *dbgi = get_irn_dbg_info(node);
3177 ir_node *op = get_Conv_op(node);
3178 ir_node *new_op = NULL;
3182 ir_mode *store_mode;
3188 /* fild can use source AM if the operand is a signed 32bit integer */
3189 if (src_mode == mode_Is) {
3190 ia32_address_mode_t am;
3192 match_arguments(&am, src_block, NULL, op, NULL,
3193 match_am | match_try_am);
3194 if (am.op_type == ia32_AddrModeS) {
3195 ia32_address_t *addr = &am.addr;
3197 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3198 addr->index, addr->mem);
3199 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3202 set_am_attributes(fild, &am);
3203 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3205 fix_mem_proj(fild, &am);
3210 if(new_op == NULL) {
3211 new_op = be_transform_node(op);
3214 noreg = ia32_new_NoReg_gp(env_cg);
3215 nomem = new_NoMem();
3216 mode = get_irn_mode(op);
3218 /* first convert to 32 bit signed if necessary */
3219 src_bits = get_mode_size_bits(src_mode);
3220 if (src_bits == 8) {
3221 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3223 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3225 } else if (src_bits < 32) {
3226 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3228 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3232 assert(get_mode_size_bits(mode) == 32);
3235 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3238 set_ia32_use_frame(store);
3239 set_ia32_op_type(store, ia32_AddrModeD);
3240 set_ia32_ls_mode(store, mode_Iu);
3242 /* exception for 32bit unsigned, do a 64bit spill+load */
3243 if(!mode_is_signed(mode)) {
3246 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3248 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3249 get_irg_frame(irg), noreg, nomem,
3252 set_ia32_use_frame(zero_store);
3253 set_ia32_op_type(zero_store, ia32_AddrModeD);
3254 add_ia32_am_offs_int(zero_store, 4);
3255 set_ia32_ls_mode(zero_store, mode_Iu);
3260 store = new_rd_Sync(dbgi, irg, block, 2, in);
3261 store_mode = mode_Ls;
3263 store_mode = mode_Is;
3267 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3269 set_ia32_use_frame(fild);
3270 set_ia32_op_type(fild, ia32_AddrModeS);
3271 set_ia32_ls_mode(fild, store_mode);
3273 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3279 * Create a conversion from one integer mode into another one
3281 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3282 dbg_info *dbgi, ir_node *block, ir_node *op,
3285 ir_graph *irg = current_ir_graph;
3286 int src_bits = get_mode_size_bits(src_mode);
3287 int tgt_bits = get_mode_size_bits(tgt_mode);
3288 ir_node *new_block = be_transform_node(block);
3290 ir_mode *smaller_mode;
3292 ia32_address_mode_t am;
3293 ia32_address_t *addr = &am.addr;
3296 if (src_bits < tgt_bits) {
3297 smaller_mode = src_mode;
3298 smaller_bits = src_bits;
3300 smaller_mode = tgt_mode;
3301 smaller_bits = tgt_bits;
3304 #ifdef DEBUG_libfirm
3306 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3311 match_arguments(&am, block, NULL, op, NULL,
3312 match_8bit | match_16bit |
3313 match_am | match_8bit_am | match_16bit_am);
3315 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3316 /* unnecessary conv. in theory it shouldn't have been AM */
3317 assert(is_ia32_NoReg_GP(addr->base));
3318 assert(is_ia32_NoReg_GP(addr->index));
3319 assert(is_NoMem(addr->mem));
3320 assert(am.addr.offset == 0);
3321 assert(am.addr.symconst_ent == NULL);
3325 if (smaller_bits == 8) {
3326 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3327 addr->index, addr->mem, am.new_op2,
3330 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3331 addr->index, addr->mem, am.new_op2,
3334 set_am_attributes(new_node, &am);
3335 /* match_arguments assume that out-mode = in-mode, this isn't true here
3337 set_ia32_ls_mode(new_node, smaller_mode);
3338 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3339 new_node = fix_mem_proj(new_node, &am);
3344 * Transforms a Conv node.
3346 * @return The created ia32 Conv node
3348 static ir_node *gen_Conv(ir_node *node) {
3349 ir_node *block = get_nodes_block(node);
3350 ir_node *new_block = be_transform_node(block);
3351 ir_node *op = get_Conv_op(node);
3352 ir_node *new_op = NULL;
3353 ir_graph *irg = current_ir_graph;
3354 dbg_info *dbgi = get_irn_dbg_info(node);
3355 ir_mode *src_mode = get_irn_mode(op);
3356 ir_mode *tgt_mode = get_irn_mode(node);
3357 int src_bits = get_mode_size_bits(src_mode);
3358 int tgt_bits = get_mode_size_bits(tgt_mode);
3359 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3360 ir_node *nomem = new_rd_NoMem(irg);
3361 ir_node *res = NULL;
3363 if (src_mode == mode_b) {
3364 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3365 /* nothing to do, we already model bools as 0/1 ints */
3366 return be_transform_node(op);
3369 if (src_mode == tgt_mode) {
3370 if (get_Conv_strict(node)) {
3371 if (ia32_cg_config.use_sse2) {
3372 /* when we are in SSE mode, we can kill all strict no-op conversion */
3373 return be_transform_node(op);
3376 /* this should be optimized already, but who knows... */
3377 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3378 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3379 return be_transform_node(op);
3383 if (mode_is_float(src_mode)) {
3384 new_op = be_transform_node(op);
3385 /* we convert from float ... */
3386 if (mode_is_float(tgt_mode)) {
3387 if(src_mode == mode_E && tgt_mode == mode_D
3388 && !get_Conv_strict(node)) {
3389 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3394 if (ia32_cg_config.use_sse2) {
3395 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3396 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3398 set_ia32_ls_mode(res, tgt_mode);
3400 if(get_Conv_strict(node)) {
3401 res = gen_x87_strict_conv(tgt_mode, new_op);
3402 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3405 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3410 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3411 if (ia32_cg_config.use_sse2) {
3412 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3414 set_ia32_ls_mode(res, src_mode);
3416 return gen_x87_fp_to_gp(node);
3420 /* we convert from int ... */
3421 if (mode_is_float(tgt_mode)) {
3423 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3424 if (ia32_cg_config.use_sse2) {
3425 new_op = be_transform_node(op);
3426 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3428 set_ia32_ls_mode(res, tgt_mode);
3430 res = gen_x87_gp_to_fp(node, src_mode);
3431 if(get_Conv_strict(node)) {
3432 /* The strict-Conv is only necessary, if the int mode has more bits
3433 * than the float mantissa */
3434 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3435 size_t float_mantissa;
3436 /* FIXME There is no way to get the mantissa size of a mode */
3437 switch (get_mode_size_bits(tgt_mode)) {
3438 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3439 case 64: float_mantissa = 52 + 1; break;
3441 case 96: float_mantissa = 64; break;
3442 default: float_mantissa = 0; break;
3444 if (float_mantissa < int_mantissa) {
3445 res = gen_x87_strict_conv(tgt_mode, res);
3446 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3451 } else if(tgt_mode == mode_b) {
3452 /* mode_b lowering already took care that we only have 0/1 values */
3453 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3454 src_mode, tgt_mode));
3455 return be_transform_node(op);
3458 if (src_bits == tgt_bits) {
3459 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3460 src_mode, tgt_mode));
3461 return be_transform_node(op);
3464 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3472 static ir_node *create_immediate_or_transform(ir_node *node,
3473 char immediate_constraint_type)
3475 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3476 if (new_node == NULL) {
3477 new_node = be_transform_node(node);
3483 * Transforms a FrameAddr into an ia32 Add.
3485 static ir_node *gen_be_FrameAddr(ir_node *node) {
3486 ir_node *block = be_transform_node(get_nodes_block(node));
3487 ir_node *op = be_get_FrameAddr_frame(node);
3488 ir_node *new_op = be_transform_node(op);
3489 ir_graph *irg = current_ir_graph;
3490 dbg_info *dbgi = get_irn_dbg_info(node);
3491 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3494 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3495 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3496 set_ia32_use_frame(new_node);
3498 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3504 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3506 static ir_node *gen_be_Return(ir_node *node) {
3507 ir_graph *irg = current_ir_graph;
3508 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3509 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3510 ir_entity *ent = get_irg_entity(irg);
3511 ir_type *tp = get_entity_type(ent);
3516 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3517 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3520 int pn_ret_val, pn_ret_mem, arity, i;
3522 assert(ret_val != NULL);
3523 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3524 return be_duplicate_node(node);
3527 res_type = get_method_res_type(tp, 0);
3529 if (! is_Primitive_type(res_type)) {
3530 return be_duplicate_node(node);
3533 mode = get_type_mode(res_type);
3534 if (! mode_is_float(mode)) {
3535 return be_duplicate_node(node);
3538 assert(get_method_n_ress(tp) == 1);
3540 pn_ret_val = get_Proj_proj(ret_val);
3541 pn_ret_mem = get_Proj_proj(ret_mem);
3543 /* get the Barrier */
3544 barrier = get_Proj_pred(ret_val);
3546 /* get result input of the Barrier */
3547 ret_val = get_irn_n(barrier, pn_ret_val);
3548 new_ret_val = be_transform_node(ret_val);
3550 /* get memory input of the Barrier */
3551 ret_mem = get_irn_n(barrier, pn_ret_mem);
3552 new_ret_mem = be_transform_node(ret_mem);
3554 frame = get_irg_frame(irg);
3556 dbgi = get_irn_dbg_info(barrier);
3557 block = be_transform_node(get_nodes_block(barrier));
3559 noreg = ia32_new_NoReg_gp(env_cg);
3561 /* store xmm0 onto stack */
3562 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3563 new_ret_mem, new_ret_val);
3564 set_ia32_ls_mode(sse_store, mode);
3565 set_ia32_op_type(sse_store, ia32_AddrModeD);
3566 set_ia32_use_frame(sse_store);
3568 /* load into x87 register */
3569 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3570 set_ia32_op_type(fld, ia32_AddrModeS);
3571 set_ia32_use_frame(fld);
3573 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3574 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3576 /* create a new barrier */
3577 arity = get_irn_arity(barrier);
3578 in = alloca(arity * sizeof(in[0]));
3579 for (i = 0; i < arity; ++i) {
3582 if (i == pn_ret_val) {
3584 } else if (i == pn_ret_mem) {
3587 ir_node *in = get_irn_n(barrier, i);
3588 new_in = be_transform_node(in);
3593 new_barrier = new_ir_node(dbgi, irg, block,
3594 get_irn_op(barrier), get_irn_mode(barrier),
3596 copy_node_attr(barrier, new_barrier);
3597 be_duplicate_deps(barrier, new_barrier);
3598 set_transformed_and_mark(barrier, new_barrier);
3600 /* transform normally */
3601 return be_duplicate_node(node);
3605 * Transform a be_AddSP into an ia32_SubSP.
3607 static ir_node *gen_be_AddSP(ir_node *node)
3609 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3610 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3612 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3613 match_am | match_immediate);
3617 * Transform a be_SubSP into an ia32_AddSP
3619 static ir_node *gen_be_SubSP(ir_node *node)
3621 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3622 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3624 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3625 match_am | match_immediate);
3629 * Change some phi modes
3631 static ir_node *gen_Phi(ir_node *node) {
3632 ir_node *block = be_transform_node(get_nodes_block(node));
3633 ir_graph *irg = current_ir_graph;
3634 dbg_info *dbgi = get_irn_dbg_info(node);
3635 ir_mode *mode = get_irn_mode(node);
3638 if(ia32_mode_needs_gp_reg(mode)) {
3639 /* we shouldn't have any 64bit stuff around anymore */
3640 assert(get_mode_size_bits(mode) <= 32);
3641 /* all integer operations are on 32bit registers now */
3643 } else if(mode_is_float(mode)) {
3644 if (ia32_cg_config.use_sse2) {
3651 /* phi nodes allow loops, so we use the old arguments for now
3652 * and fix this later */
3653 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3654 get_irn_in(node) + 1);
3655 copy_node_attr(node, phi);
3656 be_duplicate_deps(node, phi);
3658 be_set_transformed_node(node, phi);
3659 be_enqueue_preds(node);
3667 static ir_node *gen_IJmp(ir_node *node)
3669 ir_node *block = get_nodes_block(node);
3670 ir_node *new_block = be_transform_node(block);
3671 dbg_info *dbgi = get_irn_dbg_info(node);
3672 ir_node *op = get_IJmp_target(node);
3674 ia32_address_mode_t am;
3675 ia32_address_t *addr = &am.addr;
3677 assert(get_irn_mode(op) == mode_P);
3679 match_arguments(&am, block, NULL, op, NULL,
3680 match_am | match_8bit_am | match_16bit_am |
3681 match_immediate | match_8bit | match_16bit);
3683 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3684 addr->base, addr->index, addr->mem,
3686 set_am_attributes(new_node, &am);
3687 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3689 new_node = fix_mem_proj(new_node, &am);
3695 * Transform a Bound node.
3697 static ir_node *gen_Bound(ir_node *node)
3700 ir_node *lower = get_Bound_lower(node);
3701 dbg_info *dbgi = get_irn_dbg_info(node);
3703 if (is_Const_0(lower)) {
3704 /* typical case for Java */
3705 ir_node *sub, *res, *flags, *block;
3706 ir_graph *irg = current_ir_graph;
3708 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3709 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3711 block = get_nodes_block(res);
3712 if (! is_Proj(res)) {
3714 set_irn_mode(sub, mode_T);
3715 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3717 sub = get_Proj_pred(res);
3719 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3720 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3721 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3723 panic("generic Bound not supported in ia32 Backend");
3729 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3731 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3732 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3734 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3735 match_immediate | match_mode_neutral);
3738 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3740 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3741 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3742 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3746 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3748 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3749 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3750 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3754 static ir_node *gen_ia32_l_Add(ir_node *node) {
3755 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3756 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3757 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3758 match_commutative | match_am | match_immediate |
3759 match_mode_neutral);
3761 if(is_Proj(lowered)) {
3762 lowered = get_Proj_pred(lowered);
3764 assert(is_ia32_Add(lowered));
3765 set_irn_mode(lowered, mode_T);
3771 static ir_node *gen_ia32_l_Adc(ir_node *node)
3773 return gen_binop_flags(node, new_rd_ia32_Adc,
3774 match_commutative | match_am | match_immediate |
3775 match_mode_neutral);
3779 * Transforms a l_MulS into a "real" MulS node.
3781 * @return the created ia32 Mul node
3783 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3784 ir_node *left = get_binop_left(node);
3785 ir_node *right = get_binop_right(node);
3787 return gen_binop(node, left, right, new_rd_ia32_Mul,
3788 match_commutative | match_am | match_mode_neutral);
3792 * Transforms a l_IMulS into a "real" IMul1OPS node.
3794 * @return the created ia32 IMul1OP node
3796 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3797 ir_node *left = get_binop_left(node);
3798 ir_node *right = get_binop_right(node);
3800 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3801 match_commutative | match_am | match_mode_neutral);
3804 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3805 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3806 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3807 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3808 match_am | match_immediate | match_mode_neutral);
3810 if(is_Proj(lowered)) {
3811 lowered = get_Proj_pred(lowered);
3813 assert(is_ia32_Sub(lowered));
3814 set_irn_mode(lowered, mode_T);
3820 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3821 return gen_binop_flags(node, new_rd_ia32_Sbb,
3822 match_am | match_immediate | match_mode_neutral);
3826 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3827 * op1 - target to be shifted
3828 * op2 - contains bits to be shifted into target
3830 * Only op3 can be an immediate.
3832 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3833 ir_node *low, ir_node *count)
3835 ir_node *block = get_nodes_block(node);
3836 ir_node *new_block = be_transform_node(block);
3837 ir_graph *irg = current_ir_graph;
3838 dbg_info *dbgi = get_irn_dbg_info(node);
3839 ir_node *new_high = be_transform_node(high);
3840 ir_node *new_low = be_transform_node(low);
3844 /* the shift amount can be any mode that is bigger than 5 bits, since all
3845 * other bits are ignored anyway */
3846 while (is_Conv(count) &&
3847 get_irn_n_edges(count) == 1 &&
3848 mode_is_int(get_irn_mode(count))) {
3849 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3850 count = get_Conv_op(count);
3852 new_count = create_immediate_or_transform(count, 0);
3854 if (is_ia32_l_ShlD(node)) {
3855 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3858 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3861 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3866 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3868 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3869 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3870 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3871 return gen_lowered_64bit_shifts(node, high, low, count);
3874 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3876 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3877 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3878 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3879 return gen_lowered_64bit_shifts(node, high, low, count);
3882 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3883 ir_node *src_block = get_nodes_block(node);
3884 ir_node *block = be_transform_node(src_block);
3885 ir_graph *irg = current_ir_graph;
3886 dbg_info *dbgi = get_irn_dbg_info(node);
3887 ir_node *frame = get_irg_frame(irg);
3888 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3889 ir_node *nomem = new_NoMem();
3890 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3891 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3892 ir_node *new_val_low = be_transform_node(val_low);
3893 ir_node *new_val_high = be_transform_node(val_high);
3898 ir_node *store_high;
3900 if(!mode_is_signed(get_irn_mode(val_high))) {
3901 panic("unsigned long long -> float not supported yet (%+F)", node);
3905 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3907 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3909 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3910 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3912 set_ia32_use_frame(store_low);
3913 set_ia32_use_frame(store_high);
3914 set_ia32_op_type(store_low, ia32_AddrModeD);
3915 set_ia32_op_type(store_high, ia32_AddrModeD);
3916 set_ia32_ls_mode(store_low, mode_Iu);
3917 set_ia32_ls_mode(store_high, mode_Is);
3918 add_ia32_am_offs_int(store_high, 4);
3922 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3925 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3927 set_ia32_use_frame(fild);
3928 set_ia32_op_type(fild, ia32_AddrModeS);
3929 set_ia32_ls_mode(fild, mode_Ls);
3931 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3933 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3936 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3937 ir_node *src_block = get_nodes_block(node);
3938 ir_node *block = be_transform_node(src_block);
3939 ir_graph *irg = current_ir_graph;
3940 dbg_info *dbgi = get_irn_dbg_info(node);
3941 ir_node *frame = get_irg_frame(irg);
3942 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3943 ir_node *nomem = new_NoMem();
3944 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3945 ir_node *new_val = be_transform_node(val);
3946 ir_node *fist, *mem;
3948 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3949 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3950 set_ia32_use_frame(fist);
3951 set_ia32_op_type(fist, ia32_AddrModeD);
3952 set_ia32_ls_mode(fist, mode_Ls);
3958 * the BAD transformer.
3960 static ir_node *bad_transform(ir_node *node) {
3961 panic("No transform function for %+F available.", node);
3965 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
3966 ir_graph *irg = current_ir_graph;
3967 ir_node *block = be_transform_node(get_nodes_block(node));
3968 ir_node *pred = get_Proj_pred(node);
3969 ir_node *new_pred = be_transform_node(pred);
3970 ir_node *frame = get_irg_frame(irg);
3971 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3972 dbg_info *dbgi = get_irn_dbg_info(node);
3973 long pn = get_Proj_proj(node);
3978 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3979 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3980 set_ia32_use_frame(load);
3981 set_ia32_op_type(load, ia32_AddrModeS);
3982 set_ia32_ls_mode(load, mode_Iu);
3983 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3984 * 32 bit from it with this particular load */
3985 attr = get_ia32_attr(load);
3986 attr->data.need_64bit_stackent = 1;
3988 if (pn == pn_ia32_l_FloattoLL_res_high) {
3989 add_ia32_am_offs_int(load, 4);
3991 assert(pn == pn_ia32_l_FloattoLL_res_low);
3994 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4000 * Transform the Projs of an AddSP.
4002 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4003 ir_node *block = be_transform_node(get_nodes_block(node));
4004 ir_node *pred = get_Proj_pred(node);
4005 ir_node *new_pred = be_transform_node(pred);
4006 ir_graph *irg = current_ir_graph;
4007 dbg_info *dbgi = get_irn_dbg_info(node);
4008 long proj = get_Proj_proj(node);
4010 if (proj == pn_be_AddSP_sp) {
4011 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4012 pn_ia32_SubSP_stack);
4013 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4015 } else if(proj == pn_be_AddSP_res) {
4016 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4017 pn_ia32_SubSP_addr);
4018 } else if (proj == pn_be_AddSP_M) {
4019 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4022 panic("No idea how to transform proj->AddSP");
4026 * Transform the Projs of a SubSP.
4028 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4029 ir_node *block = be_transform_node(get_nodes_block(node));
4030 ir_node *pred = get_Proj_pred(node);
4031 ir_node *new_pred = be_transform_node(pred);
4032 ir_graph *irg = current_ir_graph;
4033 dbg_info *dbgi = get_irn_dbg_info(node);
4034 long proj = get_Proj_proj(node);
4036 if (proj == pn_be_SubSP_sp) {
4037 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4038 pn_ia32_AddSP_stack);
4039 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4041 } else if (proj == pn_be_SubSP_M) {
4042 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4045 panic("No idea how to transform proj->SubSP");
4049 * Transform and renumber the Projs from a Load.
4051 static ir_node *gen_Proj_Load(ir_node *node) {
4053 ir_node *block = be_transform_node(get_nodes_block(node));
4054 ir_node *pred = get_Proj_pred(node);
4055 ir_graph *irg = current_ir_graph;
4056 dbg_info *dbgi = get_irn_dbg_info(node);
4057 long proj = get_Proj_proj(node);
4059 /* loads might be part of source address mode matches, so we don't
4060 * transform the ProjMs yet (with the exception of loads whose result is
4063 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4066 /* this is needed, because sometimes we have loops that are only
4067 reachable through the ProjM */
4068 be_enqueue_preds(node);
4069 /* do it in 2 steps, to silence firm verifier */
4070 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4071 set_Proj_proj(res, pn_ia32_mem);
4075 /* renumber the proj */
4076 new_pred = be_transform_node(pred);
4077 if (is_ia32_Load(new_pred)) {
4080 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4082 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4083 case pn_Load_X_regular:
4084 return new_rd_Jmp(dbgi, irg, block);
4085 case pn_Load_X_except:
4086 /* This Load might raise an exception. Mark it. */
4087 set_ia32_exc_label(new_pred, 1);
4088 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4092 } else if (is_ia32_Conv_I2I(new_pred) ||
4093 is_ia32_Conv_I2I8Bit(new_pred)) {
4094 set_irn_mode(new_pred, mode_T);
4095 if (proj == pn_Load_res) {
4096 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4097 } else if (proj == pn_Load_M) {
4098 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4100 } else if (is_ia32_xLoad(new_pred)) {
4103 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4105 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4106 case pn_Load_X_regular:
4107 return new_rd_Jmp(dbgi, irg, block);
4108 case pn_Load_X_except:
4109 /* This Load might raise an exception. Mark it. */
4110 set_ia32_exc_label(new_pred, 1);
4111 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4115 } else if (is_ia32_vfld(new_pred)) {
4118 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4120 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4121 case pn_Load_X_regular:
4122 return new_rd_Jmp(dbgi, irg, block);
4123 case pn_Load_X_except:
4124 /* This Load might raise an exception. Mark it. */
4125 set_ia32_exc_label(new_pred, 1);
4126 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4131 /* can happen for ProJMs when source address mode happened for the
4134 /* however it should not be the result proj, as that would mean the
4135 load had multiple users and should not have been used for
4137 if (proj != pn_Load_M) {
4138 panic("internal error: transformed node not a Load");
4140 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4143 panic("No idea how to transform proj");
4147 * Transform and renumber the Projs from a DivMod like instruction.
4149 static ir_node *gen_Proj_DivMod(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 long proj = get_Proj_proj(node);
4157 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4159 switch (get_irn_opcode(pred)) {
4163 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4165 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4166 case pn_Div_X_regular:
4167 return new_rd_Jmp(dbgi, irg, block);
4168 case pn_Div_X_except:
4169 set_ia32_exc_label(new_pred, 1);
4170 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4178 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4180 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4181 case pn_Mod_X_except:
4182 set_ia32_exc_label(new_pred, 1);
4183 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4191 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4192 case pn_DivMod_res_div:
4193 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4194 case pn_DivMod_res_mod:
4195 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4196 case pn_DivMod_X_regular:
4197 return new_rd_Jmp(dbgi, irg, block);
4198 case pn_DivMod_X_except:
4199 set_ia32_exc_label(new_pred, 1);
4200 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4209 panic("No idea how to transform proj->DivMod");
4213 * Transform and renumber the Projs from a CopyB.
4215 static ir_node *gen_Proj_CopyB(ir_node *node) {
4216 ir_node *block = be_transform_node(get_nodes_block(node));
4217 ir_node *pred = get_Proj_pred(node);
4218 ir_node *new_pred = be_transform_node(pred);
4219 ir_graph *irg = current_ir_graph;
4220 dbg_info *dbgi = get_irn_dbg_info(node);
4221 long proj = get_Proj_proj(node);
4224 case pn_CopyB_M_regular:
4225 if (is_ia32_CopyB_i(new_pred)) {
4226 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4227 } else if (is_ia32_CopyB(new_pred)) {
4228 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4235 panic("No idea how to transform proj->CopyB");
4239 * Transform and renumber the Projs from a Quot.
4241 static ir_node *gen_Proj_Quot(ir_node *node) {
4242 ir_node *block = be_transform_node(get_nodes_block(node));
4243 ir_node *pred = get_Proj_pred(node);
4244 ir_node *new_pred = be_transform_node(pred);
4245 ir_graph *irg = current_ir_graph;
4246 dbg_info *dbgi = get_irn_dbg_info(node);
4247 long proj = get_Proj_proj(node);
4251 if (is_ia32_xDiv(new_pred)) {
4252 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4253 } else if (is_ia32_vfdiv(new_pred)) {
4254 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4258 if (is_ia32_xDiv(new_pred)) {
4259 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4260 } else if (is_ia32_vfdiv(new_pred)) {
4261 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4264 case pn_Quot_X_regular:
4265 case pn_Quot_X_except:
4270 panic("No idea how to transform proj->Quot");
4273 static ir_node *gen_be_Call(ir_node *node) {
4274 ir_node *res = be_duplicate_node(node);
4277 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4279 /* Run the x87 simulator if the call returns a float value */
4280 call_tp = be_Call_get_type(node);
4281 if (get_method_n_ress(call_tp) > 0) {
4282 ir_type *const res_type = get_method_res_type(call_tp, 0);
4283 ir_mode *const res_mode = get_type_mode(res_type);
4285 if (res_mode != NULL && mode_is_float(res_mode)) {
4286 env_cg->do_x87_sim = 1;
4293 static ir_node *gen_be_IncSP(ir_node *node) {
4294 ir_node *res = be_duplicate_node(node);
4295 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4301 * Transform the Projs from a be_Call.
4303 static ir_node *gen_Proj_be_Call(ir_node *node) {
4304 ir_node *block = be_transform_node(get_nodes_block(node));
4305 ir_node *call = get_Proj_pred(node);
4306 ir_node *new_call = be_transform_node(call);
4307 ir_graph *irg = current_ir_graph;
4308 dbg_info *dbgi = get_irn_dbg_info(node);
4309 ir_type *method_type = be_Call_get_type(call);
4310 int n_res = get_method_n_ress(method_type);
4311 long proj = get_Proj_proj(node);
4312 ir_mode *mode = get_irn_mode(node);
4314 const arch_register_class_t *cls;
4316 /* The following is kinda tricky: If we're using SSE, then we have to
4317 * move the result value of the call in floating point registers to an
4318 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4319 * after the call, we have to make sure to correctly make the
4320 * MemProj and the result Proj use these 2 nodes
4322 if (proj == pn_be_Call_M_regular) {
4323 // get new node for result, are we doing the sse load/store hack?
4324 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4325 ir_node *call_res_new;
4326 ir_node *call_res_pred = NULL;
4328 if (call_res != NULL) {
4329 call_res_new = be_transform_node(call_res);
4330 call_res_pred = get_Proj_pred(call_res_new);
4333 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4334 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4335 pn_be_Call_M_regular);
4337 assert(is_ia32_xLoad(call_res_pred));
4338 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4342 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4343 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4345 ir_node *frame = get_irg_frame(irg);
4346 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4348 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4351 /* in case there is no memory output: create one to serialize the copy
4353 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4354 pn_be_Call_M_regular);
4355 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4356 pn_be_Call_first_res);
4358 /* store st(0) onto stack */
4359 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4361 set_ia32_op_type(fstp, ia32_AddrModeD);
4362 set_ia32_use_frame(fstp);
4364 /* load into SSE register */
4365 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4367 set_ia32_op_type(sse_load, ia32_AddrModeS);
4368 set_ia32_use_frame(sse_load);
4370 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4376 /* transform call modes */
4377 if (mode_is_data(mode)) {
4378 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4382 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4386 * Transform the Projs from a Cmp.
4388 static ir_node *gen_Proj_Cmp(ir_node *node)
4390 /* this probably means not all mode_b nodes were lowered... */
4391 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4396 * Transform the Projs from a Bound.
4398 static ir_node *gen_Proj_Bound(ir_node *node)
4400 ir_node *new_node, *block;
4401 ir_node *pred = get_Proj_pred(node);
4403 switch (get_Proj_proj(node)) {
4405 return be_transform_node(get_Bound_mem(pred));
4406 case pn_Bound_X_regular:
4407 new_node = be_transform_node(pred);
4408 block = get_nodes_block(new_node);
4409 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4410 case pn_Bound_X_except:
4411 new_node = be_transform_node(pred);
4412 block = get_nodes_block(new_node);
4413 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4415 return be_transform_node(get_Bound_index(pred));
4417 panic("unsupported Proj from Bound");
4421 static ir_node *gen_Proj_ASM(ir_node *node)
4427 if (get_irn_mode(node) != mode_M)
4428 return be_duplicate_node(node);
4430 pred = get_Proj_pred(node);
4431 new_pred = be_transform_node(pred);
4432 block = get_nodes_block(new_pred);
4433 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4434 get_ia32_n_res(new_pred) + 1);
4438 * Transform and potentially renumber Proj nodes.
4440 static ir_node *gen_Proj(ir_node *node) {
4441 ir_node *pred = get_Proj_pred(node);
4444 switch (get_irn_opcode(pred)) {
4446 proj = get_Proj_proj(node);
4447 if (proj == pn_Store_M) {
4448 return be_transform_node(pred);
4450 panic("No idea how to transform proj->Store");
4453 return gen_Proj_Load(node);
4455 return gen_Proj_ASM(node);
4459 return gen_Proj_DivMod(node);
4461 return gen_Proj_CopyB(node);
4463 return gen_Proj_Quot(node);
4465 return gen_Proj_be_SubSP(node);
4467 return gen_Proj_be_AddSP(node);
4469 return gen_Proj_be_Call(node);
4471 return gen_Proj_Cmp(node);
4473 return gen_Proj_Bound(node);
4475 proj = get_Proj_proj(node);
4476 if (proj == pn_Start_X_initial_exec) {
4477 ir_node *block = get_nodes_block(pred);
4478 dbg_info *dbgi = get_irn_dbg_info(node);
4481 /* we exchange the ProjX with a jump */
4482 block = be_transform_node(block);
4483 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
4486 if (node == be_get_old_anchor(anchor_tls)) {
4487 return gen_Proj_tls(node);
4492 if (is_ia32_l_FloattoLL(pred)) {
4493 return gen_Proj_l_FloattoLL(node);
4495 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4499 ir_mode *mode = get_irn_mode(node);
4500 if (ia32_mode_needs_gp_reg(mode)) {
4501 ir_node *new_pred = be_transform_node(pred);
4502 ir_node *block = be_transform_node(get_nodes_block(node));
4503 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4504 mode_Iu, get_Proj_proj(node));
4505 #ifdef DEBUG_libfirm
4506 new_proj->node_nr = node->node_nr;
4512 return be_duplicate_node(node);
4516 * Enters all transform functions into the generic pointer
4518 static void register_transformers(void)
4522 /* first clear the generic function pointer for all ops */
4523 clear_irp_opcodes_generic_func();
4525 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4526 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4564 /* transform ops from intrinsic lowering */
4576 GEN(ia32_l_LLtoFloat);
4577 GEN(ia32_l_FloattoLL);
4583 /* we should never see these nodes */
4598 /* handle generic backend nodes */
4607 op_Mulh = get_op_Mulh();
4616 * Pre-transform all unknown and noreg nodes.
4618 static void ia32_pretransform_node(void *arch_cg) {
4619 ia32_code_gen_t *cg = arch_cg;
4621 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4622 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4623 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4624 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4625 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4626 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4631 * Walker, checks if all ia32 nodes producing more than one result have their
4632 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4634 static void add_missing_keep_walker(ir_node *node, void *data)
4637 unsigned found_projs = 0;
4638 const ir_edge_t *edge;
4639 ir_mode *mode = get_irn_mode(node);
4644 if(!is_ia32_irn(node))
4647 n_outs = get_ia32_n_res(node);
4650 if(is_ia32_SwitchJmp(node))
4653 assert(n_outs < (int) sizeof(unsigned) * 8);
4654 foreach_out_edge(node, edge) {
4655 ir_node *proj = get_edge_src_irn(edge);
4656 int pn = get_Proj_proj(proj);
4658 if (get_irn_mode(proj) == mode_M)
4661 assert(pn < n_outs);
4662 found_projs |= 1 << pn;
4666 /* are keeps missing? */
4668 for(i = 0; i < n_outs; ++i) {
4671 const arch_register_req_t *req;
4672 const arch_register_class_t *cls;
4674 if(found_projs & (1 << i)) {
4678 req = get_ia32_out_req(node, i);
4683 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4687 block = get_nodes_block(node);
4688 in[0] = new_r_Proj(current_ir_graph, block, node,
4689 arch_register_class_mode(cls), i);
4690 if(last_keep != NULL) {
4691 be_Keep_add_node(last_keep, cls, in[0]);
4693 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4694 if(sched_is_scheduled(node)) {
4695 sched_add_after(node, last_keep);
4702 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4705 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4707 ir_graph *irg = be_get_birg_irg(cg->birg);
4708 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4711 /* do the transformation */
4712 void ia32_transform_graph(ia32_code_gen_t *cg) {
4714 ir_graph *irg = cg->irg;
4716 register_transformers();
4718 initial_fpcw = NULL;
4720 BE_TIMER_PUSH(t_heights);
4721 heights = heights_new(irg);
4722 BE_TIMER_POP(t_heights);
4723 ia32_calculate_non_address_mode_nodes(cg->birg);
4725 /* the transform phase is not safe for CSE (yet) because several nodes get
4726 * attributes set after their creation */
4727 cse_last = get_opt_cse();
4730 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4732 set_opt_cse(cse_last);
4734 ia32_free_non_address_mode_nodes();
4735 heights_free(heights);
4739 void ia32_init_transform(void)
4741 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");