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 ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
809 if (am->mem_proj == NULL)
812 /* we have to create a mode_T so the old MemProj can attach to us */
813 mode = get_irn_mode(node);
814 load = get_Proj_pred(am->mem_proj);
816 mark_irn_visited(load);
817 be_set_transformed_node(load, node);
819 if (mode != mode_T) {
820 set_irn_mode(node, mode_T);
821 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
828 * Construct a standard binary operation, set AM and immediate if required.
830 * @param node The original node for which the binop is created
831 * @param op1 The first operand
832 * @param op2 The second operand
833 * @param func The node constructor function
834 * @return The constructed ia32 node.
836 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
837 construct_binop_func *func, match_flags_t flags)
840 ir_node *block, *new_block, *new_node;
841 ia32_address_mode_t am;
842 ia32_address_t *addr = &am.addr;
844 block = get_nodes_block(node);
845 match_arguments(&am, block, op1, op2, NULL, flags);
847 dbgi = get_irn_dbg_info(node);
848 new_block = be_transform_node(block);
849 new_node = func(dbgi, current_ir_graph, new_block,
850 addr->base, addr->index, addr->mem,
851 am.new_op1, am.new_op2);
852 set_am_attributes(new_node, &am);
853 /* we can't use source address mode anymore when using immediates */
854 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
855 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
856 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
858 new_node = fix_mem_proj(new_node, &am);
865 n_ia32_l_binop_right,
866 n_ia32_l_binop_eflags
868 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
869 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
870 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
871 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
872 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
873 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
876 * Construct a binary operation which also consumes the eflags.
878 * @param node The node to transform
879 * @param func The node constructor function
880 * @param flags The match flags
881 * @return The constructor ia32 node
883 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
886 ir_node *src_block = get_nodes_block(node);
887 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
888 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
889 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
891 ir_node *block, *new_node, *new_eflags;
892 ia32_address_mode_t am;
893 ia32_address_t *addr = &am.addr;
895 match_arguments(&am, src_block, op1, op2, eflags, flags);
897 dbgi = get_irn_dbg_info(node);
898 block = be_transform_node(src_block);
899 new_eflags = be_transform_node(eflags);
900 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
901 addr->mem, am.new_op1, am.new_op2, new_eflags);
902 set_am_attributes(new_node, &am);
903 /* we can't use source address mode anymore when using immediates */
904 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
905 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
906 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
908 new_node = fix_mem_proj(new_node, &am);
913 static ir_node *get_fpcw(void)
916 if (initial_fpcw != NULL)
919 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
920 &ia32_fp_cw_regs[REG_FPCW]);
921 initial_fpcw = be_transform_node(fpcw);
927 * Construct a standard binary operation, set AM and immediate if required.
929 * @param op1 The first operand
930 * @param op2 The second operand
931 * @param func The node constructor function
932 * @return The constructed ia32 node.
934 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
935 construct_binop_float_func *func,
938 ir_mode *mode = get_irn_mode(node);
940 ir_node *block, *new_block, *new_node;
941 ia32_address_mode_t am;
942 ia32_address_t *addr = &am.addr;
944 /* cannot use address mode with long double on x87 */
945 if (get_mode_size_bits(mode) > 64)
948 block = get_nodes_block(node);
949 match_arguments(&am, block, op1, op2, NULL, flags);
951 dbgi = get_irn_dbg_info(node);
952 new_block = be_transform_node(block);
953 new_node = func(dbgi, current_ir_graph, new_block,
954 addr->base, addr->index, addr->mem,
955 am.new_op1, am.new_op2, get_fpcw());
956 set_am_attributes(new_node, &am);
958 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
960 new_node = fix_mem_proj(new_node, &am);
966 * Construct a shift/rotate binary operation, sets AM and immediate if required.
968 * @param op1 The first operand
969 * @param op2 The second operand
970 * @param func The node constructor function
971 * @return The constructed ia32 node.
973 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
974 construct_shift_func *func,
978 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
980 assert(! mode_is_float(get_irn_mode(node)));
981 assert(flags & match_immediate);
982 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
984 if (flags & match_mode_neutral) {
985 op1 = ia32_skip_downconv(op1);
986 new_op1 = be_transform_node(op1);
987 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
988 new_op1 = create_upconv(op1, node);
990 new_op1 = be_transform_node(op1);
993 /* the shift amount can be any mode that is bigger than 5 bits, since all
994 * other bits are ignored anyway */
995 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
996 ir_node *const op = get_Conv_op(op2);
997 if (mode_is_float(get_irn_mode(op)))
1000 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1002 new_op2 = create_immediate_or_transform(op2, 0);
1004 dbgi = get_irn_dbg_info(node);
1005 block = get_nodes_block(node);
1006 new_block = be_transform_node(block);
1007 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1008 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1010 /* lowered shift instruction may have a dependency operand, handle it here */
1011 if (get_irn_arity(node) == 3) {
1012 /* we have a dependency */
1013 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1014 add_irn_dep(new_node, new_dep);
1022 * Construct a standard unary operation, set AM and immediate if required.
1024 * @param op The operand
1025 * @param func The node constructor function
1026 * @return The constructed ia32 node.
1028 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1029 match_flags_t flags)
1032 ir_node *block, *new_block, *new_op, *new_node;
1034 assert(flags == 0 || flags == match_mode_neutral);
1035 if (flags & match_mode_neutral) {
1036 op = ia32_skip_downconv(op);
1039 new_op = be_transform_node(op);
1040 dbgi = get_irn_dbg_info(node);
1041 block = get_nodes_block(node);
1042 new_block = be_transform_node(block);
1043 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1045 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1050 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1051 ia32_address_t *addr)
1053 ir_node *base, *index, *res;
1057 base = ia32_new_NoReg_gp(env_cg);
1059 base = be_transform_node(base);
1062 index = addr->index;
1063 if (index == NULL) {
1064 index = ia32_new_NoReg_gp(env_cg);
1066 index = be_transform_node(index);
1069 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1070 set_address(res, addr);
1076 * Returns non-zero if a given address mode has a symbolic or
1077 * numerical offset != 0.
1079 static int am_has_immediates(const ia32_address_t *addr)
1081 return addr->offset != 0 || addr->symconst_ent != NULL
1082 || addr->frame_entity || addr->use_frame;
1086 * Creates an ia32 Add.
1088 * @return the created ia32 Add node
1090 static ir_node *gen_Add(ir_node *node) {
1091 ir_mode *mode = get_irn_mode(node);
1092 ir_node *op1 = get_Add_left(node);
1093 ir_node *op2 = get_Add_right(node);
1095 ir_node *block, *new_block, *new_node, *add_immediate_op;
1096 ia32_address_t addr;
1097 ia32_address_mode_t am;
1099 if (mode_is_float(mode)) {
1100 if (ia32_cg_config.use_sse2)
1101 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1102 match_commutative | match_am);
1104 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1105 match_commutative | match_am);
1108 ia32_mark_non_am(node);
1110 op2 = ia32_skip_downconv(op2);
1111 op1 = ia32_skip_downconv(op1);
1115 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1116 * 1. Add with immediate -> Lea
1117 * 2. Add with possible source address mode -> Add
1118 * 3. Otherwise -> Lea
1120 memset(&addr, 0, sizeof(addr));
1121 ia32_create_address_mode(&addr, node, /*force=*/1);
1122 add_immediate_op = NULL;
1124 dbgi = get_irn_dbg_info(node);
1125 block = get_nodes_block(node);
1126 new_block = be_transform_node(block);
1129 if(addr.base == NULL && addr.index == NULL) {
1130 ir_graph *irg = current_ir_graph;
1131 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1132 addr.symconst_sign, addr.offset);
1133 add_irn_dep(new_node, get_irg_frame(irg));
1134 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1137 /* add with immediate? */
1138 if(addr.index == NULL) {
1139 add_immediate_op = addr.base;
1140 } else if(addr.base == NULL && addr.scale == 0) {
1141 add_immediate_op = addr.index;
1144 if(add_immediate_op != NULL) {
1145 if(!am_has_immediates(&addr)) {
1146 #ifdef DEBUG_libfirm
1147 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1150 return be_transform_node(add_immediate_op);
1153 new_node = create_lea_from_address(dbgi, new_block, &addr);
1154 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1158 /* test if we can use source address mode */
1159 match_arguments(&am, block, op1, op2, NULL, match_commutative
1160 | match_mode_neutral | match_am | match_immediate | match_try_am);
1162 /* construct an Add with source address mode */
1163 if (am.op_type == ia32_AddrModeS) {
1164 ir_graph *irg = current_ir_graph;
1165 ia32_address_t *am_addr = &am.addr;
1166 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1167 am_addr->index, am_addr->mem, am.new_op1,
1169 set_am_attributes(new_node, &am);
1170 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1172 new_node = fix_mem_proj(new_node, &am);
1177 /* otherwise construct a lea */
1178 new_node = create_lea_from_address(dbgi, new_block, &addr);
1179 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1184 * Creates an ia32 Mul.
1186 * @return the created ia32 Mul node
1188 static ir_node *gen_Mul(ir_node *node) {
1189 ir_node *op1 = get_Mul_left(node);
1190 ir_node *op2 = get_Mul_right(node);
1191 ir_mode *mode = get_irn_mode(node);
1193 if (mode_is_float(mode)) {
1194 if (ia32_cg_config.use_sse2)
1195 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1196 match_commutative | match_am);
1198 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1199 match_commutative | match_am);
1201 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1202 match_commutative | match_am | match_mode_neutral |
1203 match_immediate | match_am_and_immediates);
1207 * Creates an ia32 Mulh.
1208 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1209 * this result while Mul returns the lower 32 bit.
1211 * @return the created ia32 Mulh node
1213 static ir_node *gen_Mulh(ir_node *node)
1215 ir_node *block = get_nodes_block(node);
1216 ir_node *new_block = be_transform_node(block);
1217 ir_graph *irg = current_ir_graph;
1218 dbg_info *dbgi = get_irn_dbg_info(node);
1219 ir_mode *mode = get_irn_mode(node);
1220 ir_node *op1 = get_Mulh_left(node);
1221 ir_node *op2 = get_Mulh_right(node);
1222 ir_node *proj_res_high;
1224 ia32_address_mode_t am;
1225 ia32_address_t *addr = &am.addr;
1227 assert(!mode_is_float(mode) && "Mulh with float not supported");
1228 assert(get_mode_size_bits(mode) == 32);
1230 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1232 if (mode_is_signed(mode)) {
1233 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1234 addr->index, addr->mem, am.new_op1,
1237 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1238 addr->index, addr->mem, am.new_op1,
1242 set_am_attributes(new_node, &am);
1243 /* we can't use source address mode anymore when using immediates */
1244 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1245 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1246 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1248 assert(get_irn_mode(new_node) == mode_T);
1250 fix_mem_proj(new_node, &am);
1252 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1253 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1254 mode_Iu, pn_ia32_IMul1OP_res_high);
1256 return proj_res_high;
1262 * Creates an ia32 And.
1264 * @return The created ia32 And node
1266 static ir_node *gen_And(ir_node *node) {
1267 ir_node *op1 = get_And_left(node);
1268 ir_node *op2 = get_And_right(node);
1269 assert(! mode_is_float(get_irn_mode(node)));
1271 /* is it a zero extension? */
1272 if (is_Const(op2)) {
1273 tarval *tv = get_Const_tarval(op2);
1274 long v = get_tarval_long(tv);
1276 if (v == 0xFF || v == 0xFFFF) {
1277 dbg_info *dbgi = get_irn_dbg_info(node);
1278 ir_node *block = get_nodes_block(node);
1285 assert(v == 0xFFFF);
1288 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1293 return gen_binop(node, op1, op2, new_rd_ia32_And,
1294 match_commutative | match_mode_neutral | match_am
1301 * Creates an ia32 Or.
1303 * @return The created ia32 Or node
1305 static ir_node *gen_Or(ir_node *node) {
1306 ir_node *op1 = get_Or_left(node);
1307 ir_node *op2 = get_Or_right(node);
1309 assert (! mode_is_float(get_irn_mode(node)));
1310 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1311 | match_mode_neutral | match_am | match_immediate);
1317 * Creates an ia32 Eor.
1319 * @return The created ia32 Eor node
1321 static ir_node *gen_Eor(ir_node *node) {
1322 ir_node *op1 = get_Eor_left(node);
1323 ir_node *op2 = get_Eor_right(node);
1325 assert(! mode_is_float(get_irn_mode(node)));
1326 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1327 | match_mode_neutral | match_am | match_immediate);
1332 * Creates an ia32 Sub.
1334 * @return The created ia32 Sub node
1336 static ir_node *gen_Sub(ir_node *node) {
1337 ir_node *op1 = get_Sub_left(node);
1338 ir_node *op2 = get_Sub_right(node);
1339 ir_mode *mode = get_irn_mode(node);
1341 if (mode_is_float(mode)) {
1342 if (ia32_cg_config.use_sse2)
1343 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1345 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1349 if (is_Const(op2)) {
1350 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1354 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1355 | match_am | match_immediate);
1358 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1359 ir_node *const src_val,
1360 ir_node *const src_mem,
1361 ir_node *const am_mem)
1363 if (is_NoMem(am_mem)) {
1364 return be_transform_node(src_mem);
1365 } else if (is_Proj(src_val) &&
1367 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1368 /* avoid memory loop */
1370 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1371 ir_node *const ptr_pred = get_Proj_pred(src_val);
1372 int const arity = get_Sync_n_preds(src_mem);
1377 NEW_ARR_A(ir_node*, ins, arity + 1);
1379 for (i = arity - 1; i >= 0; --i) {
1380 ir_node *const pred = get_Sync_pred(src_mem, i);
1382 /* avoid memory loop */
1383 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1386 ins[n++] = be_transform_node(pred);
1391 return new_r_Sync(irg, block, n, ins);
1395 ins[0] = be_transform_node(src_mem);
1397 return new_r_Sync(irg, block, 2, ins);
1402 * Generates an ia32 DivMod with additional infrastructure for the
1403 * register allocator if needed.
1405 static ir_node *create_Div(ir_node *node)
1407 ir_graph *irg = current_ir_graph;
1408 dbg_info *dbgi = get_irn_dbg_info(node);
1409 ir_node *block = get_nodes_block(node);
1410 ir_node *new_block = be_transform_node(block);
1417 ir_node *sign_extension;
1418 ia32_address_mode_t am;
1419 ia32_address_t *addr = &am.addr;
1421 /* the upper bits have random contents for smaller modes */
1422 switch (get_irn_opcode(node)) {
1424 op1 = get_Div_left(node);
1425 op2 = get_Div_right(node);
1426 mem = get_Div_mem(node);
1427 mode = get_Div_resmode(node);
1430 op1 = get_Mod_left(node);
1431 op2 = get_Mod_right(node);
1432 mem = get_Mod_mem(node);
1433 mode = get_Mod_resmode(node);
1436 op1 = get_DivMod_left(node);
1437 op2 = get_DivMod_right(node);
1438 mem = get_DivMod_mem(node);
1439 mode = get_DivMod_resmode(node);
1442 panic("invalid divmod node %+F", node);
1445 match_arguments(&am, block, op1, op2, NULL, match_am);
1447 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1448 is the memory of the consumed address. We can have only the second op as address
1449 in Div nodes, so check only op2. */
1450 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1452 if (mode_is_signed(mode)) {
1453 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1454 add_irn_dep(produceval, get_irg_frame(irg));
1455 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1458 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1459 addr->index, new_mem, am.new_op2,
1460 am.new_op1, sign_extension);
1462 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1463 add_irn_dep(sign_extension, get_irg_frame(irg));
1465 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1466 addr->index, new_mem, am.new_op2,
1467 am.new_op1, sign_extension);
1470 set_irn_pinned(new_node, get_irn_pinned(node));
1472 set_am_attributes(new_node, &am);
1473 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1475 new_node = fix_mem_proj(new_node, &am);
1481 static ir_node *gen_Mod(ir_node *node) {
1482 return create_Div(node);
1485 static ir_node *gen_Div(ir_node *node) {
1486 return create_Div(node);
1489 static ir_node *gen_DivMod(ir_node *node) {
1490 return create_Div(node);
1496 * Creates an ia32 floating Div.
1498 * @return The created ia32 xDiv node
1500 static ir_node *gen_Quot(ir_node *node)
1502 ir_node *op1 = get_Quot_left(node);
1503 ir_node *op2 = get_Quot_right(node);
1505 if (ia32_cg_config.use_sse2) {
1506 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1508 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1514 * Creates an ia32 Shl.
1516 * @return The created ia32 Shl node
1518 static ir_node *gen_Shl(ir_node *node) {
1519 ir_node *left = get_Shl_left(node);
1520 ir_node *right = get_Shl_right(node);
1522 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1523 match_mode_neutral | match_immediate);
1527 * Creates an ia32 Shr.
1529 * @return The created ia32 Shr node
1531 static ir_node *gen_Shr(ir_node *node) {
1532 ir_node *left = get_Shr_left(node);
1533 ir_node *right = get_Shr_right(node);
1535 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1541 * Creates an ia32 Sar.
1543 * @return The created ia32 Shrs node
1545 static ir_node *gen_Shrs(ir_node *node) {
1546 ir_node *left = get_Shrs_left(node);
1547 ir_node *right = get_Shrs_right(node);
1548 ir_mode *mode = get_irn_mode(node);
1550 if(is_Const(right) && mode == mode_Is) {
1551 tarval *tv = get_Const_tarval(right);
1552 long val = get_tarval_long(tv);
1554 /* this is a sign extension */
1555 ir_graph *irg = current_ir_graph;
1556 dbg_info *dbgi = get_irn_dbg_info(node);
1557 ir_node *block = be_transform_node(get_nodes_block(node));
1559 ir_node *new_op = be_transform_node(op);
1560 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1561 add_irn_dep(pval, get_irg_frame(irg));
1563 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1567 /* 8 or 16 bit sign extension? */
1568 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1569 ir_node *shl_left = get_Shl_left(left);
1570 ir_node *shl_right = get_Shl_right(left);
1571 if(is_Const(shl_right)) {
1572 tarval *tv1 = get_Const_tarval(right);
1573 tarval *tv2 = get_Const_tarval(shl_right);
1574 if(tv1 == tv2 && tarval_is_long(tv1)) {
1575 long val = get_tarval_long(tv1);
1576 if(val == 16 || val == 24) {
1577 dbg_info *dbgi = get_irn_dbg_info(node);
1578 ir_node *block = get_nodes_block(node);
1588 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1597 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1603 * Creates an ia32 Rol.
1605 * @param op1 The first operator
1606 * @param op2 The second operator
1607 * @return The created ia32 RotL node
1609 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1610 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1616 * Creates an ia32 Ror.
1617 * NOTE: There is no RotR with immediate because this would always be a RotL
1618 * "imm-mode_size_bits" which can be pre-calculated.
1620 * @param op1 The first operator
1621 * @param op2 The second operator
1622 * @return The created ia32 RotR node
1624 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1625 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1631 * Creates an ia32 RotR or RotL (depending on the found pattern).
1633 * @return The created ia32 RotL or RotR node
1635 static ir_node *gen_Rotl(ir_node *node) {
1636 ir_node *rotate = NULL;
1637 ir_node *op1 = get_Rotl_left(node);
1638 ir_node *op2 = get_Rotl_right(node);
1640 /* Firm has only RotL, so we are looking for a right (op2)
1641 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1642 that means we can create a RotR instead of an Add and a RotL */
1646 ir_node *left = get_Add_left(add);
1647 ir_node *right = get_Add_right(add);
1648 if (is_Const(right)) {
1649 tarval *tv = get_Const_tarval(right);
1650 ir_mode *mode = get_irn_mode(node);
1651 long bits = get_mode_size_bits(mode);
1653 if (is_Minus(left) &&
1654 tarval_is_long(tv) &&
1655 get_tarval_long(tv) == bits &&
1658 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1659 rotate = gen_Ror(node, op1, get_Minus_op(left));
1664 if (rotate == NULL) {
1665 rotate = gen_Rol(node, op1, op2);
1674 * Transforms a Minus node.
1676 * @return The created ia32 Minus node
1678 static ir_node *gen_Minus(ir_node *node)
1680 ir_node *op = get_Minus_op(node);
1681 ir_node *block = be_transform_node(get_nodes_block(node));
1682 ir_graph *irg = current_ir_graph;
1683 dbg_info *dbgi = get_irn_dbg_info(node);
1684 ir_mode *mode = get_irn_mode(node);
1689 if (mode_is_float(mode)) {
1690 ir_node *new_op = be_transform_node(op);
1691 if (ia32_cg_config.use_sse2) {
1692 /* TODO: non-optimal... if we have many xXors, then we should
1693 * rather create a load for the const and use that instead of
1694 * several AM nodes... */
1695 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1696 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1697 ir_node *nomem = new_rd_NoMem(irg);
1699 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1700 nomem, new_op, noreg_xmm);
1702 size = get_mode_size_bits(mode);
1703 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1705 set_ia32_am_sc(new_node, ent);
1706 set_ia32_op_type(new_node, ia32_AddrModeS);
1707 set_ia32_ls_mode(new_node, mode);
1709 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1712 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1715 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1721 * Transforms a Not node.
1723 * @return The created ia32 Not node
1725 static ir_node *gen_Not(ir_node *node) {
1726 ir_node *op = get_Not_op(node);
1728 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1729 assert (! mode_is_float(get_irn_mode(node)));
1731 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1737 * Transforms an Abs node.
1739 * @return The created ia32 Abs node
1741 static ir_node *gen_Abs(ir_node *node)
1743 ir_node *block = get_nodes_block(node);
1744 ir_node *new_block = be_transform_node(block);
1745 ir_node *op = get_Abs_op(node);
1746 ir_graph *irg = current_ir_graph;
1747 dbg_info *dbgi = get_irn_dbg_info(node);
1748 ir_mode *mode = get_irn_mode(node);
1749 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1750 ir_node *nomem = new_NoMem();
1756 if (mode_is_float(mode)) {
1757 new_op = be_transform_node(op);
1759 if (ia32_cg_config.use_sse2) {
1760 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1761 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1762 nomem, new_op, noreg_fp);
1764 size = get_mode_size_bits(mode);
1765 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1767 set_ia32_am_sc(new_node, ent);
1769 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1771 set_ia32_op_type(new_node, ia32_AddrModeS);
1772 set_ia32_ls_mode(new_node, mode);
1774 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1775 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1778 ir_node *xor, *pval, *sign_extension;
1780 if (get_mode_size_bits(mode) == 32) {
1781 new_op = be_transform_node(op);
1783 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1786 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1787 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1790 add_irn_dep(pval, get_irg_frame(irg));
1791 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1793 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1794 nomem, new_op, sign_extension);
1795 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1797 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1798 nomem, xor, sign_extension);
1799 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1806 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1808 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1809 dbg_info *dbgi = get_irn_dbg_info(cmp);
1810 ir_node *block = get_nodes_block(cmp);
1811 ir_node *new_block = be_transform_node(block);
1812 ir_node *op1 = be_transform_node(x);
1813 ir_node *op2 = be_transform_node(n);
1815 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1819 * Transform a node returning a "flag" result.
1821 * @param node the node to transform
1822 * @param pnc_out the compare mode to use
1824 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1833 /* we have a Cmp as input */
1834 if (is_Proj(node)) {
1835 ir_node *pred = get_Proj_pred(node);
1837 pn_Cmp pnc = get_Proj_proj(node);
1838 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1839 ir_node *l = get_Cmp_left(pred);
1840 ir_node *r = get_Cmp_right(pred);
1842 ir_node *la = get_And_left(l);
1843 ir_node *ra = get_And_right(l);
1845 ir_node *c = get_Shl_left(la);
1846 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1847 /* (1 << n) & ra) */
1848 ir_node *n = get_Shl_right(la);
1849 flags = gen_bt(pred, ra, n);
1850 /* we must generate a Jc/Jnc jump */
1851 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1854 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1859 ir_node *c = get_Shl_left(ra);
1860 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1861 /* la & (1 << n)) */
1862 ir_node *n = get_Shl_right(ra);
1863 flags = gen_bt(pred, la, n);
1864 /* we must generate a Jc/Jnc jump */
1865 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1868 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1874 flags = be_transform_node(pred);
1880 /* a mode_b value, we have to compare it against 0 */
1881 dbgi = get_irn_dbg_info(node);
1882 new_block = be_transform_node(get_nodes_block(node));
1883 new_op = be_transform_node(node);
1884 noreg = ia32_new_NoReg_gp(env_cg);
1885 nomem = new_NoMem();
1886 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1887 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1888 *pnc_out = pn_Cmp_Lg;
1893 * Transforms a Load.
1895 * @return the created ia32 Load node
1897 static ir_node *gen_Load(ir_node *node) {
1898 ir_node *old_block = get_nodes_block(node);
1899 ir_node *block = be_transform_node(old_block);
1900 ir_node *ptr = get_Load_ptr(node);
1901 ir_node *mem = get_Load_mem(node);
1902 ir_node *new_mem = be_transform_node(mem);
1905 ir_graph *irg = current_ir_graph;
1906 dbg_info *dbgi = get_irn_dbg_info(node);
1907 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1908 ir_mode *mode = get_Load_mode(node);
1911 ia32_address_t addr;
1913 /* construct load address */
1914 memset(&addr, 0, sizeof(addr));
1915 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1922 base = be_transform_node(base);
1928 index = be_transform_node(index);
1931 if (mode_is_float(mode)) {
1932 if (ia32_cg_config.use_sse2) {
1933 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1935 res_mode = mode_xmm;
1937 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1939 res_mode = mode_vfp;
1942 assert(mode != mode_b);
1944 /* create a conv node with address mode for smaller modes */
1945 if(get_mode_size_bits(mode) < 32) {
1946 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1947 new_mem, noreg, mode);
1949 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1954 set_irn_pinned(new_node, get_irn_pinned(node));
1955 set_ia32_op_type(new_node, ia32_AddrModeS);
1956 set_ia32_ls_mode(new_node, mode);
1957 set_address(new_node, &addr);
1959 if(get_irn_pinned(node) == op_pin_state_floats) {
1960 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1963 /* make sure we are scheduled behind the initial IncSP/Barrier
1964 * to avoid spills being placed before it
1966 if (block == get_irg_start_block(irg)) {
1967 add_irn_dep(new_node, get_irg_frame(irg));
1970 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1975 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1976 ir_node *ptr, ir_node *other)
1983 /* we only use address mode if we're the only user of the load */
1984 if (get_irn_n_edges(node) > 1)
1987 load = get_Proj_pred(node);
1990 if (get_nodes_block(load) != block)
1993 /* store should have the same pointer as the load */
1994 if (get_Load_ptr(load) != ptr)
1997 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1998 if (other != NULL &&
1999 get_nodes_block(other) == block &&
2000 heights_reachable_in_block(heights, other, load)) {
2007 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
2008 ir_node *const pred = get_Sync_pred(mem, i);
2010 if (is_Proj(pred) && get_Proj_pred(pred) == load)
2013 if (get_nodes_block(pred) == block &&
2014 heights_reachable_in_block(heights, pred, load)) {
2019 /* Store should be attached to the load */
2020 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
2027 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
2029 mark_irn_visited(old_node);
2030 be_set_transformed_node(old_node, new_node);
2033 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2034 ir_node *mem, ir_node *ptr, ir_mode *mode,
2035 construct_binop_dest_func *func,
2036 construct_binop_dest_func *func8bit,
2037 match_flags_t flags)
2039 ir_node *src_block = get_nodes_block(node);
2041 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2042 ir_graph *irg = current_ir_graph;
2049 ia32_address_mode_t am;
2050 ia32_address_t *addr = &am.addr;
2051 memset(&am, 0, sizeof(am));
2053 assert(flags & match_dest_am);
2054 assert(flags & match_immediate); /* there is no destam node without... */
2055 commutative = (flags & match_commutative) != 0;
2057 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2058 build_address(&am, op1);
2059 new_op = create_immediate_or_transform(op2, 0);
2060 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2061 build_address(&am, op2);
2062 new_op = create_immediate_or_transform(op1, 0);
2067 if(addr->base == NULL)
2068 addr->base = noreg_gp;
2069 if(addr->index == NULL)
2070 addr->index = noreg_gp;
2071 if(addr->mem == NULL)
2072 addr->mem = new_NoMem();
2074 dbgi = get_irn_dbg_info(node);
2075 block = be_transform_node(src_block);
2076 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2078 if(get_mode_size_bits(mode) == 8) {
2079 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2082 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
2085 set_address(new_node, addr);
2086 set_ia32_op_type(new_node, ia32_AddrModeD);
2087 set_ia32_ls_mode(new_node, mode);
2088 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2090 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2091 mem_proj = be_transform_node(am.mem_proj);
2092 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2097 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2098 ir_node *ptr, ir_mode *mode,
2099 construct_unop_dest_func *func)
2101 ir_graph *irg = current_ir_graph;
2102 ir_node *src_block = get_nodes_block(node);
2108 ia32_address_mode_t am;
2109 ia32_address_t *addr = &am.addr;
2110 memset(&am, 0, sizeof(am));
2112 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2115 build_address(&am, op);
2117 dbgi = get_irn_dbg_info(node);
2118 block = be_transform_node(src_block);
2119 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2120 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2121 set_address(new_node, addr);
2122 set_ia32_op_type(new_node, ia32_AddrModeD);
2123 set_ia32_ls_mode(new_node, mode);
2124 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2126 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2127 mem_proj = be_transform_node(am.mem_proj);
2128 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2133 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2134 ir_mode *mode = get_irn_mode(node);
2135 ir_node *mux_true = get_Mux_true(node);
2136 ir_node *mux_false = get_Mux_false(node);
2147 ia32_address_t addr;
2149 if(get_mode_size_bits(mode) != 8)
2152 if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2154 } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2160 build_address_ptr(&addr, ptr, mem);
2162 irg = current_ir_graph;
2163 dbgi = get_irn_dbg_info(node);
2164 block = get_nodes_block(node);
2165 new_block = be_transform_node(block);
2166 cond = get_Mux_sel(node);
2167 flags = get_flags_node(cond, &pnc);
2168 new_mem = be_transform_node(mem);
2169 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2170 addr.index, addr.mem, flags, pnc, negated);
2171 set_address(new_node, &addr);
2172 set_ia32_op_type(new_node, ia32_AddrModeD);
2173 set_ia32_ls_mode(new_node, mode);
2174 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2179 static ir_node *try_create_dest_am(ir_node *node) {
2180 ir_node *val = get_Store_value(node);
2181 ir_node *mem = get_Store_mem(node);
2182 ir_node *ptr = get_Store_ptr(node);
2183 ir_mode *mode = get_irn_mode(val);
2184 unsigned bits = get_mode_size_bits(mode);
2189 /* handle only GP modes for now... */
2190 if(!ia32_mode_needs_gp_reg(mode))
2194 /* store must be the only user of the val node */
2195 if(get_irn_n_edges(val) > 1)
2197 /* skip pointless convs */
2199 ir_node *conv_op = get_Conv_op(val);
2200 ir_mode *pred_mode = get_irn_mode(conv_op);
2201 if (!ia32_mode_needs_gp_reg(pred_mode))
2203 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2211 /* value must be in the same block */
2212 if(get_nodes_block(node) != get_nodes_block(val))
2215 switch (get_irn_opcode(val)) {
2217 op1 = get_Add_left(val);
2218 op2 = get_Add_right(val);
2219 if(is_Const_1(op2)) {
2220 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2221 new_rd_ia32_IncMem);
2223 } else if(is_Const_Minus_1(op2)) {
2224 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2225 new_rd_ia32_DecMem);
2228 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2229 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2230 match_dest_am | match_commutative |
2234 op1 = get_Sub_left(val);
2235 op2 = get_Sub_right(val);
2236 if (is_Const(op2)) {
2237 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2239 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2240 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2241 match_dest_am | match_immediate |
2245 op1 = get_And_left(val);
2246 op2 = get_And_right(val);
2247 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2248 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2249 match_dest_am | match_commutative |
2253 op1 = get_Or_left(val);
2254 op2 = get_Or_right(val);
2255 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2256 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2257 match_dest_am | match_commutative |
2261 op1 = get_Eor_left(val);
2262 op2 = get_Eor_right(val);
2263 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2264 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2265 match_dest_am | match_commutative |
2269 op1 = get_Shl_left(val);
2270 op2 = get_Shl_right(val);
2271 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2272 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2273 match_dest_am | match_immediate);
2276 op1 = get_Shr_left(val);
2277 op2 = get_Shr_right(val);
2278 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2279 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2280 match_dest_am | match_immediate);
2283 op1 = get_Shrs_left(val);
2284 op2 = get_Shrs_right(val);
2285 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2286 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2287 match_dest_am | match_immediate);
2290 op1 = get_Rotl_left(val);
2291 op2 = get_Rotl_right(val);
2292 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2293 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2294 match_dest_am | match_immediate);
2296 /* TODO: match ROR patterns... */
2298 new_node = try_create_SetMem(val, ptr, mem);
2301 op1 = get_Minus_op(val);
2302 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2305 /* should be lowered already */
2306 assert(mode != mode_b);
2307 op1 = get_Not_op(val);
2308 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2314 if(new_node != NULL) {
2315 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2316 get_irn_pinned(node) == op_pin_state_pinned) {
2317 set_irn_pinned(new_node, op_pin_state_pinned);
2324 static int is_float_to_int32_conv(const ir_node *node)
2326 ir_mode *mode = get_irn_mode(node);
2330 if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode))
2332 /* don't report unsigned as conv to 32bit, because we really need to do
2333 * a vfist with 64bit signed in this case */
2334 if(!mode_is_signed(mode))
2339 conv_op = get_Conv_op(node);
2340 conv_mode = get_irn_mode(conv_op);
2342 if(!mode_is_float(conv_mode))
2349 * Transform a Store(floatConst).
2351 * @return the created ia32 Store node
2353 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2355 ir_mode *mode = get_irn_mode(cns);
2356 unsigned size = get_mode_size_bytes(mode);
2357 tarval *tv = get_Const_tarval(cns);
2358 ir_node *block = get_nodes_block(node);
2359 ir_node *new_block = be_transform_node(block);
2360 ir_node *ptr = get_Store_ptr(node);
2361 ir_node *mem = get_Store_mem(node);
2362 ir_graph *irg = current_ir_graph;
2363 dbg_info *dbgi = get_irn_dbg_info(node);
2367 ia32_address_t addr;
2369 assert(size % 4 == 0);
2372 build_address_ptr(&addr, ptr, mem);
2376 get_tarval_sub_bits(tv, ofs) |
2377 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2378 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2379 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2380 ir_node *imm = create_Immediate(NULL, 0, val);
2382 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2383 addr.index, addr.mem, imm);
2385 set_irn_pinned(new_node, get_irn_pinned(node));
2386 set_ia32_op_type(new_node, ia32_AddrModeD);
2387 set_ia32_ls_mode(new_node, mode_Iu);
2388 set_address(new_node, &addr);
2389 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2391 ins[i++] = new_node;
2396 } while (size != 0);
2398 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2402 * Generate a vfist or vfisttp instruction.
2404 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2405 ir_node *mem, ir_node *val, ir_node **fist)
2409 if (ia32_cg_config.use_fisttp) {
2410 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2411 if other users exists */
2412 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2413 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2414 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2415 be_new_Keep(reg_class, irg, block, 1, &value);
2417 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2420 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2423 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2429 * Transforms a normal Store.
2431 * @return the created ia32 Store node
2433 static ir_node *gen_normal_Store(ir_node *node)
2435 ir_node *val = get_Store_value(node);
2436 ir_mode *mode = get_irn_mode(val);
2437 ir_node *block = get_nodes_block(node);
2438 ir_node *new_block = be_transform_node(block);
2439 ir_node *ptr = get_Store_ptr(node);
2440 ir_node *mem = get_Store_mem(node);
2441 ir_graph *irg = current_ir_graph;
2442 dbg_info *dbgi = get_irn_dbg_info(node);
2443 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2444 ir_node *new_val, *new_node, *store;
2445 ia32_address_t addr;
2447 /* check for destination address mode */
2448 new_node = try_create_dest_am(node);
2449 if (new_node != NULL)
2452 /* construct store address */
2453 memset(&addr, 0, sizeof(addr));
2454 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2456 if (addr.base == NULL) {
2459 addr.base = be_transform_node(addr.base);
2462 if (addr.index == NULL) {
2465 addr.index = be_transform_node(addr.index);
2467 addr.mem = be_transform_node(mem);
2469 if (mode_is_float(mode)) {
2470 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2472 while (is_Conv(val) && mode == get_irn_mode(val)) {
2473 ir_node *op = get_Conv_op(val);
2474 if (!mode_is_float(get_irn_mode(op)))
2478 new_val = be_transform_node(val);
2479 if (ia32_cg_config.use_sse2) {
2480 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2481 addr.index, addr.mem, new_val);
2483 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2484 addr.index, addr.mem, new_val, mode);
2487 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2488 val = get_Conv_op(val);
2490 /* TODO: is this optimisation still necessary at all (middleend)? */
2491 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2492 while (is_Conv(val)) {
2493 ir_node *op = get_Conv_op(val);
2494 if (!mode_is_float(get_irn_mode(op)))
2496 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2500 new_val = be_transform_node(val);
2501 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2503 new_val = create_immediate_or_transform(val, 0);
2504 assert(mode != mode_b);
2506 if (get_mode_size_bits(mode) == 8) {
2507 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2508 addr.index, addr.mem, new_val);
2510 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2511 addr.index, addr.mem, new_val);
2516 set_irn_pinned(store, get_irn_pinned(node));
2517 set_ia32_op_type(store, ia32_AddrModeD);
2518 set_ia32_ls_mode(store, mode);
2520 set_address(store, &addr);
2521 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2527 * Transforms a Store.
2529 * @return the created ia32 Store node
2531 static ir_node *gen_Store(ir_node *node)
2533 ir_node *val = get_Store_value(node);
2534 ir_mode *mode = get_irn_mode(val);
2536 if (mode_is_float(mode) && is_Const(val)) {
2539 /* we are storing a floating point constant */
2540 if (ia32_cg_config.use_sse2) {
2541 transform = !is_simple_sse_Const(val);
2543 transform = !is_simple_x87_Const(val);
2546 return gen_float_const_Store(node, val);
2548 return gen_normal_Store(node);
2552 * Transforms a Switch.
2554 * @return the created ia32 SwitchJmp node
2556 static ir_node *create_Switch(ir_node *node)
2558 ir_graph *irg = current_ir_graph;
2559 dbg_info *dbgi = get_irn_dbg_info(node);
2560 ir_node *block = be_transform_node(get_nodes_block(node));
2561 ir_node *sel = get_Cond_selector(node);
2562 ir_node *new_sel = be_transform_node(sel);
2563 int switch_min = INT_MAX;
2564 int switch_max = INT_MIN;
2565 long default_pn = get_Cond_defaultProj(node);
2567 const ir_edge_t *edge;
2569 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2571 /* determine the smallest switch case value */
2572 foreach_out_edge(node, edge) {
2573 ir_node *proj = get_edge_src_irn(edge);
2574 long pn = get_Proj_proj(proj);
2575 if(pn == default_pn)
2584 if((unsigned) (switch_max - switch_min) > 256000) {
2585 panic("Size of switch %+F bigger than 256000", node);
2588 if (switch_min != 0) {
2589 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2591 /* if smallest switch case is not 0 we need an additional sub */
2592 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2593 add_ia32_am_offs_int(new_sel, -switch_min);
2594 set_ia32_op_type(new_sel, ia32_AddrModeS);
2596 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2599 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2600 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2606 * Transform a Cond node.
2608 static ir_node *gen_Cond(ir_node *node) {
2609 ir_node *block = get_nodes_block(node);
2610 ir_node *new_block = be_transform_node(block);
2611 ir_graph *irg = current_ir_graph;
2612 dbg_info *dbgi = get_irn_dbg_info(node);
2613 ir_node *sel = get_Cond_selector(node);
2614 ir_mode *sel_mode = get_irn_mode(sel);
2615 ir_node *flags = NULL;
2619 if (sel_mode != mode_b) {
2620 return create_Switch(node);
2623 /* we get flags from a Cmp */
2624 flags = get_flags_node(sel, &pnc);
2626 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2627 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2632 static ir_node *gen_be_Copy(ir_node *node)
2634 ir_node *new_node = be_duplicate_node(node);
2635 ir_mode *mode = get_irn_mode(new_node);
2637 if (ia32_mode_needs_gp_reg(mode)) {
2638 set_irn_mode(new_node, mode_Iu);
2644 static ir_node *create_Fucom(ir_node *node)
2646 ir_graph *irg = current_ir_graph;
2647 dbg_info *dbgi = get_irn_dbg_info(node);
2648 ir_node *block = get_nodes_block(node);
2649 ir_node *new_block = be_transform_node(block);
2650 ir_node *left = get_Cmp_left(node);
2651 ir_node *new_left = be_transform_node(left);
2652 ir_node *right = get_Cmp_right(node);
2656 if(ia32_cg_config.use_fucomi) {
2657 new_right = be_transform_node(right);
2658 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2660 set_ia32_commutative(new_node);
2661 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2663 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2664 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2667 new_right = be_transform_node(right);
2668 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2672 set_ia32_commutative(new_node);
2674 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2676 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2677 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2683 static ir_node *create_Ucomi(ir_node *node)
2685 ir_graph *irg = current_ir_graph;
2686 dbg_info *dbgi = get_irn_dbg_info(node);
2687 ir_node *src_block = get_nodes_block(node);
2688 ir_node *new_block = be_transform_node(src_block);
2689 ir_node *left = get_Cmp_left(node);
2690 ir_node *right = get_Cmp_right(node);
2692 ia32_address_mode_t am;
2693 ia32_address_t *addr = &am.addr;
2695 match_arguments(&am, src_block, left, right, NULL,
2696 match_commutative | match_am);
2698 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2699 addr->mem, am.new_op1, am.new_op2,
2701 set_am_attributes(new_node, &am);
2703 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2705 new_node = fix_mem_proj(new_node, &am);
2711 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2712 * to fold an and into a test node
2714 static bool can_fold_test_and(ir_node *node)
2716 const ir_edge_t *edge;
2718 /** we can only have eq and lg projs */
2719 foreach_out_edge(node, edge) {
2720 ir_node *proj = get_edge_src_irn(edge);
2721 pn_Cmp pnc = get_Proj_proj(proj);
2722 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2730 * returns true if it is assured, that the upper bits of a node are "clean"
2731 * which means for a 16 or 8 bit value, that the upper bits in the register
2732 * are 0 for unsigned and a copy of the last significant bit for unsigned
2735 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2737 assert(ia32_mode_needs_gp_reg(mode));
2738 if (get_mode_size_bits(mode) >= 32)
2741 if (is_ia32_Conv_I2I(transformed_node)
2742 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2743 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2744 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2746 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2752 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2753 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2754 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2755 const ia32_immediate_attr_t *attr
2756 = get_ia32_immediate_attr_const(right);
2757 if (attr->symconst == 0
2758 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2764 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2765 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2766 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2767 const ia32_immediate_attr_t *attr
2768 = get_ia32_immediate_attr_const(right);
2769 if (attr->symconst == 0
2770 && (unsigned) attr->offset
2771 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2777 if (is_ia32_Immediate(transformed_node)
2778 || is_ia32_Const(transformed_node)) {
2779 const ia32_immediate_attr_t *attr
2780 = get_ia32_immediate_attr_const(transformed_node);
2781 if (mode_is_signed(mode)) {
2782 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2783 if (shifted == 0 || shifted == -1)
2786 unsigned long shifted = (unsigned long) attr->offset;
2787 shifted >>= get_mode_size_bits(mode);
2797 * Generate code for a Cmp.
2799 static ir_node *gen_Cmp(ir_node *node)
2801 ir_graph *irg = current_ir_graph;
2802 dbg_info *dbgi = get_irn_dbg_info(node);
2803 ir_node *block = get_nodes_block(node);
2804 ir_node *new_block = be_transform_node(block);
2805 ir_node *left = get_Cmp_left(node);
2806 ir_node *right = get_Cmp_right(node);
2807 ir_mode *cmp_mode = get_irn_mode(left);
2809 ia32_address_mode_t am;
2810 ia32_address_t *addr = &am.addr;
2813 if(mode_is_float(cmp_mode)) {
2814 if (ia32_cg_config.use_sse2) {
2815 return create_Ucomi(node);
2817 return create_Fucom(node);
2821 assert(ia32_mode_needs_gp_reg(cmp_mode));
2823 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2824 cmp_unsigned = !mode_is_signed(cmp_mode);
2825 if (is_Const_0(right) &&
2827 get_irn_n_edges(left) == 1 &&
2828 can_fold_test_and(node)) {
2829 /* Test(and_left, and_right) */
2830 ir_node *and_left = get_And_left(left);
2831 ir_node *and_right = get_And_right(left);
2832 ir_mode *mode = get_irn_mode(and_left);
2834 /* matze: code here used mode instead of cmd_mode, I think it is always
2835 * the same as cmp_mode, but I leave this here to see if this is really
2838 assert(mode == cmp_mode);
2840 match_arguments(&am, block, and_left, and_right, NULL,
2842 match_am | match_8bit_am | match_16bit_am |
2843 match_am_and_immediates | match_immediate |
2844 match_8bit | match_16bit);
2846 /* use 32bit compare mode if possible since the opcode is smaller */
2847 if (upper_bits_clean(am.new_op1, cmp_mode)
2848 && upper_bits_clean(am.new_op2, cmp_mode)) {
2849 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2852 if (get_mode_size_bits(cmp_mode) == 8) {
2853 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2854 addr->index, addr->mem, am.new_op1,
2855 am.new_op2, am.ins_permuted,
2858 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2859 addr->index, addr->mem, am.new_op1,
2860 am.new_op2, am.ins_permuted,
2864 /* Cmp(left, right) */
2865 match_arguments(&am, block, left, right, NULL,
2866 match_commutative | match_am | match_8bit_am |
2867 match_16bit_am | match_am_and_immediates |
2868 match_immediate | match_8bit | match_16bit);
2869 /* use 32bit compare mode if possible since the opcode is smaller */
2870 if (upper_bits_clean(am.new_op1, cmp_mode)
2871 && upper_bits_clean(am.new_op2, cmp_mode)) {
2872 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2875 if (get_mode_size_bits(cmp_mode) == 8) {
2876 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2877 addr->index, addr->mem, am.new_op1,
2878 am.new_op2, am.ins_permuted,
2881 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2882 addr->index, addr->mem, am.new_op1,
2883 am.new_op2, am.ins_permuted, cmp_unsigned);
2886 set_am_attributes(new_node, &am);
2887 set_ia32_ls_mode(new_node, cmp_mode);
2889 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2891 new_node = fix_mem_proj(new_node, &am);
2896 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2899 ir_graph *irg = current_ir_graph;
2900 dbg_info *dbgi = get_irn_dbg_info(node);
2901 ir_node *block = get_nodes_block(node);
2902 ir_node *new_block = be_transform_node(block);
2903 ir_node *val_true = get_Mux_true(node);
2904 ir_node *val_false = get_Mux_false(node);
2906 match_flags_t match_flags;
2907 ia32_address_mode_t am;
2908 ia32_address_t *addr;
2910 assert(ia32_cg_config.use_cmov);
2911 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2915 match_flags = match_commutative | match_am | match_16bit_am |
2918 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2920 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2921 addr->mem, am.new_op1, am.new_op2, new_flags,
2922 am.ins_permuted, pnc);
2923 set_am_attributes(new_node, &am);
2925 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2927 new_node = fix_mem_proj(new_node, &am);
2933 * Creates a ia32 Setcc instruction.
2935 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2936 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2939 ir_graph *irg = current_ir_graph;
2940 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2941 ir_node *nomem = new_NoMem();
2942 ir_mode *mode = get_irn_mode(orig_node);
2945 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2946 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2948 /* we might need to conv the result up */
2949 if (get_mode_size_bits(mode) > 8) {
2950 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2951 nomem, new_node, mode_Bu);
2952 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2959 * Create instruction for an unsigned Difference or Zero.
2961 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2962 ir_graph *irg = current_ir_graph;
2963 ir_mode *mode = get_irn_mode(psi);
2964 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2967 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2968 match_mode_neutral | match_am | match_immediate | match_two_users);
2970 block = get_nodes_block(new_node);
2972 if (is_Proj(new_node)) {
2973 sub = get_Proj_pred(new_node);
2974 assert(is_ia32_Sub(sub));
2977 set_irn_mode(sub, mode_T);
2978 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2980 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2982 dbgi = get_irn_dbg_info(psi);
2983 noreg = ia32_new_NoReg_gp(env_cg);
2984 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2985 nomem = new_NoMem();
2986 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2988 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2989 set_ia32_commutative(new_node);
2994 * Transforms a Mux node into CMov.
2996 * @return The transformed node.
2998 static ir_node *gen_Mux(ir_node *node)
3000 dbg_info *dbgi = get_irn_dbg_info(node);
3001 ir_node *block = get_nodes_block(node);
3002 ir_node *new_block = be_transform_node(block);
3003 ir_node *mux_true = get_Mux_true(node);
3004 ir_node *mux_false = get_Mux_false(node);
3005 ir_node *cond = get_Mux_sel(node);
3006 ir_mode *mode = get_irn_mode(node);
3009 assert(get_irn_mode(cond) == mode_b);
3011 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3012 if (mode_is_float(mode)) {
3013 ir_node *cmp = get_Proj_pred(cond);
3014 ir_node *cmp_left = get_Cmp_left(cmp);
3015 ir_node *cmp_right = get_Cmp_right(cmp);
3016 pn_Cmp pnc = get_Proj_proj(cond);
3018 if (ia32_cg_config.use_sse2) {
3019 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3020 if (cmp_left == mux_true && cmp_right == mux_false) {
3021 /* Mux(a <= b, a, b) => MIN */
3022 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3023 match_commutative | match_am | match_two_users);
3024 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3025 /* Mux(a <= b, b, a) => MAX */
3026 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3027 match_commutative | match_am | match_two_users);
3029 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3030 if (cmp_left == mux_true && cmp_right == mux_false) {
3031 /* Mux(a >= b, a, b) => MAX */
3032 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3033 match_commutative | match_am | match_two_users);
3034 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3035 /* Mux(a >= b, b, a) => MIN */
3036 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3037 match_commutative | match_am | match_two_users);
3041 panic("cannot transform floating point Mux");
3047 assert(ia32_mode_needs_gp_reg(mode));
3049 if (is_Proj(cond)) {
3050 ir_node *cmp = get_Proj_pred(cond);
3052 ir_node *cmp_left = get_Cmp_left(cmp);
3053 ir_node *cmp_right = get_Cmp_right(cmp);
3054 pn_Cmp pnc = get_Proj_proj(cond);
3056 /* check for unsigned Doz first */
3057 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3058 is_Const_0(mux_false) && is_Sub(mux_true) &&
3059 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3060 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3061 return create_Doz(node, cmp_left, cmp_right);
3062 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3063 is_Const_0(mux_true) && is_Sub(mux_false) &&
3064 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3065 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3066 return create_Doz(node, cmp_left, cmp_right);
3071 flags = get_flags_node(cond, &pnc);
3073 if (is_Const(mux_true) && is_Const(mux_false)) {
3074 /* both are const, good */
3075 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3076 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3077 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3078 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3080 /* Not that simple. */
3085 new_node = create_CMov(node, cond, flags, pnc);
3093 * Create a conversion from x87 state register to general purpose.
3095 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3096 ir_node *block = be_transform_node(get_nodes_block(node));
3097 ir_node *op = get_Conv_op(node);
3098 ir_node *new_op = be_transform_node(op);
3099 ia32_code_gen_t *cg = env_cg;
3100 ir_graph *irg = current_ir_graph;
3101 dbg_info *dbgi = get_irn_dbg_info(node);
3102 ir_node *noreg = ia32_new_NoReg_gp(cg);
3103 ir_mode *mode = get_irn_mode(node);
3104 ir_node *fist, *load, *mem;
3106 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3107 set_irn_pinned(fist, op_pin_state_floats);
3108 set_ia32_use_frame(fist);
3109 set_ia32_op_type(fist, ia32_AddrModeD);
3111 assert(get_mode_size_bits(mode) <= 32);
3112 /* exception we can only store signed 32 bit integers, so for unsigned
3113 we store a 64bit (signed) integer and load the lower bits */
3114 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3115 set_ia32_ls_mode(fist, mode_Ls);
3117 set_ia32_ls_mode(fist, mode_Is);
3119 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3122 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3124 set_irn_pinned(load, op_pin_state_floats);
3125 set_ia32_use_frame(load);
3126 set_ia32_op_type(load, ia32_AddrModeS);
3127 set_ia32_ls_mode(load, mode_Is);
3128 if(get_ia32_ls_mode(fist) == mode_Ls) {
3129 ia32_attr_t *attr = get_ia32_attr(load);
3130 attr->data.need_64bit_stackent = 1;
3132 ia32_attr_t *attr = get_ia32_attr(load);
3133 attr->data.need_32bit_stackent = 1;
3135 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3137 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3141 * Creates a x87 strict Conv by placing a Store and a Load
3143 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3145 ir_node *block = get_nodes_block(node);
3146 ir_graph *irg = current_ir_graph;
3147 dbg_info *dbgi = get_irn_dbg_info(node);
3148 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3149 ir_node *nomem = new_NoMem();
3150 ir_node *frame = get_irg_frame(irg);
3151 ir_node *store, *load;
3154 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3156 set_ia32_use_frame(store);
3157 set_ia32_op_type(store, ia32_AddrModeD);
3158 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3160 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3162 set_ia32_use_frame(load);
3163 set_ia32_op_type(load, ia32_AddrModeS);
3164 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3166 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3171 * Create a conversion from general purpose to x87 register
3173 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3174 ir_node *src_block = get_nodes_block(node);
3175 ir_node *block = be_transform_node(src_block);
3176 ir_graph *irg = current_ir_graph;
3177 dbg_info *dbgi = get_irn_dbg_info(node);
3178 ir_node *op = get_Conv_op(node);
3179 ir_node *new_op = NULL;
3183 ir_mode *store_mode;
3189 /* fild can use source AM if the operand is a signed 32bit integer */
3190 if (src_mode == mode_Is) {
3191 ia32_address_mode_t am;
3193 match_arguments(&am, src_block, NULL, op, NULL,
3194 match_am | match_try_am);
3195 if (am.op_type == ia32_AddrModeS) {
3196 ia32_address_t *addr = &am.addr;
3198 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3199 addr->index, addr->mem);
3200 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3203 set_am_attributes(fild, &am);
3204 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3206 fix_mem_proj(fild, &am);
3211 if(new_op == NULL) {
3212 new_op = be_transform_node(op);
3215 noreg = ia32_new_NoReg_gp(env_cg);
3216 nomem = new_NoMem();
3217 mode = get_irn_mode(op);
3219 /* first convert to 32 bit signed if necessary */
3220 src_bits = get_mode_size_bits(src_mode);
3221 if (src_bits == 8) {
3222 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3224 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3226 } else if (src_bits < 32) {
3227 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3229 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3233 assert(get_mode_size_bits(mode) == 32);
3236 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3239 set_ia32_use_frame(store);
3240 set_ia32_op_type(store, ia32_AddrModeD);
3241 set_ia32_ls_mode(store, mode_Iu);
3243 /* exception for 32bit unsigned, do a 64bit spill+load */
3244 if(!mode_is_signed(mode)) {
3247 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3249 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3250 get_irg_frame(irg), noreg, nomem,
3253 set_ia32_use_frame(zero_store);
3254 set_ia32_op_type(zero_store, ia32_AddrModeD);
3255 add_ia32_am_offs_int(zero_store, 4);
3256 set_ia32_ls_mode(zero_store, mode_Iu);
3261 store = new_rd_Sync(dbgi, irg, block, 2, in);
3262 store_mode = mode_Ls;
3264 store_mode = mode_Is;
3268 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3270 set_ia32_use_frame(fild);
3271 set_ia32_op_type(fild, ia32_AddrModeS);
3272 set_ia32_ls_mode(fild, store_mode);
3274 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3280 * Create a conversion from one integer mode into another one
3282 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3283 dbg_info *dbgi, ir_node *block, ir_node *op,
3286 ir_graph *irg = current_ir_graph;
3287 int src_bits = get_mode_size_bits(src_mode);
3288 int tgt_bits = get_mode_size_bits(tgt_mode);
3289 ir_node *new_block = be_transform_node(block);
3291 ir_mode *smaller_mode;
3293 ia32_address_mode_t am;
3294 ia32_address_t *addr = &am.addr;
3297 if (src_bits < tgt_bits) {
3298 smaller_mode = src_mode;
3299 smaller_bits = src_bits;
3301 smaller_mode = tgt_mode;
3302 smaller_bits = tgt_bits;
3305 #ifdef DEBUG_libfirm
3307 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3312 match_arguments(&am, block, NULL, op, NULL,
3313 match_8bit | match_16bit |
3314 match_am | match_8bit_am | match_16bit_am);
3316 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3317 /* unnecessary conv. in theory it shouldn't have been AM */
3318 assert(is_ia32_NoReg_GP(addr->base));
3319 assert(is_ia32_NoReg_GP(addr->index));
3320 assert(is_NoMem(addr->mem));
3321 assert(am.addr.offset == 0);
3322 assert(am.addr.symconst_ent == NULL);
3326 if (smaller_bits == 8) {
3327 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3328 addr->index, addr->mem, am.new_op2,
3331 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3332 addr->index, addr->mem, am.new_op2,
3335 set_am_attributes(new_node, &am);
3336 /* match_arguments assume that out-mode = in-mode, this isn't true here
3338 set_ia32_ls_mode(new_node, smaller_mode);
3339 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3340 new_node = fix_mem_proj(new_node, &am);
3345 * Transforms a Conv node.
3347 * @return The created ia32 Conv node
3349 static ir_node *gen_Conv(ir_node *node) {
3350 ir_node *block = get_nodes_block(node);
3351 ir_node *new_block = be_transform_node(block);
3352 ir_node *op = get_Conv_op(node);
3353 ir_node *new_op = NULL;
3354 ir_graph *irg = current_ir_graph;
3355 dbg_info *dbgi = get_irn_dbg_info(node);
3356 ir_mode *src_mode = get_irn_mode(op);
3357 ir_mode *tgt_mode = get_irn_mode(node);
3358 int src_bits = get_mode_size_bits(src_mode);
3359 int tgt_bits = get_mode_size_bits(tgt_mode);
3360 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3361 ir_node *nomem = new_rd_NoMem(irg);
3362 ir_node *res = NULL;
3364 if (src_mode == mode_b) {
3365 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3366 /* nothing to do, we already model bools as 0/1 ints */
3367 return be_transform_node(op);
3370 if (src_mode == tgt_mode) {
3371 if (get_Conv_strict(node)) {
3372 if (ia32_cg_config.use_sse2) {
3373 /* when we are in SSE mode, we can kill all strict no-op conversion */
3374 return be_transform_node(op);
3377 /* this should be optimized already, but who knows... */
3378 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3379 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3380 return be_transform_node(op);
3384 if (mode_is_float(src_mode)) {
3385 new_op = be_transform_node(op);
3386 /* we convert from float ... */
3387 if (mode_is_float(tgt_mode)) {
3388 if(src_mode == mode_E && tgt_mode == mode_D
3389 && !get_Conv_strict(node)) {
3390 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3395 if (ia32_cg_config.use_sse2) {
3396 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3397 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3399 set_ia32_ls_mode(res, tgt_mode);
3401 if(get_Conv_strict(node)) {
3402 res = gen_x87_strict_conv(tgt_mode, new_op);
3403 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3406 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3411 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3412 if (ia32_cg_config.use_sse2) {
3413 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3415 set_ia32_ls_mode(res, src_mode);
3417 return gen_x87_fp_to_gp(node);
3421 /* we convert from int ... */
3422 if (mode_is_float(tgt_mode)) {
3424 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3425 if (ia32_cg_config.use_sse2) {
3426 new_op = be_transform_node(op);
3427 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3429 set_ia32_ls_mode(res, tgt_mode);
3431 res = gen_x87_gp_to_fp(node, src_mode);
3432 if(get_Conv_strict(node)) {
3433 /* The strict-Conv is only necessary, if the int mode has more bits
3434 * than the float mantissa */
3435 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3436 size_t float_mantissa;
3437 /* FIXME There is no way to get the mantissa size of a mode */
3438 switch (get_mode_size_bits(tgt_mode)) {
3439 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3440 case 64: float_mantissa = 52 + 1; break;
3442 case 96: float_mantissa = 64; break;
3443 default: float_mantissa = 0; break;
3445 if (float_mantissa < int_mantissa) {
3446 res = gen_x87_strict_conv(tgt_mode, res);
3447 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3452 } else if(tgt_mode == mode_b) {
3453 /* mode_b lowering already took care that we only have 0/1 values */
3454 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3455 src_mode, tgt_mode));
3456 return be_transform_node(op);
3459 if (src_bits == tgt_bits) {
3460 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3461 src_mode, tgt_mode));
3462 return be_transform_node(op);
3465 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3473 static ir_node *create_immediate_or_transform(ir_node *node,
3474 char immediate_constraint_type)
3476 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3477 if (new_node == NULL) {
3478 new_node = be_transform_node(node);
3484 * Transforms a FrameAddr into an ia32 Add.
3486 static ir_node *gen_be_FrameAddr(ir_node *node) {
3487 ir_node *block = be_transform_node(get_nodes_block(node));
3488 ir_node *op = be_get_FrameAddr_frame(node);
3489 ir_node *new_op = be_transform_node(op);
3490 ir_graph *irg = current_ir_graph;
3491 dbg_info *dbgi = get_irn_dbg_info(node);
3492 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3495 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3496 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3497 set_ia32_use_frame(new_node);
3499 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3505 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3507 static ir_node *gen_be_Return(ir_node *node) {
3508 ir_graph *irg = current_ir_graph;
3509 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3510 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3511 ir_entity *ent = get_irg_entity(irg);
3512 ir_type *tp = get_entity_type(ent);
3517 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3518 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3521 int pn_ret_val, pn_ret_mem, arity, i;
3523 assert(ret_val != NULL);
3524 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3525 return be_duplicate_node(node);
3528 res_type = get_method_res_type(tp, 0);
3530 if (! is_Primitive_type(res_type)) {
3531 return be_duplicate_node(node);
3534 mode = get_type_mode(res_type);
3535 if (! mode_is_float(mode)) {
3536 return be_duplicate_node(node);
3539 assert(get_method_n_ress(tp) == 1);
3541 pn_ret_val = get_Proj_proj(ret_val);
3542 pn_ret_mem = get_Proj_proj(ret_mem);
3544 /* get the Barrier */
3545 barrier = get_Proj_pred(ret_val);
3547 /* get result input of the Barrier */
3548 ret_val = get_irn_n(barrier, pn_ret_val);
3549 new_ret_val = be_transform_node(ret_val);
3551 /* get memory input of the Barrier */
3552 ret_mem = get_irn_n(barrier, pn_ret_mem);
3553 new_ret_mem = be_transform_node(ret_mem);
3555 frame = get_irg_frame(irg);
3557 dbgi = get_irn_dbg_info(barrier);
3558 block = be_transform_node(get_nodes_block(barrier));
3560 noreg = ia32_new_NoReg_gp(env_cg);
3562 /* store xmm0 onto stack */
3563 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3564 new_ret_mem, new_ret_val);
3565 set_ia32_ls_mode(sse_store, mode);
3566 set_ia32_op_type(sse_store, ia32_AddrModeD);
3567 set_ia32_use_frame(sse_store);
3569 /* load into x87 register */
3570 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3571 set_ia32_op_type(fld, ia32_AddrModeS);
3572 set_ia32_use_frame(fld);
3574 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3575 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3577 /* create a new barrier */
3578 arity = get_irn_arity(barrier);
3579 in = alloca(arity * sizeof(in[0]));
3580 for (i = 0; i < arity; ++i) {
3583 if (i == pn_ret_val) {
3585 } else if (i == pn_ret_mem) {
3588 ir_node *in = get_irn_n(barrier, i);
3589 new_in = be_transform_node(in);
3594 new_barrier = new_ir_node(dbgi, irg, block,
3595 get_irn_op(barrier), get_irn_mode(barrier),
3597 copy_node_attr(barrier, new_barrier);
3598 be_duplicate_deps(barrier, new_barrier);
3599 be_set_transformed_node(barrier, new_barrier);
3600 mark_irn_visited(barrier);
3602 /* transform normally */
3603 return be_duplicate_node(node);
3607 * Transform a be_AddSP into an ia32_SubSP.
3609 static ir_node *gen_be_AddSP(ir_node *node)
3611 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3612 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3614 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3615 match_am | match_immediate);
3619 * Transform a be_SubSP into an ia32_AddSP
3621 static ir_node *gen_be_SubSP(ir_node *node)
3623 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3624 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3626 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3627 match_am | match_immediate);
3631 * Change some phi modes
3633 static ir_node *gen_Phi(ir_node *node) {
3634 ir_node *block = be_transform_node(get_nodes_block(node));
3635 ir_graph *irg = current_ir_graph;
3636 dbg_info *dbgi = get_irn_dbg_info(node);
3637 ir_mode *mode = get_irn_mode(node);
3640 if(ia32_mode_needs_gp_reg(mode)) {
3641 /* we shouldn't have any 64bit stuff around anymore */
3642 assert(get_mode_size_bits(mode) <= 32);
3643 /* all integer operations are on 32bit registers now */
3645 } else if(mode_is_float(mode)) {
3646 if (ia32_cg_config.use_sse2) {
3653 /* phi nodes allow loops, so we use the old arguments for now
3654 * and fix this later */
3655 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3656 get_irn_in(node) + 1);
3657 copy_node_attr(node, phi);
3658 be_duplicate_deps(node, phi);
3660 be_set_transformed_node(node, phi);
3661 be_enqueue_preds(node);
3669 static ir_node *gen_IJmp(ir_node *node)
3671 ir_node *block = get_nodes_block(node);
3672 ir_node *new_block = be_transform_node(block);
3673 dbg_info *dbgi = get_irn_dbg_info(node);
3674 ir_node *op = get_IJmp_target(node);
3676 ia32_address_mode_t am;
3677 ia32_address_t *addr = &am.addr;
3679 assert(get_irn_mode(op) == mode_P);
3681 match_arguments(&am, block, NULL, op, NULL,
3682 match_am | match_8bit_am | match_16bit_am |
3683 match_immediate | match_8bit | match_16bit);
3685 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3686 addr->base, addr->index, addr->mem,
3688 set_am_attributes(new_node, &am);
3689 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3691 new_node = fix_mem_proj(new_node, &am);
3697 * Transform a Bound node.
3699 static ir_node *gen_Bound(ir_node *node)
3702 ir_node *lower = get_Bound_lower(node);
3703 dbg_info *dbgi = get_irn_dbg_info(node);
3705 if (is_Const_0(lower)) {
3706 /* typical case for Java */
3707 ir_node *sub, *res, *flags, *block;
3708 ir_graph *irg = current_ir_graph;
3710 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3711 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3713 block = get_nodes_block(res);
3714 if (! is_Proj(res)) {
3716 set_irn_mode(sub, mode_T);
3717 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3719 sub = get_Proj_pred(res);
3721 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3722 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3723 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3725 panic("generic Bound not supported in ia32 Backend");
3731 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3733 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3734 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3736 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3737 match_immediate | match_mode_neutral);
3740 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3742 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3743 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3744 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3748 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3750 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3751 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3752 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3756 static ir_node *gen_ia32_l_Add(ir_node *node) {
3757 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3758 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3759 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3760 match_commutative | match_am | match_immediate |
3761 match_mode_neutral);
3763 if(is_Proj(lowered)) {
3764 lowered = get_Proj_pred(lowered);
3766 assert(is_ia32_Add(lowered));
3767 set_irn_mode(lowered, mode_T);
3773 static ir_node *gen_ia32_l_Adc(ir_node *node)
3775 return gen_binop_flags(node, new_rd_ia32_Adc,
3776 match_commutative | match_am | match_immediate |
3777 match_mode_neutral);
3781 * Transforms a l_MulS into a "real" MulS node.
3783 * @return the created ia32 Mul node
3785 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3786 ir_node *left = get_binop_left(node);
3787 ir_node *right = get_binop_right(node);
3789 return gen_binop(node, left, right, new_rd_ia32_Mul,
3790 match_commutative | match_am | match_mode_neutral);
3794 * Transforms a l_IMulS into a "real" IMul1OPS node.
3796 * @return the created ia32 IMul1OP node
3798 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3799 ir_node *left = get_binop_left(node);
3800 ir_node *right = get_binop_right(node);
3802 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3803 match_commutative | match_am | match_mode_neutral);
3806 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3807 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3808 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3809 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3810 match_am | match_immediate | match_mode_neutral);
3812 if(is_Proj(lowered)) {
3813 lowered = get_Proj_pred(lowered);
3815 assert(is_ia32_Sub(lowered));
3816 set_irn_mode(lowered, mode_T);
3822 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3823 return gen_binop_flags(node, new_rd_ia32_Sbb,
3824 match_am | match_immediate | match_mode_neutral);
3828 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3829 * op1 - target to be shifted
3830 * op2 - contains bits to be shifted into target
3832 * Only op3 can be an immediate.
3834 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3835 ir_node *low, ir_node *count)
3837 ir_node *block = get_nodes_block(node);
3838 ir_node *new_block = be_transform_node(block);
3839 ir_graph *irg = current_ir_graph;
3840 dbg_info *dbgi = get_irn_dbg_info(node);
3841 ir_node *new_high = be_transform_node(high);
3842 ir_node *new_low = be_transform_node(low);
3846 /* the shift amount can be any mode that is bigger than 5 bits, since all
3847 * other bits are ignored anyway */
3848 while (is_Conv(count) &&
3849 get_irn_n_edges(count) == 1 &&
3850 mode_is_int(get_irn_mode(count))) {
3851 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3852 count = get_Conv_op(count);
3854 new_count = create_immediate_or_transform(count, 0);
3856 if (is_ia32_l_ShlD(node)) {
3857 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3860 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3863 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3868 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3870 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3871 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3872 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3873 return gen_lowered_64bit_shifts(node, high, low, count);
3876 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3878 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3879 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3880 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3881 return gen_lowered_64bit_shifts(node, high, low, count);
3884 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3885 ir_node *src_block = get_nodes_block(node);
3886 ir_node *block = be_transform_node(src_block);
3887 ir_graph *irg = current_ir_graph;
3888 dbg_info *dbgi = get_irn_dbg_info(node);
3889 ir_node *frame = get_irg_frame(irg);
3890 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3891 ir_node *nomem = new_NoMem();
3892 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3893 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3894 ir_node *new_val_low = be_transform_node(val_low);
3895 ir_node *new_val_high = be_transform_node(val_high);
3900 ir_node *store_high;
3902 if(!mode_is_signed(get_irn_mode(val_high))) {
3903 panic("unsigned long long -> float not supported yet (%+F)", node);
3907 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3909 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3911 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3912 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3914 set_ia32_use_frame(store_low);
3915 set_ia32_use_frame(store_high);
3916 set_ia32_op_type(store_low, ia32_AddrModeD);
3917 set_ia32_op_type(store_high, ia32_AddrModeD);
3918 set_ia32_ls_mode(store_low, mode_Iu);
3919 set_ia32_ls_mode(store_high, mode_Is);
3920 add_ia32_am_offs_int(store_high, 4);
3924 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3927 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3929 set_ia32_use_frame(fild);
3930 set_ia32_op_type(fild, ia32_AddrModeS);
3931 set_ia32_ls_mode(fild, mode_Ls);
3933 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3935 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3938 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3939 ir_node *src_block = get_nodes_block(node);
3940 ir_node *block = be_transform_node(src_block);
3941 ir_graph *irg = current_ir_graph;
3942 dbg_info *dbgi = get_irn_dbg_info(node);
3943 ir_node *frame = get_irg_frame(irg);
3944 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3945 ir_node *nomem = new_NoMem();
3946 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3947 ir_node *new_val = be_transform_node(val);
3948 ir_node *fist, *mem;
3950 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3951 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3952 set_ia32_use_frame(fist);
3953 set_ia32_op_type(fist, ia32_AddrModeD);
3954 set_ia32_ls_mode(fist, mode_Ls);
3960 * the BAD transformer.
3962 static ir_node *bad_transform(ir_node *node) {
3963 panic("No transform function for %+F available.", node);
3967 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
3968 ir_graph *irg = current_ir_graph;
3969 ir_node *block = be_transform_node(get_nodes_block(node));
3970 ir_node *pred = get_Proj_pred(node);
3971 ir_node *new_pred = be_transform_node(pred);
3972 ir_node *frame = get_irg_frame(irg);
3973 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3974 dbg_info *dbgi = get_irn_dbg_info(node);
3975 long pn = get_Proj_proj(node);
3980 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3981 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3982 set_ia32_use_frame(load);
3983 set_ia32_op_type(load, ia32_AddrModeS);
3984 set_ia32_ls_mode(load, mode_Iu);
3985 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3986 * 32 bit from it with this particular load */
3987 attr = get_ia32_attr(load);
3988 attr->data.need_64bit_stackent = 1;
3990 if (pn == pn_ia32_l_FloattoLL_res_high) {
3991 add_ia32_am_offs_int(load, 4);
3993 assert(pn == pn_ia32_l_FloattoLL_res_low);
3996 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4002 * Transform the Projs of an AddSP.
4004 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4005 ir_node *block = be_transform_node(get_nodes_block(node));
4006 ir_node *pred = get_Proj_pred(node);
4007 ir_node *new_pred = be_transform_node(pred);
4008 ir_graph *irg = current_ir_graph;
4009 dbg_info *dbgi = get_irn_dbg_info(node);
4010 long proj = get_Proj_proj(node);
4012 if (proj == pn_be_AddSP_sp) {
4013 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4014 pn_ia32_SubSP_stack);
4015 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4017 } else if(proj == pn_be_AddSP_res) {
4018 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4019 pn_ia32_SubSP_addr);
4020 } else if (proj == pn_be_AddSP_M) {
4021 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4025 return new_rd_Unknown(irg, get_irn_mode(node));
4029 * Transform the Projs of a SubSP.
4031 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4032 ir_node *block = be_transform_node(get_nodes_block(node));
4033 ir_node *pred = get_Proj_pred(node);
4034 ir_node *new_pred = be_transform_node(pred);
4035 ir_graph *irg = current_ir_graph;
4036 dbg_info *dbgi = get_irn_dbg_info(node);
4037 long proj = get_Proj_proj(node);
4039 if (proj == pn_be_SubSP_sp) {
4040 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4041 pn_ia32_AddSP_stack);
4042 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4044 } else if (proj == pn_be_SubSP_M) {
4045 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4049 return new_rd_Unknown(irg, get_irn_mode(node));
4053 * Transform and renumber the Projs from a Load.
4055 static ir_node *gen_Proj_Load(ir_node *node) {
4057 ir_node *block = be_transform_node(get_nodes_block(node));
4058 ir_node *pred = get_Proj_pred(node);
4059 ir_graph *irg = current_ir_graph;
4060 dbg_info *dbgi = get_irn_dbg_info(node);
4061 long proj = get_Proj_proj(node);
4063 /* loads might be part of source address mode matches, so we don't
4064 * transform the ProjMs yet (with the exception of loads whose result is
4067 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4070 /* this is needed, because sometimes we have loops that are only
4071 reachable through the ProjM */
4072 be_enqueue_preds(node);
4073 /* do it in 2 steps, to silence firm verifier */
4074 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4075 set_Proj_proj(res, pn_ia32_mem);
4079 /* renumber the proj */
4080 new_pred = be_transform_node(pred);
4081 if (is_ia32_Load(new_pred)) {
4084 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4086 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4087 case pn_Load_X_regular:
4088 return new_rd_Jmp(dbgi, irg, block);
4089 case pn_Load_X_except:
4090 /* This Load might raise an exception. Mark it. */
4091 set_ia32_exc_label(new_pred, 1);
4092 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4096 } else if (is_ia32_Conv_I2I(new_pred) ||
4097 is_ia32_Conv_I2I8Bit(new_pred)) {
4098 set_irn_mode(new_pred, mode_T);
4099 if (proj == pn_Load_res) {
4100 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4101 } else if (proj == pn_Load_M) {
4102 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4104 } else if (is_ia32_xLoad(new_pred)) {
4107 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4109 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4110 case pn_Load_X_regular:
4111 return new_rd_Jmp(dbgi, irg, block);
4112 case pn_Load_X_except:
4113 /* This Load might raise an exception. Mark it. */
4114 set_ia32_exc_label(new_pred, 1);
4115 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4119 } else if (is_ia32_vfld(new_pred)) {
4122 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4124 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4125 case pn_Load_X_regular:
4126 return new_rd_Jmp(dbgi, irg, block);
4127 case pn_Load_X_except:
4128 /* This Load might raise an exception. Mark it. */
4129 set_ia32_exc_label(new_pred, 1);
4130 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4135 /* can happen for ProJMs when source address mode happened for the
4138 /* however it should not be the result proj, as that would mean the
4139 load had multiple users and should not have been used for
4141 if (proj != pn_Load_M) {
4142 panic("internal error: transformed node not a Load");
4144 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4147 panic("No idea how to transform proj");
4151 * Transform and renumber the Projs from a DivMod like instruction.
4153 static ir_node *gen_Proj_DivMod(ir_node *node) {
4154 ir_node *block = be_transform_node(get_nodes_block(node));
4155 ir_node *pred = get_Proj_pred(node);
4156 ir_node *new_pred = be_transform_node(pred);
4157 ir_graph *irg = current_ir_graph;
4158 dbg_info *dbgi = get_irn_dbg_info(node);
4159 ir_mode *mode = get_irn_mode(node);
4160 long proj = get_Proj_proj(node);
4162 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4164 switch (get_irn_opcode(pred)) {
4168 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4170 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4171 case pn_Div_X_regular:
4172 return new_rd_Jmp(dbgi, irg, block);
4173 case pn_Div_X_except:
4174 set_ia32_exc_label(new_pred, 1);
4175 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4183 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4185 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4186 case pn_Mod_X_except:
4187 set_ia32_exc_label(new_pred, 1);
4188 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4196 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4197 case pn_DivMod_res_div:
4198 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4199 case pn_DivMod_res_mod:
4200 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4201 case pn_DivMod_X_regular:
4202 return new_rd_Jmp(dbgi, irg, block);
4203 case pn_DivMod_X_except:
4204 set_ia32_exc_label(new_pred, 1);
4205 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4215 return new_rd_Unknown(irg, mode);
4219 * Transform and renumber the Projs from a CopyB.
4221 static ir_node *gen_Proj_CopyB(ir_node *node) {
4222 ir_node *block = be_transform_node(get_nodes_block(node));
4223 ir_node *pred = get_Proj_pred(node);
4224 ir_node *new_pred = be_transform_node(pred);
4225 ir_graph *irg = current_ir_graph;
4226 dbg_info *dbgi = get_irn_dbg_info(node);
4227 ir_mode *mode = get_irn_mode(node);
4228 long proj = get_Proj_proj(node);
4231 case pn_CopyB_M_regular:
4232 if (is_ia32_CopyB_i(new_pred)) {
4233 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4234 } else if (is_ia32_CopyB(new_pred)) {
4235 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4243 return new_rd_Unknown(irg, mode);
4247 * Transform and renumber the Projs from a Quot.
4249 static ir_node *gen_Proj_Quot(ir_node *node) {
4250 ir_node *block = be_transform_node(get_nodes_block(node));
4251 ir_node *pred = get_Proj_pred(node);
4252 ir_node *new_pred = be_transform_node(pred);
4253 ir_graph *irg = current_ir_graph;
4254 dbg_info *dbgi = get_irn_dbg_info(node);
4255 ir_mode *mode = get_irn_mode(node);
4256 long proj = get_Proj_proj(node);
4260 if (is_ia32_xDiv(new_pred)) {
4261 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4262 } else if (is_ia32_vfdiv(new_pred)) {
4263 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4267 if (is_ia32_xDiv(new_pred)) {
4268 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4269 } else if (is_ia32_vfdiv(new_pred)) {
4270 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4273 case pn_Quot_X_regular:
4274 case pn_Quot_X_except:
4280 return new_rd_Unknown(irg, mode);
4283 static ir_node *gen_be_Call(ir_node *node) {
4284 ir_node *res = be_duplicate_node(node);
4287 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4289 /* Run the x87 simulator if the call returns a float value */
4290 call_tp = be_Call_get_type(node);
4291 if (get_method_n_ress(call_tp) > 0) {
4292 ir_type *const res_type = get_method_res_type(call_tp, 0);
4293 ir_mode *const res_mode = get_type_mode(res_type);
4295 if (res_mode != NULL && mode_is_float(res_mode)) {
4296 env_cg->do_x87_sim = 1;
4303 static ir_node *gen_be_IncSP(ir_node *node) {
4304 ir_node *res = be_duplicate_node(node);
4305 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4311 * Transform the Projs from a be_Call.
4313 static ir_node *gen_Proj_be_Call(ir_node *node) {
4314 ir_node *block = be_transform_node(get_nodes_block(node));
4315 ir_node *call = get_Proj_pred(node);
4316 ir_node *new_call = be_transform_node(call);
4317 ir_graph *irg = current_ir_graph;
4318 dbg_info *dbgi = get_irn_dbg_info(node);
4319 ir_type *method_type = be_Call_get_type(call);
4320 int n_res = get_method_n_ress(method_type);
4321 long proj = get_Proj_proj(node);
4322 ir_mode *mode = get_irn_mode(node);
4324 const arch_register_class_t *cls;
4326 /* The following is kinda tricky: If we're using SSE, then we have to
4327 * move the result value of the call in floating point registers to an
4328 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4329 * after the call, we have to make sure to correctly make the
4330 * MemProj and the result Proj use these 2 nodes
4332 if (proj == pn_be_Call_M_regular) {
4333 // get new node for result, are we doing the sse load/store hack?
4334 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4335 ir_node *call_res_new;
4336 ir_node *call_res_pred = NULL;
4338 if (call_res != NULL) {
4339 call_res_new = be_transform_node(call_res);
4340 call_res_pred = get_Proj_pred(call_res_new);
4343 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4344 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4345 pn_be_Call_M_regular);
4347 assert(is_ia32_xLoad(call_res_pred));
4348 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4352 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4353 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4355 ir_node *frame = get_irg_frame(irg);
4356 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4358 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4361 /* in case there is no memory output: create one to serialize the copy
4363 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4364 pn_be_Call_M_regular);
4365 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4366 pn_be_Call_first_res);
4368 /* store st(0) onto stack */
4369 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4371 set_ia32_op_type(fstp, ia32_AddrModeD);
4372 set_ia32_use_frame(fstp);
4374 /* load into SSE register */
4375 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4377 set_ia32_op_type(sse_load, ia32_AddrModeS);
4378 set_ia32_use_frame(sse_load);
4380 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4386 /* transform call modes */
4387 if (mode_is_data(mode)) {
4388 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4392 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4396 * Transform the Projs from a Cmp.
4398 static ir_node *gen_Proj_Cmp(ir_node *node)
4400 /* this probably means not all mode_b nodes were lowered... */
4401 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4406 * Transform the Projs from a Bound.
4408 static ir_node *gen_Proj_Bound(ir_node *node)
4410 ir_node *new_node, *block;
4411 ir_node *pred = get_Proj_pred(node);
4413 switch (get_Proj_proj(node)) {
4415 return be_transform_node(get_Bound_mem(pred));
4416 case pn_Bound_X_regular:
4417 new_node = be_transform_node(pred);
4418 block = get_nodes_block(new_node);
4419 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4420 case pn_Bound_X_except:
4421 new_node = be_transform_node(pred);
4422 block = get_nodes_block(new_node);
4423 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4425 return be_transform_node(get_Bound_index(pred));
4427 panic("unsupported Proj from Bound");
4431 static ir_node *gen_Proj_ASM(ir_node *node)
4437 if (get_irn_mode(node) != mode_M)
4438 return be_duplicate_node(node);
4440 pred = get_Proj_pred(node);
4441 new_pred = be_transform_node(pred);
4442 block = get_nodes_block(new_pred);
4443 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4444 get_ia32_n_res(new_pred) + 1);
4448 * Transform and potentially renumber Proj nodes.
4450 static ir_node *gen_Proj(ir_node *node) {
4451 ir_node *pred = get_Proj_pred(node);
4454 switch (get_irn_opcode(pred)) {
4456 proj = get_Proj_proj(node);
4457 if (proj == pn_Store_M) {
4458 return be_transform_node(pred);
4461 return new_r_Bad(current_ir_graph);
4464 return gen_Proj_Load(node);
4466 return gen_Proj_ASM(node);
4470 return gen_Proj_DivMod(node);
4472 return gen_Proj_CopyB(node);
4474 return gen_Proj_Quot(node);
4476 return gen_Proj_be_SubSP(node);
4478 return gen_Proj_be_AddSP(node);
4480 return gen_Proj_be_Call(node);
4482 return gen_Proj_Cmp(node);
4484 return gen_Proj_Bound(node);
4486 proj = get_Proj_proj(node);
4487 if (proj == pn_Start_X_initial_exec) {
4488 ir_node *block = get_nodes_block(pred);
4489 dbg_info *dbgi = get_irn_dbg_info(node);
4492 /* we exchange the ProjX with a jump */
4493 block = be_transform_node(block);
4494 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
4497 if (node == be_get_old_anchor(anchor_tls)) {
4498 return gen_Proj_tls(node);
4503 if (is_ia32_l_FloattoLL(pred)) {
4504 return gen_Proj_l_FloattoLL(node);
4506 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4510 ir_mode *mode = get_irn_mode(node);
4511 if (ia32_mode_needs_gp_reg(mode)) {
4512 ir_node *new_pred = be_transform_node(pred);
4513 ir_node *block = be_transform_node(get_nodes_block(node));
4514 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4515 mode_Iu, get_Proj_proj(node));
4516 #ifdef DEBUG_libfirm
4517 new_proj->node_nr = node->node_nr;
4523 return be_duplicate_node(node);
4527 * Enters all transform functions into the generic pointer
4529 static void register_transformers(void)
4533 /* first clear the generic function pointer for all ops */
4534 clear_irp_opcodes_generic_func();
4536 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4537 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4575 /* transform ops from intrinsic lowering */
4587 GEN(ia32_l_LLtoFloat);
4588 GEN(ia32_l_FloattoLL);
4594 /* we should never see these nodes */
4609 /* handle generic backend nodes */
4618 op_Mulh = get_op_Mulh();
4627 * Pre-transform all unknown and noreg nodes.
4629 static void ia32_pretransform_node(void *arch_cg) {
4630 ia32_code_gen_t *cg = arch_cg;
4632 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4633 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4634 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4635 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4636 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4637 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4642 * Walker, checks if all ia32 nodes producing more than one result have their
4643 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4645 static void add_missing_keep_walker(ir_node *node, void *data)
4648 unsigned found_projs = 0;
4649 const ir_edge_t *edge;
4650 ir_mode *mode = get_irn_mode(node);
4655 if(!is_ia32_irn(node))
4658 n_outs = get_ia32_n_res(node);
4661 if(is_ia32_SwitchJmp(node))
4664 assert(n_outs < (int) sizeof(unsigned) * 8);
4665 foreach_out_edge(node, edge) {
4666 ir_node *proj = get_edge_src_irn(edge);
4667 int pn = get_Proj_proj(proj);
4669 if (get_irn_mode(proj) == mode_M)
4672 assert(pn < n_outs);
4673 found_projs |= 1 << pn;
4677 /* are keeps missing? */
4679 for(i = 0; i < n_outs; ++i) {
4682 const arch_register_req_t *req;
4683 const arch_register_class_t *cls;
4685 if(found_projs & (1 << i)) {
4689 req = get_ia32_out_req(node, i);
4694 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4698 block = get_nodes_block(node);
4699 in[0] = new_r_Proj(current_ir_graph, block, node,
4700 arch_register_class_mode(cls), i);
4701 if(last_keep != NULL) {
4702 be_Keep_add_node(last_keep, cls, in[0]);
4704 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4705 if(sched_is_scheduled(node)) {
4706 sched_add_after(node, last_keep);
4713 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4716 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4718 ir_graph *irg = be_get_birg_irg(cg->birg);
4719 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4722 /* do the transformation */
4723 void ia32_transform_graph(ia32_code_gen_t *cg) {
4725 ir_graph *irg = cg->irg;
4727 register_transformers();
4729 initial_fpcw = NULL;
4731 BE_TIMER_PUSH(t_heights);
4732 heights = heights_new(irg);
4733 BE_TIMER_POP(t_heights);
4734 ia32_calculate_non_address_mode_nodes(cg->birg);
4736 /* the transform phase is not safe for CSE (yet) because several nodes get
4737 * attributes set after their creation */
4738 cse_last = get_opt_cse();
4741 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4743 set_opt_cse(cse_last);
4745 ia32_free_non_address_mode_nodes();
4746 heights_free(heights);
4750 void ia32_init_transform(void)
4752 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");