2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
36 #include "irgraph_t.h"
41 #include "iredges_t.h"
54 #include "../benode_t.h"
55 #include "../besched.h"
57 #include "../beutil.h"
58 #include "../beirg_t.h"
59 #include "../betranshlp.h"
62 #include "bearch_ia32_t.h"
63 #include "ia32_common_transform.h"
64 #include "ia32_nodes_attr.h"
65 #include "ia32_transform.h"
66 #include "ia32_new_nodes.h"
67 #include "ia32_map_regs.h"
68 #include "ia32_dbg_stat.h"
69 #include "ia32_optimize.h"
70 #include "ia32_util.h"
71 #include "ia32_address_mode.h"
72 #include "ia32_architecture.h"
74 #include "gen_ia32_regalloc_if.h"
76 #define SFP_SIGN "0x80000000"
77 #define DFP_SIGN "0x8000000000000000"
78 #define SFP_ABS "0x7FFFFFFF"
79 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
80 #define DFP_INTMAX "9223372036854775807"
82 #define TP_SFP_SIGN "ia32_sfp_sign"
83 #define TP_DFP_SIGN "ia32_dfp_sign"
84 #define TP_SFP_ABS "ia32_sfp_abs"
85 #define TP_DFP_ABS "ia32_dfp_abs"
86 #define TP_INT_MAX "ia32_int_max"
88 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
89 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
90 #define ENT_SFP_ABS "IA32_SFP_ABS"
91 #define ENT_DFP_ABS "IA32_DFP_ABS"
92 #define ENT_INT_MAX "IA32_INT_MAX"
94 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
95 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
97 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
99 static ir_node *initial_fpcw = NULL;
101 extern ir_op *get_op_Mulh(void);
103 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
104 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
105 ir_node *op1, ir_node *op2);
107 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
108 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
109 ir_node *op1, ir_node *op2, ir_node *flags);
111 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
112 ir_node *block, ir_node *op1, ir_node *op2);
114 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
115 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
118 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
119 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
121 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
122 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
123 ir_node *op1, ir_node *op2, ir_node *fpcw);
125 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
126 ir_node *block, ir_node *op);
128 static ir_node *create_immediate_or_transform(ir_node *node,
129 char immediate_constraint_type);
131 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
132 dbg_info *dbgi, ir_node *block,
133 ir_node *op, ir_node *orig_node);
135 /** Return non-zero is a node represents the 0 constant. */
136 static bool is_Const_0(ir_node *node) {
137 return is_Const(node) && is_Const_null(node);
140 /** Return non-zero is a node represents the 1 constant. */
141 static bool is_Const_1(ir_node *node) {
142 return is_Const(node) && is_Const_one(node);
145 /** Return non-zero is a node represents the -1 constant. */
146 static bool is_Const_Minus_1(ir_node *node) {
147 return is_Const(node) && is_Const_all_one(node);
151 * returns true if constant can be created with a simple float command
153 static bool is_simple_x87_Const(ir_node *node)
155 tarval *tv = get_Const_tarval(node);
156 if (tarval_is_null(tv) || tarval_is_one(tv))
159 /* TODO: match all the other float constants */
164 * returns true if constant can be created with a simple float command
166 static bool is_simple_sse_Const(ir_node *node)
168 tarval *tv = get_Const_tarval(node);
169 ir_mode *mode = get_tarval_mode(tv);
174 if (tarval_is_null(tv) || tarval_is_one(tv))
177 if (mode == mode_D) {
178 unsigned val = get_tarval_sub_bits(tv, 0) |
179 (get_tarval_sub_bits(tv, 1) << 8) |
180 (get_tarval_sub_bits(tv, 2) << 16) |
181 (get_tarval_sub_bits(tv, 3) << 24);
183 /* lower 32bit are zero, really a 32bit constant */
187 /* TODO: match all the other float constants */
192 * Transforms a Const.
194 static ir_node *gen_Const(ir_node *node) {
195 ir_graph *irg = current_ir_graph;
196 ir_node *old_block = get_nodes_block(node);
197 ir_node *block = be_transform_node(old_block);
198 dbg_info *dbgi = get_irn_dbg_info(node);
199 ir_mode *mode = get_irn_mode(node);
201 assert(is_Const(node));
203 if (mode_is_float(mode)) {
205 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
206 ir_node *nomem = new_NoMem();
210 if (ia32_cg_config.use_sse2) {
211 tarval *tv = get_Const_tarval(node);
212 if (tarval_is_null(tv)) {
213 load = new_rd_ia32_xZero(dbgi, irg, block);
214 set_ia32_ls_mode(load, mode);
216 } else if (tarval_is_one(tv)) {
217 int cnst = mode == mode_F ? 26 : 55;
218 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
219 ir_node *imm2 = create_Immediate(NULL, 0, 2);
220 ir_node *pslld, *psrld;
222 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
223 set_ia32_ls_mode(load, mode);
224 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
225 set_ia32_ls_mode(pslld, mode);
226 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
227 set_ia32_ls_mode(psrld, mode);
229 } else if (mode == mode_F) {
230 /* we can place any 32bit constant by using a movd gp, sse */
231 unsigned val = get_tarval_sub_bits(tv, 0) |
232 (get_tarval_sub_bits(tv, 1) << 8) |
233 (get_tarval_sub_bits(tv, 2) << 16) |
234 (get_tarval_sub_bits(tv, 3) << 24);
235 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
236 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
237 set_ia32_ls_mode(load, mode);
240 if (mode == mode_D) {
241 unsigned val = get_tarval_sub_bits(tv, 0) |
242 (get_tarval_sub_bits(tv, 1) << 8) |
243 (get_tarval_sub_bits(tv, 2) << 16) |
244 (get_tarval_sub_bits(tv, 3) << 24);
246 ir_node *imm32 = create_Immediate(NULL, 0, 32);
247 ir_node *cnst, *psllq;
249 /* fine, lower 32bit are zero, produce 32bit value */
250 val = get_tarval_sub_bits(tv, 4) |
251 (get_tarval_sub_bits(tv, 5) << 8) |
252 (get_tarval_sub_bits(tv, 6) << 16) |
253 (get_tarval_sub_bits(tv, 7) << 24);
254 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
255 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
256 set_ia32_ls_mode(load, mode);
257 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
258 set_ia32_ls_mode(psllq, mode);
263 floatent = create_float_const_entity(node);
265 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
267 set_ia32_op_type(load, ia32_AddrModeS);
268 set_ia32_am_sc(load, floatent);
269 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
270 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
273 if (is_Const_null(node)) {
274 load = new_rd_ia32_vfldz(dbgi, irg, block);
276 set_ia32_ls_mode(load, mode);
277 } else if (is_Const_one(node)) {
278 load = new_rd_ia32_vfld1(dbgi, irg, block);
280 set_ia32_ls_mode(load, mode);
282 floatent = create_float_const_entity(node);
284 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
285 set_ia32_op_type(load, ia32_AddrModeS);
286 set_ia32_am_sc(load, floatent);
287 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
288 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
289 /* take the mode from the entity */
290 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
294 /* Const Nodes before the initial IncSP are a bad idea, because
295 * they could be spilled and we have no SP ready at that point yet.
296 * So add a dependency to the initial frame pointer calculation to
297 * avoid that situation.
299 if (get_irg_start_block(irg) == block) {
300 add_irn_dep(load, get_irg_frame(irg));
303 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
305 } else { /* non-float mode */
307 tarval *tv = get_Const_tarval(node);
310 tv = tarval_convert_to(tv, mode_Iu);
312 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
314 panic("couldn't convert constant tarval (%+F)", node);
316 val = get_tarval_long(tv);
318 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
319 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
322 if (get_irg_start_block(irg) == block) {
323 add_irn_dep(cnst, get_irg_frame(irg));
331 * Transforms a SymConst.
333 static ir_node *gen_SymConst(ir_node *node) {
334 ir_graph *irg = current_ir_graph;
335 ir_node *old_block = get_nodes_block(node);
336 ir_node *block = be_transform_node(old_block);
337 dbg_info *dbgi = get_irn_dbg_info(node);
338 ir_mode *mode = get_irn_mode(node);
341 if (mode_is_float(mode)) {
342 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
343 ir_node *nomem = new_NoMem();
345 if (ia32_cg_config.use_sse2)
346 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
348 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
349 set_ia32_am_sc(cnst, get_SymConst_entity(node));
350 set_ia32_use_frame(cnst);
354 if(get_SymConst_kind(node) != symconst_addr_ent) {
355 panic("backend only support symconst_addr_ent (at %+F)", node);
357 entity = get_SymConst_entity(node);
358 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
361 /* Const Nodes before the initial IncSP are a bad idea, because
362 * they could be spilled and we have no SP ready at that point yet
364 if (get_irg_start_block(irg) == block) {
365 add_irn_dep(cnst, get_irg_frame(irg));
368 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
373 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
374 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
375 static const struct {
377 const char *ent_name;
378 const char *cnst_str;
381 } names [ia32_known_const_max] = {
382 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
383 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
384 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
385 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
386 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
388 static ir_entity *ent_cache[ia32_known_const_max];
390 const char *tp_name, *ent_name, *cnst_str;
398 ent_name = names[kct].ent_name;
399 if (! ent_cache[kct]) {
400 tp_name = names[kct].tp_name;
401 cnst_str = names[kct].cnst_str;
403 switch (names[kct].mode) {
404 case 0: mode = mode_Iu; break;
405 case 1: mode = mode_Lu; break;
406 default: mode = mode_F; break;
408 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
409 tp = new_type_primitive(new_id_from_str(tp_name), mode);
410 /* set the specified alignment */
411 set_type_alignment_bytes(tp, names[kct].align);
413 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
415 set_entity_ld_ident(ent, get_entity_ident(ent));
416 set_entity_visibility(ent, visibility_local);
417 set_entity_variability(ent, variability_constant);
418 set_entity_allocation(ent, allocation_static);
420 /* we create a new entity here: It's initialization must resist on the
422 rem = current_ir_graph;
423 current_ir_graph = get_const_code_irg();
424 cnst = new_Const(mode, tv);
425 current_ir_graph = rem;
427 set_atomic_ent_value(ent, cnst);
429 /* cache the entry */
430 ent_cache[kct] = ent;
433 return ent_cache[kct];
436 static int prevents_AM(ir_node *const block, ir_node *const am_candidate,
437 ir_node *const other)
439 if (get_nodes_block(other) != block)
442 if (is_Sync(other)) {
445 for (i = get_Sync_n_preds(other) - 1; i >= 0; --i) {
446 ir_node *const pred = get_Sync_pred(other, i);
448 if (get_nodes_block(pred) != block)
451 /* Do not block ourselves from getting eaten */
452 if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate)
455 if (!heights_reachable_in_block(heights, pred, am_candidate))
463 /* Do not block ourselves from getting eaten */
464 if (is_Proj(other) && get_Proj_pred(other) == am_candidate)
467 if (!heights_reachable_in_block(heights, other, am_candidate))
475 * return true if the node is a Proj(Load) and could be used in source address
476 * mode for another node. Will return only true if the @p other node is not
477 * dependent on the memory of the Load (for binary operations use the other
478 * input here, for unary operations use NULL).
480 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
481 ir_node *other, ir_node *other2, match_flags_t flags)
486 /* float constants are always available */
487 if (is_Const(node)) {
488 ir_mode *mode = get_irn_mode(node);
489 if (mode_is_float(mode)) {
490 if (ia32_cg_config.use_sse2) {
491 if (is_simple_sse_Const(node))
494 if (is_simple_x87_Const(node))
497 if (get_irn_n_edges(node) > 1)
505 load = get_Proj_pred(node);
506 pn = get_Proj_proj(node);
507 if (!is_Load(load) || pn != pn_Load_res)
509 if (get_nodes_block(load) != block)
511 /* we only use address mode if we're the only user of the load */
512 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
514 /* in some edge cases with address mode we might reach the load normally
515 * and through some AM sequence, if it is already materialized then we
516 * can't create an AM node from it */
517 if (be_is_transformed(node))
520 /* don't do AM if other node inputs depend on the load (via mem-proj) */
521 if (other != NULL && prevents_AM(block, load, other))
524 if (other2 != NULL && prevents_AM(block, load, other2))
530 typedef struct ia32_address_mode_t ia32_address_mode_t;
531 struct ia32_address_mode_t {
536 ia32_op_type_t op_type;
540 unsigned commutative : 1;
541 unsigned ins_permuted : 1;
544 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
548 /* construct load address */
549 memset(addr, 0, sizeof(addr[0]));
550 ia32_create_address_mode(addr, ptr, /*force=*/0);
552 noreg_gp = ia32_new_NoReg_gp(env_cg);
553 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
554 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
555 addr->mem = be_transform_node(mem);
558 static void build_address(ia32_address_mode_t *am, ir_node *node)
560 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
561 ia32_address_t *addr = &am->addr;
567 if (is_Const(node)) {
568 ir_entity *entity = create_float_const_entity(node);
569 addr->base = noreg_gp;
570 addr->index = noreg_gp;
571 addr->mem = new_NoMem();
572 addr->symconst_ent = entity;
574 am->ls_mode = get_type_mode(get_entity_type(entity));
575 am->pinned = op_pin_state_floats;
579 load = get_Proj_pred(node);
580 ptr = get_Load_ptr(load);
581 mem = get_Load_mem(load);
582 new_mem = be_transform_node(mem);
583 am->pinned = get_irn_pinned(load);
584 am->ls_mode = get_Load_mode(load);
585 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
588 /* construct load address */
589 ia32_create_address_mode(addr, ptr, /*force=*/0);
591 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
592 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
596 static void set_address(ir_node *node, const ia32_address_t *addr)
598 set_ia32_am_scale(node, addr->scale);
599 set_ia32_am_sc(node, addr->symconst_ent);
600 set_ia32_am_offs_int(node, addr->offset);
601 if(addr->symconst_sign)
602 set_ia32_am_sc_sign(node);
604 set_ia32_use_frame(node);
605 set_ia32_frame_ent(node, addr->frame_entity);
609 * Apply attributes of a given address mode to a node.
611 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
613 set_address(node, &am->addr);
615 set_ia32_op_type(node, am->op_type);
616 set_ia32_ls_mode(node, am->ls_mode);
617 if (am->pinned == op_pin_state_pinned) {
618 /* beware: some nodes are already pinned and did not allow to change the state */
619 if (get_irn_pinned(node) != op_pin_state_pinned)
620 set_irn_pinned(node, op_pin_state_pinned);
623 set_ia32_commutative(node);
627 * Check, if a given node is a Down-Conv, ie. a integer Conv
628 * from a mode with a mode with more bits to a mode with lesser bits.
629 * Moreover, we return only true if the node has not more than 1 user.
631 * @param node the node
632 * @return non-zero if node is a Down-Conv
634 static int is_downconv(const ir_node *node)
642 /* we only want to skip the conv when we're the only user
643 * (not optimal but for now...)
645 if(get_irn_n_edges(node) > 1)
648 src_mode = get_irn_mode(get_Conv_op(node));
649 dest_mode = get_irn_mode(node);
650 return ia32_mode_needs_gp_reg(src_mode)
651 && ia32_mode_needs_gp_reg(dest_mode)
652 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
655 /* Skip all Down-Conv's on a given node and return the resulting node. */
656 ir_node *ia32_skip_downconv(ir_node *node) {
657 while (is_downconv(node))
658 node = get_Conv_op(node);
663 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
665 ir_mode *mode = get_irn_mode(node);
670 if(mode_is_signed(mode)) {
675 block = get_nodes_block(node);
676 dbgi = get_irn_dbg_info(node);
678 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
682 * matches operands of a node into ia32 addressing/operand modes. This covers
683 * usage of source address mode, immediates, operations with non 32-bit modes,
685 * The resulting data is filled into the @p am struct. block is the block
686 * of the node whose arguments are matched. op1, op2 are the first and second
687 * input that are matched (op1 may be NULL). other_op is another unrelated
688 * input that is not matched! but which is needed sometimes to check if AM
689 * for op1/op2 is legal.
690 * @p flags describes the supported modes of the operation in detail.
692 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
693 ir_node *op1, ir_node *op2, ir_node *other_op,
696 ia32_address_t *addr = &am->addr;
697 ir_mode *mode = get_irn_mode(op2);
698 int mode_bits = get_mode_size_bits(mode);
699 ir_node *noreg_gp, *new_op1, *new_op2;
701 unsigned commutative;
702 int use_am_and_immediates;
705 memset(am, 0, sizeof(am[0]));
707 commutative = (flags & match_commutative) != 0;
708 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
709 use_am = (flags & match_am) != 0;
710 use_immediate = (flags & match_immediate) != 0;
711 assert(!use_am_and_immediates || use_immediate);
714 assert(!commutative || op1 != NULL);
715 assert(use_am || !(flags & match_8bit_am));
716 assert(use_am || !(flags & match_16bit_am));
718 if (mode_bits == 8) {
719 if (!(flags & match_8bit_am))
721 /* we don't automatically add upconvs yet */
722 assert((flags & match_mode_neutral) || (flags & match_8bit));
723 } else if (mode_bits == 16) {
724 if (!(flags & match_16bit_am))
726 /* we don't automatically add upconvs yet */
727 assert((flags & match_mode_neutral) || (flags & match_16bit));
730 /* we can simply skip downconvs for mode neutral nodes: the upper bits
731 * can be random for these operations */
732 if (flags & match_mode_neutral) {
733 op2 = ia32_skip_downconv(op2);
735 op1 = ia32_skip_downconv(op1);
739 /* match immediates. firm nodes are normalized: constants are always on the
742 if (!(flags & match_try_am) && use_immediate) {
743 new_op2 = try_create_Immediate(op2, 0);
746 noreg_gp = ia32_new_NoReg_gp(env_cg);
747 if (new_op2 == NULL &&
748 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
749 build_address(am, op2);
750 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
751 if (mode_is_float(mode)) {
752 new_op2 = ia32_new_NoReg_vfp(env_cg);
756 am->op_type = ia32_AddrModeS;
757 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
759 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
761 build_address(am, op1);
763 if (mode_is_float(mode)) {
764 noreg = ia32_new_NoReg_vfp(env_cg);
769 if (new_op2 != NULL) {
772 new_op1 = be_transform_node(op2);
774 am->ins_permuted = 1;
776 am->op_type = ia32_AddrModeS;
778 if (flags & match_try_am) {
781 am->op_type = ia32_Normal;
785 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
787 new_op2 = be_transform_node(op2);
788 am->op_type = ia32_Normal;
789 am->ls_mode = get_irn_mode(op2);
790 if (flags & match_mode_neutral)
791 am->ls_mode = mode_Iu;
793 if (addr->base == NULL)
794 addr->base = noreg_gp;
795 if (addr->index == NULL)
796 addr->index = noreg_gp;
797 if (addr->mem == NULL)
798 addr->mem = new_NoMem();
800 am->new_op1 = new_op1;
801 am->new_op2 = new_op2;
802 am->commutative = commutative;
805 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
807 mark_irn_visited(old_node);
808 be_set_transformed_node(old_node, new_node);
811 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
816 if (am->mem_proj == NULL)
819 /* we have to create a mode_T so the old MemProj can attach to us */
820 mode = get_irn_mode(node);
821 load = get_Proj_pred(am->mem_proj);
823 set_transformed_and_mark(load, node);
825 if (mode != mode_T) {
826 set_irn_mode(node, mode_T);
827 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
834 * Construct a standard binary operation, set AM and immediate if required.
836 * @param node The original node for which the binop is created
837 * @param op1 The first operand
838 * @param op2 The second operand
839 * @param func The node constructor function
840 * @return The constructed ia32 node.
842 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
843 construct_binop_func *func, match_flags_t flags)
846 ir_node *block, *new_block, *new_node;
847 ia32_address_mode_t am;
848 ia32_address_t *addr = &am.addr;
850 block = get_nodes_block(node);
851 match_arguments(&am, block, op1, op2, NULL, flags);
853 dbgi = get_irn_dbg_info(node);
854 new_block = be_transform_node(block);
855 new_node = func(dbgi, current_ir_graph, new_block,
856 addr->base, addr->index, addr->mem,
857 am.new_op1, am.new_op2);
858 set_am_attributes(new_node, &am);
859 /* we can't use source address mode anymore when using immediates */
860 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
861 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
862 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
864 new_node = fix_mem_proj(new_node, &am);
871 n_ia32_l_binop_right,
872 n_ia32_l_binop_eflags
874 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
875 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
876 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
877 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
878 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
879 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
882 * Construct a binary operation which also consumes the eflags.
884 * @param node The node to transform
885 * @param func The node constructor function
886 * @param flags The match flags
887 * @return The constructor ia32 node
889 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
892 ir_node *src_block = get_nodes_block(node);
893 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
894 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
895 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
897 ir_node *block, *new_node, *new_eflags;
898 ia32_address_mode_t am;
899 ia32_address_t *addr = &am.addr;
901 match_arguments(&am, src_block, op1, op2, eflags, flags);
903 dbgi = get_irn_dbg_info(node);
904 block = be_transform_node(src_block);
905 new_eflags = be_transform_node(eflags);
906 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
907 addr->mem, am.new_op1, am.new_op2, new_eflags);
908 set_am_attributes(new_node, &am);
909 /* we can't use source address mode anymore when using immediates */
910 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
911 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
912 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
914 new_node = fix_mem_proj(new_node, &am);
919 static ir_node *get_fpcw(void)
922 if (initial_fpcw != NULL)
925 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
926 &ia32_fp_cw_regs[REG_FPCW]);
927 initial_fpcw = be_transform_node(fpcw);
933 * Construct a standard binary operation, set AM and immediate if required.
935 * @param op1 The first operand
936 * @param op2 The second operand
937 * @param func The node constructor function
938 * @return The constructed ia32 node.
940 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
941 construct_binop_float_func *func,
944 ir_mode *mode = get_irn_mode(node);
946 ir_node *block, *new_block, *new_node;
947 ia32_address_mode_t am;
948 ia32_address_t *addr = &am.addr;
950 /* cannot use address mode with long double on x87 */
951 if (get_mode_size_bits(mode) > 64)
954 block = get_nodes_block(node);
955 match_arguments(&am, block, op1, op2, NULL, flags);
957 dbgi = get_irn_dbg_info(node);
958 new_block = be_transform_node(block);
959 new_node = func(dbgi, current_ir_graph, new_block,
960 addr->base, addr->index, addr->mem,
961 am.new_op1, am.new_op2, get_fpcw());
962 set_am_attributes(new_node, &am);
964 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
966 new_node = fix_mem_proj(new_node, &am);
972 * Construct a shift/rotate binary operation, sets AM and immediate if required.
974 * @param op1 The first operand
975 * @param op2 The second operand
976 * @param func The node constructor function
977 * @return The constructed ia32 node.
979 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
980 construct_shift_func *func,
984 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
986 assert(! mode_is_float(get_irn_mode(node)));
987 assert(flags & match_immediate);
988 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
990 if (flags & match_mode_neutral) {
991 op1 = ia32_skip_downconv(op1);
992 new_op1 = be_transform_node(op1);
993 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
994 new_op1 = create_upconv(op1, node);
996 new_op1 = be_transform_node(op1);
999 /* the shift amount can be any mode that is bigger than 5 bits, since all
1000 * other bits are ignored anyway */
1001 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1002 ir_node *const op = get_Conv_op(op2);
1003 if (mode_is_float(get_irn_mode(op)))
1006 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1008 new_op2 = create_immediate_or_transform(op2, 0);
1010 dbgi = get_irn_dbg_info(node);
1011 block = get_nodes_block(node);
1012 new_block = be_transform_node(block);
1013 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1014 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1016 /* lowered shift instruction may have a dependency operand, handle it here */
1017 if (get_irn_arity(node) == 3) {
1018 /* we have a dependency */
1019 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1020 add_irn_dep(new_node, new_dep);
1028 * Construct a standard unary operation, set AM and immediate if required.
1030 * @param op The operand
1031 * @param func The node constructor function
1032 * @return The constructed ia32 node.
1034 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1035 match_flags_t flags)
1038 ir_node *block, *new_block, *new_op, *new_node;
1040 assert(flags == 0 || flags == match_mode_neutral);
1041 if (flags & match_mode_neutral) {
1042 op = ia32_skip_downconv(op);
1045 new_op = be_transform_node(op);
1046 dbgi = get_irn_dbg_info(node);
1047 block = get_nodes_block(node);
1048 new_block = be_transform_node(block);
1049 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1051 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1056 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1057 ia32_address_t *addr)
1059 ir_node *base, *index, *res;
1063 base = ia32_new_NoReg_gp(env_cg);
1065 base = be_transform_node(base);
1068 index = addr->index;
1069 if (index == NULL) {
1070 index = ia32_new_NoReg_gp(env_cg);
1072 index = be_transform_node(index);
1075 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1076 set_address(res, addr);
1082 * Returns non-zero if a given address mode has a symbolic or
1083 * numerical offset != 0.
1085 static int am_has_immediates(const ia32_address_t *addr)
1087 return addr->offset != 0 || addr->symconst_ent != NULL
1088 || addr->frame_entity || addr->use_frame;
1092 * Creates an ia32 Add.
1094 * @return the created ia32 Add node
1096 static ir_node *gen_Add(ir_node *node) {
1097 ir_mode *mode = get_irn_mode(node);
1098 ir_node *op1 = get_Add_left(node);
1099 ir_node *op2 = get_Add_right(node);
1101 ir_node *block, *new_block, *new_node, *add_immediate_op;
1102 ia32_address_t addr;
1103 ia32_address_mode_t am;
1105 if (mode_is_float(mode)) {
1106 if (ia32_cg_config.use_sse2)
1107 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1108 match_commutative | match_am);
1110 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1111 match_commutative | match_am);
1114 ia32_mark_non_am(node);
1116 op2 = ia32_skip_downconv(op2);
1117 op1 = ia32_skip_downconv(op1);
1121 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1122 * 1. Add with immediate -> Lea
1123 * 2. Add with possible source address mode -> Add
1124 * 3. Otherwise -> Lea
1126 memset(&addr, 0, sizeof(addr));
1127 ia32_create_address_mode(&addr, node, /*force=*/1);
1128 add_immediate_op = NULL;
1130 dbgi = get_irn_dbg_info(node);
1131 block = get_nodes_block(node);
1132 new_block = be_transform_node(block);
1135 if(addr.base == NULL && addr.index == NULL) {
1136 ir_graph *irg = current_ir_graph;
1137 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1138 addr.symconst_sign, addr.offset);
1139 add_irn_dep(new_node, get_irg_frame(irg));
1140 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1143 /* add with immediate? */
1144 if(addr.index == NULL) {
1145 add_immediate_op = addr.base;
1146 } else if(addr.base == NULL && addr.scale == 0) {
1147 add_immediate_op = addr.index;
1150 if(add_immediate_op != NULL) {
1151 if(!am_has_immediates(&addr)) {
1152 #ifdef DEBUG_libfirm
1153 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1156 return be_transform_node(add_immediate_op);
1159 new_node = create_lea_from_address(dbgi, new_block, &addr);
1160 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1164 /* test if we can use source address mode */
1165 match_arguments(&am, block, op1, op2, NULL, match_commutative
1166 | match_mode_neutral | match_am | match_immediate | match_try_am);
1168 /* construct an Add with source address mode */
1169 if (am.op_type == ia32_AddrModeS) {
1170 ir_graph *irg = current_ir_graph;
1171 ia32_address_t *am_addr = &am.addr;
1172 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1173 am_addr->index, am_addr->mem, am.new_op1,
1175 set_am_attributes(new_node, &am);
1176 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1178 new_node = fix_mem_proj(new_node, &am);
1183 /* otherwise construct a lea */
1184 new_node = create_lea_from_address(dbgi, new_block, &addr);
1185 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1190 * Creates an ia32 Mul.
1192 * @return the created ia32 Mul node
1194 static ir_node *gen_Mul(ir_node *node) {
1195 ir_node *op1 = get_Mul_left(node);
1196 ir_node *op2 = get_Mul_right(node);
1197 ir_mode *mode = get_irn_mode(node);
1199 if (mode_is_float(mode)) {
1200 if (ia32_cg_config.use_sse2)
1201 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1202 match_commutative | match_am);
1204 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1205 match_commutative | match_am);
1207 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1208 match_commutative | match_am | match_mode_neutral |
1209 match_immediate | match_am_and_immediates);
1213 * Creates an ia32 Mulh.
1214 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1215 * this result while Mul returns the lower 32 bit.
1217 * @return the created ia32 Mulh node
1219 static ir_node *gen_Mulh(ir_node *node)
1221 ir_node *block = get_nodes_block(node);
1222 ir_node *new_block = be_transform_node(block);
1223 ir_graph *irg = current_ir_graph;
1224 dbg_info *dbgi = get_irn_dbg_info(node);
1225 ir_mode *mode = get_irn_mode(node);
1226 ir_node *op1 = get_Mulh_left(node);
1227 ir_node *op2 = get_Mulh_right(node);
1228 ir_node *proj_res_high;
1230 ia32_address_mode_t am;
1231 ia32_address_t *addr = &am.addr;
1233 assert(!mode_is_float(mode) && "Mulh with float not supported");
1234 assert(get_mode_size_bits(mode) == 32);
1236 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1238 if (mode_is_signed(mode)) {
1239 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1240 addr->index, addr->mem, am.new_op1,
1243 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1244 addr->index, addr->mem, am.new_op1,
1248 set_am_attributes(new_node, &am);
1249 /* we can't use source address mode anymore when using immediates */
1250 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1251 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1252 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1254 assert(get_irn_mode(new_node) == mode_T);
1256 fix_mem_proj(new_node, &am);
1258 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1259 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1260 mode_Iu, pn_ia32_IMul1OP_res_high);
1262 return proj_res_high;
1268 * Creates an ia32 And.
1270 * @return The created ia32 And node
1272 static ir_node *gen_And(ir_node *node) {
1273 ir_node *op1 = get_And_left(node);
1274 ir_node *op2 = get_And_right(node);
1275 assert(! mode_is_float(get_irn_mode(node)));
1277 /* is it a zero extension? */
1278 if (is_Const(op2)) {
1279 tarval *tv = get_Const_tarval(op2);
1280 long v = get_tarval_long(tv);
1282 if (v == 0xFF || v == 0xFFFF) {
1283 dbg_info *dbgi = get_irn_dbg_info(node);
1284 ir_node *block = get_nodes_block(node);
1291 assert(v == 0xFFFF);
1294 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1299 return gen_binop(node, op1, op2, new_rd_ia32_And,
1300 match_commutative | match_mode_neutral | match_am
1307 * Creates an ia32 Or.
1309 * @return The created ia32 Or node
1311 static ir_node *gen_Or(ir_node *node) {
1312 ir_node *op1 = get_Or_left(node);
1313 ir_node *op2 = get_Or_right(node);
1315 assert (! mode_is_float(get_irn_mode(node)));
1316 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1317 | match_mode_neutral | match_am | match_immediate);
1323 * Creates an ia32 Eor.
1325 * @return The created ia32 Eor node
1327 static ir_node *gen_Eor(ir_node *node) {
1328 ir_node *op1 = get_Eor_left(node);
1329 ir_node *op2 = get_Eor_right(node);
1331 assert(! mode_is_float(get_irn_mode(node)));
1332 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1333 | match_mode_neutral | match_am | match_immediate);
1338 * Creates an ia32 Sub.
1340 * @return The created ia32 Sub node
1342 static ir_node *gen_Sub(ir_node *node) {
1343 ir_node *op1 = get_Sub_left(node);
1344 ir_node *op2 = get_Sub_right(node);
1345 ir_mode *mode = get_irn_mode(node);
1347 if (mode_is_float(mode)) {
1348 if (ia32_cg_config.use_sse2)
1349 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1351 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1355 if (is_Const(op2)) {
1356 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1360 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1361 | match_am | match_immediate);
1364 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1365 ir_node *const src_val,
1366 ir_node *const src_mem,
1367 ir_node *const am_mem)
1369 if (is_NoMem(am_mem)) {
1370 return be_transform_node(src_mem);
1371 } else if (is_Proj(src_val) &&
1373 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1374 /* avoid memory loop */
1376 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1377 ir_node *const ptr_pred = get_Proj_pred(src_val);
1378 int const arity = get_Sync_n_preds(src_mem);
1383 NEW_ARR_A(ir_node*, ins, arity + 1);
1385 for (i = arity - 1; i >= 0; --i) {
1386 ir_node *const pred = get_Sync_pred(src_mem, i);
1388 /* avoid memory loop */
1389 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1392 ins[n++] = be_transform_node(pred);
1397 return new_r_Sync(irg, block, n, ins);
1401 ins[0] = be_transform_node(src_mem);
1403 return new_r_Sync(irg, block, 2, ins);
1408 * Generates an ia32 DivMod with additional infrastructure for the
1409 * register allocator if needed.
1411 static ir_node *create_Div(ir_node *node)
1413 ir_graph *irg = current_ir_graph;
1414 dbg_info *dbgi = get_irn_dbg_info(node);
1415 ir_node *block = get_nodes_block(node);
1416 ir_node *new_block = be_transform_node(block);
1423 ir_node *sign_extension;
1424 ia32_address_mode_t am;
1425 ia32_address_t *addr = &am.addr;
1427 /* the upper bits have random contents for smaller modes */
1428 switch (get_irn_opcode(node)) {
1430 op1 = get_Div_left(node);
1431 op2 = get_Div_right(node);
1432 mem = get_Div_mem(node);
1433 mode = get_Div_resmode(node);
1436 op1 = get_Mod_left(node);
1437 op2 = get_Mod_right(node);
1438 mem = get_Mod_mem(node);
1439 mode = get_Mod_resmode(node);
1442 op1 = get_DivMod_left(node);
1443 op2 = get_DivMod_right(node);
1444 mem = get_DivMod_mem(node);
1445 mode = get_DivMod_resmode(node);
1448 panic("invalid divmod node %+F", node);
1451 match_arguments(&am, block, op1, op2, NULL, match_am);
1453 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1454 is the memory of the consumed address. We can have only the second op as address
1455 in Div nodes, so check only op2. */
1456 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1458 if (mode_is_signed(mode)) {
1459 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1460 add_irn_dep(produceval, get_irg_frame(irg));
1461 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1464 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1465 addr->index, new_mem, am.new_op2,
1466 am.new_op1, sign_extension);
1468 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1469 add_irn_dep(sign_extension, get_irg_frame(irg));
1471 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1472 addr->index, new_mem, am.new_op2,
1473 am.new_op1, sign_extension);
1476 set_irn_pinned(new_node, get_irn_pinned(node));
1478 set_am_attributes(new_node, &am);
1479 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1481 new_node = fix_mem_proj(new_node, &am);
1487 static ir_node *gen_Mod(ir_node *node) {
1488 return create_Div(node);
1491 static ir_node *gen_Div(ir_node *node) {
1492 return create_Div(node);
1495 static ir_node *gen_DivMod(ir_node *node) {
1496 return create_Div(node);
1502 * Creates an ia32 floating Div.
1504 * @return The created ia32 xDiv node
1506 static ir_node *gen_Quot(ir_node *node)
1508 ir_node *op1 = get_Quot_left(node);
1509 ir_node *op2 = get_Quot_right(node);
1511 if (ia32_cg_config.use_sse2) {
1512 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1514 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1520 * Creates an ia32 Shl.
1522 * @return The created ia32 Shl node
1524 static ir_node *gen_Shl(ir_node *node) {
1525 ir_node *left = get_Shl_left(node);
1526 ir_node *right = get_Shl_right(node);
1528 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1529 match_mode_neutral | match_immediate);
1533 * Creates an ia32 Shr.
1535 * @return The created ia32 Shr node
1537 static ir_node *gen_Shr(ir_node *node) {
1538 ir_node *left = get_Shr_left(node);
1539 ir_node *right = get_Shr_right(node);
1541 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1547 * Creates an ia32 Sar.
1549 * @return The created ia32 Shrs node
1551 static ir_node *gen_Shrs(ir_node *node) {
1552 ir_node *left = get_Shrs_left(node);
1553 ir_node *right = get_Shrs_right(node);
1554 ir_mode *mode = get_irn_mode(node);
1556 if(is_Const(right) && mode == mode_Is) {
1557 tarval *tv = get_Const_tarval(right);
1558 long val = get_tarval_long(tv);
1560 /* this is a sign extension */
1561 ir_graph *irg = current_ir_graph;
1562 dbg_info *dbgi = get_irn_dbg_info(node);
1563 ir_node *block = be_transform_node(get_nodes_block(node));
1565 ir_node *new_op = be_transform_node(op);
1566 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1567 add_irn_dep(pval, get_irg_frame(irg));
1569 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1573 /* 8 or 16 bit sign extension? */
1574 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1575 ir_node *shl_left = get_Shl_left(left);
1576 ir_node *shl_right = get_Shl_right(left);
1577 if(is_Const(shl_right)) {
1578 tarval *tv1 = get_Const_tarval(right);
1579 tarval *tv2 = get_Const_tarval(shl_right);
1580 if(tv1 == tv2 && tarval_is_long(tv1)) {
1581 long val = get_tarval_long(tv1);
1582 if(val == 16 || val == 24) {
1583 dbg_info *dbgi = get_irn_dbg_info(node);
1584 ir_node *block = get_nodes_block(node);
1594 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1603 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1609 * Creates an ia32 Rol.
1611 * @param op1 The first operator
1612 * @param op2 The second operator
1613 * @return The created ia32 RotL node
1615 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1616 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1622 * Creates an ia32 Ror.
1623 * NOTE: There is no RotR with immediate because this would always be a RotL
1624 * "imm-mode_size_bits" which can be pre-calculated.
1626 * @param op1 The first operator
1627 * @param op2 The second operator
1628 * @return The created ia32 RotR node
1630 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1631 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1637 * Creates an ia32 RotR or RotL (depending on the found pattern).
1639 * @return The created ia32 RotL or RotR node
1641 static ir_node *gen_Rotl(ir_node *node) {
1642 ir_node *rotate = NULL;
1643 ir_node *op1 = get_Rotl_left(node);
1644 ir_node *op2 = get_Rotl_right(node);
1646 /* Firm has only RotL, so we are looking for a right (op2)
1647 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1648 that means we can create a RotR instead of an Add and a RotL */
1652 ir_node *left = get_Add_left(add);
1653 ir_node *right = get_Add_right(add);
1654 if (is_Const(right)) {
1655 tarval *tv = get_Const_tarval(right);
1656 ir_mode *mode = get_irn_mode(node);
1657 long bits = get_mode_size_bits(mode);
1659 if (is_Minus(left) &&
1660 tarval_is_long(tv) &&
1661 get_tarval_long(tv) == bits &&
1664 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1665 rotate = gen_Ror(node, op1, get_Minus_op(left));
1670 if (rotate == NULL) {
1671 rotate = gen_Rol(node, op1, op2);
1680 * Transforms a Minus node.
1682 * @return The created ia32 Minus node
1684 static ir_node *gen_Minus(ir_node *node)
1686 ir_node *op = get_Minus_op(node);
1687 ir_node *block = be_transform_node(get_nodes_block(node));
1688 ir_graph *irg = current_ir_graph;
1689 dbg_info *dbgi = get_irn_dbg_info(node);
1690 ir_mode *mode = get_irn_mode(node);
1695 if (mode_is_float(mode)) {
1696 ir_node *new_op = be_transform_node(op);
1697 if (ia32_cg_config.use_sse2) {
1698 /* TODO: non-optimal... if we have many xXors, then we should
1699 * rather create a load for the const and use that instead of
1700 * several AM nodes... */
1701 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1702 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1703 ir_node *nomem = new_rd_NoMem(irg);
1705 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1706 nomem, new_op, noreg_xmm);
1708 size = get_mode_size_bits(mode);
1709 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1711 set_ia32_am_sc(new_node, ent);
1712 set_ia32_op_type(new_node, ia32_AddrModeS);
1713 set_ia32_ls_mode(new_node, mode);
1715 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1718 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1721 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1727 * Transforms a Not node.
1729 * @return The created ia32 Not node
1731 static ir_node *gen_Not(ir_node *node) {
1732 ir_node *op = get_Not_op(node);
1734 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1735 assert (! mode_is_float(get_irn_mode(node)));
1737 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1743 * Transforms an Abs node.
1745 * @return The created ia32 Abs node
1747 static ir_node *gen_Abs(ir_node *node)
1749 ir_node *block = get_nodes_block(node);
1750 ir_node *new_block = be_transform_node(block);
1751 ir_node *op = get_Abs_op(node);
1752 ir_graph *irg = current_ir_graph;
1753 dbg_info *dbgi = get_irn_dbg_info(node);
1754 ir_mode *mode = get_irn_mode(node);
1755 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1756 ir_node *nomem = new_NoMem();
1762 if (mode_is_float(mode)) {
1763 new_op = be_transform_node(op);
1765 if (ia32_cg_config.use_sse2) {
1766 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1767 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1768 nomem, new_op, noreg_fp);
1770 size = get_mode_size_bits(mode);
1771 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1773 set_ia32_am_sc(new_node, ent);
1775 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1777 set_ia32_op_type(new_node, ia32_AddrModeS);
1778 set_ia32_ls_mode(new_node, mode);
1780 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1781 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1784 ir_node *xor, *pval, *sign_extension;
1786 if (get_mode_size_bits(mode) == 32) {
1787 new_op = be_transform_node(op);
1789 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1792 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1793 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1796 add_irn_dep(pval, get_irg_frame(irg));
1797 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1799 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1800 nomem, new_op, sign_extension);
1801 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1803 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1804 nomem, xor, sign_extension);
1805 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1812 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1814 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1815 dbg_info *dbgi = get_irn_dbg_info(cmp);
1816 ir_node *block = get_nodes_block(cmp);
1817 ir_node *new_block = be_transform_node(block);
1818 ir_node *op1 = be_transform_node(x);
1819 ir_node *op2 = be_transform_node(n);
1821 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1825 * Transform a node returning a "flag" result.
1827 * @param node the node to transform
1828 * @param pnc_out the compare mode to use
1830 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1839 /* we have a Cmp as input */
1840 if (is_Proj(node)) {
1841 ir_node *pred = get_Proj_pred(node);
1843 pn_Cmp pnc = get_Proj_proj(node);
1844 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1845 ir_node *l = get_Cmp_left(pred);
1846 ir_node *r = get_Cmp_right(pred);
1848 ir_node *la = get_And_left(l);
1849 ir_node *ra = get_And_right(l);
1851 ir_node *c = get_Shl_left(la);
1852 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1853 /* (1 << n) & ra) */
1854 ir_node *n = get_Shl_right(la);
1855 flags = gen_bt(pred, ra, n);
1856 /* we must generate a Jc/Jnc jump */
1857 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1860 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1865 ir_node *c = get_Shl_left(ra);
1866 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1867 /* la & (1 << n)) */
1868 ir_node *n = get_Shl_right(ra);
1869 flags = gen_bt(pred, la, n);
1870 /* we must generate a Jc/Jnc jump */
1871 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1874 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1880 flags = be_transform_node(pred);
1886 /* a mode_b value, we have to compare it against 0 */
1887 dbgi = get_irn_dbg_info(node);
1888 new_block = be_transform_node(get_nodes_block(node));
1889 new_op = be_transform_node(node);
1890 noreg = ia32_new_NoReg_gp(env_cg);
1891 nomem = new_NoMem();
1892 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1893 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1894 *pnc_out = pn_Cmp_Lg;
1899 * Transforms a Load.
1901 * @return the created ia32 Load node
1903 static ir_node *gen_Load(ir_node *node) {
1904 ir_node *old_block = get_nodes_block(node);
1905 ir_node *block = be_transform_node(old_block);
1906 ir_node *ptr = get_Load_ptr(node);
1907 ir_node *mem = get_Load_mem(node);
1908 ir_node *new_mem = be_transform_node(mem);
1911 ir_graph *irg = current_ir_graph;
1912 dbg_info *dbgi = get_irn_dbg_info(node);
1913 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1914 ir_mode *mode = get_Load_mode(node);
1917 ia32_address_t addr;
1919 /* construct load address */
1920 memset(&addr, 0, sizeof(addr));
1921 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1928 base = be_transform_node(base);
1934 index = be_transform_node(index);
1937 if (mode_is_float(mode)) {
1938 if (ia32_cg_config.use_sse2) {
1939 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1941 res_mode = mode_xmm;
1943 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1945 res_mode = mode_vfp;
1948 assert(mode != mode_b);
1950 /* create a conv node with address mode for smaller modes */
1951 if(get_mode_size_bits(mode) < 32) {
1952 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1953 new_mem, noreg, mode);
1955 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1960 set_irn_pinned(new_node, get_irn_pinned(node));
1961 set_ia32_op_type(new_node, ia32_AddrModeS);
1962 set_ia32_ls_mode(new_node, mode);
1963 set_address(new_node, &addr);
1965 if(get_irn_pinned(node) == op_pin_state_floats) {
1966 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1969 /* make sure we are scheduled behind the initial IncSP/Barrier
1970 * to avoid spills being placed before it
1972 if (block == get_irg_start_block(irg)) {
1973 add_irn_dep(new_node, get_irg_frame(irg));
1976 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1981 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1982 ir_node *ptr, ir_node *other)
1989 /* we only use address mode if we're the only user of the load */
1990 if (get_irn_n_edges(node) > 1)
1993 load = get_Proj_pred(node);
1996 if (get_nodes_block(load) != block)
1999 /* store should have the same pointer as the load */
2000 if (get_Load_ptr(load) != ptr)
2003 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2004 if (other != NULL &&
2005 get_nodes_block(other) == block &&
2006 heights_reachable_in_block(heights, other, load)) {
2013 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
2014 ir_node *const pred = get_Sync_pred(mem, i);
2016 if (is_Proj(pred) && get_Proj_pred(pred) == load)
2019 if (get_nodes_block(pred) == block &&
2020 heights_reachable_in_block(heights, pred, load)) {
2025 /* Store should be attached to the load */
2026 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
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);
2833 /* matze: code here used mode instead of cmd_mode, I think it is always
2834 * the same as cmp_mode, but I leave this here to see if this is really
2837 assert(get_irn_mode(and_left) == cmp_mode);
2839 match_arguments(&am, block, and_left, and_right, NULL,
2841 match_am | match_8bit_am | match_16bit_am |
2842 match_am_and_immediates | match_immediate |
2843 match_8bit | match_16bit);
2845 /* use 32bit compare mode if possible since the opcode is smaller */
2846 if (upper_bits_clean(am.new_op1, cmp_mode)
2847 && upper_bits_clean(am.new_op2, cmp_mode)) {
2848 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2851 if (get_mode_size_bits(cmp_mode) == 8) {
2852 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2853 addr->index, addr->mem, am.new_op1,
2854 am.new_op2, am.ins_permuted,
2857 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2858 addr->index, addr->mem, am.new_op1,
2859 am.new_op2, am.ins_permuted,
2863 /* Cmp(left, right) */
2864 match_arguments(&am, block, left, right, NULL,
2865 match_commutative | match_am | match_8bit_am |
2866 match_16bit_am | match_am_and_immediates |
2867 match_immediate | match_8bit | match_16bit);
2868 /* use 32bit compare mode if possible since the opcode is smaller */
2869 if (upper_bits_clean(am.new_op1, cmp_mode)
2870 && upper_bits_clean(am.new_op2, cmp_mode)) {
2871 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2874 if (get_mode_size_bits(cmp_mode) == 8) {
2875 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2876 addr->index, addr->mem, am.new_op1,
2877 am.new_op2, am.ins_permuted,
2880 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2881 addr->index, addr->mem, am.new_op1,
2882 am.new_op2, am.ins_permuted, cmp_unsigned);
2885 set_am_attributes(new_node, &am);
2886 set_ia32_ls_mode(new_node, cmp_mode);
2888 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2890 new_node = fix_mem_proj(new_node, &am);
2895 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2898 ir_graph *irg = current_ir_graph;
2899 dbg_info *dbgi = get_irn_dbg_info(node);
2900 ir_node *block = get_nodes_block(node);
2901 ir_node *new_block = be_transform_node(block);
2902 ir_node *val_true = get_Mux_true(node);
2903 ir_node *val_false = get_Mux_false(node);
2905 match_flags_t match_flags;
2906 ia32_address_mode_t am;
2907 ia32_address_t *addr;
2909 assert(ia32_cg_config.use_cmov);
2910 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2914 match_flags = match_commutative | match_am | match_16bit_am |
2917 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2919 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2920 addr->mem, am.new_op1, am.new_op2, new_flags,
2921 am.ins_permuted, pnc);
2922 set_am_attributes(new_node, &am);
2924 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2926 new_node = fix_mem_proj(new_node, &am);
2932 * Creates a ia32 Setcc instruction.
2934 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2935 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2938 ir_graph *irg = current_ir_graph;
2939 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2940 ir_node *nomem = new_NoMem();
2941 ir_mode *mode = get_irn_mode(orig_node);
2944 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2945 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2947 /* we might need to conv the result up */
2948 if (get_mode_size_bits(mode) > 8) {
2949 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2950 nomem, new_node, mode_Bu);
2951 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2958 * Create instruction for an unsigned Difference or Zero.
2960 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2961 ir_graph *irg = current_ir_graph;
2962 ir_mode *mode = get_irn_mode(psi);
2963 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2966 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2967 match_mode_neutral | match_am | match_immediate | match_two_users);
2969 block = get_nodes_block(new_node);
2971 if (is_Proj(new_node)) {
2972 sub = get_Proj_pred(new_node);
2973 assert(is_ia32_Sub(sub));
2976 set_irn_mode(sub, mode_T);
2977 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2979 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2981 dbgi = get_irn_dbg_info(psi);
2982 noreg = ia32_new_NoReg_gp(env_cg);
2983 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2984 nomem = new_NoMem();
2985 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2987 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2988 set_ia32_commutative(new_node);
2993 * Transforms a Mux node into CMov.
2995 * @return The transformed node.
2997 static ir_node *gen_Mux(ir_node *node)
2999 dbg_info *dbgi = get_irn_dbg_info(node);
3000 ir_node *block = get_nodes_block(node);
3001 ir_node *new_block = be_transform_node(block);
3002 ir_node *mux_true = get_Mux_true(node);
3003 ir_node *mux_false = get_Mux_false(node);
3004 ir_node *cond = get_Mux_sel(node);
3005 ir_mode *mode = get_irn_mode(node);
3008 assert(get_irn_mode(cond) == mode_b);
3010 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3011 if (mode_is_float(mode)) {
3012 ir_node *cmp = get_Proj_pred(cond);
3013 ir_node *cmp_left = get_Cmp_left(cmp);
3014 ir_node *cmp_right = get_Cmp_right(cmp);
3015 pn_Cmp pnc = get_Proj_proj(cond);
3017 if (ia32_cg_config.use_sse2) {
3018 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3019 if (cmp_left == mux_true && cmp_right == mux_false) {
3020 /* Mux(a <= b, a, b) => MIN */
3021 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3022 match_commutative | match_am | match_two_users);
3023 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3024 /* Mux(a <= b, b, a) => MAX */
3025 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3026 match_commutative | match_am | match_two_users);
3028 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3029 if (cmp_left == mux_true && cmp_right == mux_false) {
3030 /* Mux(a >= b, a, b) => MAX */
3031 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3032 match_commutative | match_am | match_two_users);
3033 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3034 /* Mux(a >= b, b, a) => MIN */
3035 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3036 match_commutative | match_am | match_two_users);
3040 panic("cannot transform floating point Mux");
3046 assert(ia32_mode_needs_gp_reg(mode));
3048 if (is_Proj(cond)) {
3049 ir_node *cmp = get_Proj_pred(cond);
3051 ir_node *cmp_left = get_Cmp_left(cmp);
3052 ir_node *cmp_right = get_Cmp_right(cmp);
3053 pn_Cmp pnc = get_Proj_proj(cond);
3055 /* check for unsigned Doz first */
3056 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3057 is_Const_0(mux_false) && is_Sub(mux_true) &&
3058 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3059 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3060 return create_Doz(node, cmp_left, cmp_right);
3061 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3062 is_Const_0(mux_true) && is_Sub(mux_false) &&
3063 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3064 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3065 return create_Doz(node, cmp_left, cmp_right);
3070 flags = get_flags_node(cond, &pnc);
3072 if (is_Const(mux_true) && is_Const(mux_false)) {
3073 /* both are const, good */
3074 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3075 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3076 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3077 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3079 /* Not that simple. */
3084 new_node = create_CMov(node, cond, flags, pnc);
3092 * Create a conversion from x87 state register to general purpose.
3094 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3095 ir_node *block = be_transform_node(get_nodes_block(node));
3096 ir_node *op = get_Conv_op(node);
3097 ir_node *new_op = be_transform_node(op);
3098 ia32_code_gen_t *cg = env_cg;
3099 ir_graph *irg = current_ir_graph;
3100 dbg_info *dbgi = get_irn_dbg_info(node);
3101 ir_node *noreg = ia32_new_NoReg_gp(cg);
3102 ir_mode *mode = get_irn_mode(node);
3103 ir_node *fist, *load, *mem;
3105 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3106 set_irn_pinned(fist, op_pin_state_floats);
3107 set_ia32_use_frame(fist);
3108 set_ia32_op_type(fist, ia32_AddrModeD);
3110 assert(get_mode_size_bits(mode) <= 32);
3111 /* exception we can only store signed 32 bit integers, so for unsigned
3112 we store a 64bit (signed) integer and load the lower bits */
3113 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3114 set_ia32_ls_mode(fist, mode_Ls);
3116 set_ia32_ls_mode(fist, mode_Is);
3118 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3121 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3123 set_irn_pinned(load, op_pin_state_floats);
3124 set_ia32_use_frame(load);
3125 set_ia32_op_type(load, ia32_AddrModeS);
3126 set_ia32_ls_mode(load, mode_Is);
3127 if(get_ia32_ls_mode(fist) == mode_Ls) {
3128 ia32_attr_t *attr = get_ia32_attr(load);
3129 attr->data.need_64bit_stackent = 1;
3131 ia32_attr_t *attr = get_ia32_attr(load);
3132 attr->data.need_32bit_stackent = 1;
3134 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3136 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3140 * Creates a x87 strict Conv by placing a Store and a Load
3142 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3144 ir_node *block = get_nodes_block(node);
3145 ir_graph *irg = current_ir_graph;
3146 dbg_info *dbgi = get_irn_dbg_info(node);
3147 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3148 ir_node *nomem = new_NoMem();
3149 ir_node *frame = get_irg_frame(irg);
3150 ir_node *store, *load;
3153 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3155 set_ia32_use_frame(store);
3156 set_ia32_op_type(store, ia32_AddrModeD);
3157 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3159 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3161 set_ia32_use_frame(load);
3162 set_ia32_op_type(load, ia32_AddrModeS);
3163 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3165 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3170 * Create a conversion from general purpose to x87 register
3172 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3173 ir_node *src_block = get_nodes_block(node);
3174 ir_node *block = be_transform_node(src_block);
3175 ir_graph *irg = current_ir_graph;
3176 dbg_info *dbgi = get_irn_dbg_info(node);
3177 ir_node *op = get_Conv_op(node);
3178 ir_node *new_op = NULL;
3182 ir_mode *store_mode;
3188 /* fild can use source AM if the operand is a signed 32bit integer */
3189 if (src_mode == mode_Is) {
3190 ia32_address_mode_t am;
3192 match_arguments(&am, src_block, NULL, op, NULL,
3193 match_am | match_try_am);
3194 if (am.op_type == ia32_AddrModeS) {
3195 ia32_address_t *addr = &am.addr;
3197 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3198 addr->index, addr->mem);
3199 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3202 set_am_attributes(fild, &am);
3203 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3205 fix_mem_proj(fild, &am);
3210 if(new_op == NULL) {
3211 new_op = be_transform_node(op);
3214 noreg = ia32_new_NoReg_gp(env_cg);
3215 nomem = new_NoMem();
3216 mode = get_irn_mode(op);
3218 /* first convert to 32 bit signed if necessary */
3219 src_bits = get_mode_size_bits(src_mode);
3220 if (src_bits == 8) {
3221 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3223 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3225 } else if (src_bits < 32) {
3226 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3228 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3232 assert(get_mode_size_bits(mode) == 32);
3235 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3238 set_ia32_use_frame(store);
3239 set_ia32_op_type(store, ia32_AddrModeD);
3240 set_ia32_ls_mode(store, mode_Iu);
3242 /* exception for 32bit unsigned, do a 64bit spill+load */
3243 if(!mode_is_signed(mode)) {
3246 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3248 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3249 get_irg_frame(irg), noreg, nomem,
3252 set_ia32_use_frame(zero_store);
3253 set_ia32_op_type(zero_store, ia32_AddrModeD);
3254 add_ia32_am_offs_int(zero_store, 4);
3255 set_ia32_ls_mode(zero_store, mode_Iu);
3260 store = new_rd_Sync(dbgi, irg, block, 2, in);
3261 store_mode = mode_Ls;
3263 store_mode = mode_Is;
3267 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3269 set_ia32_use_frame(fild);
3270 set_ia32_op_type(fild, ia32_AddrModeS);
3271 set_ia32_ls_mode(fild, store_mode);
3273 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3279 * Create a conversion from one integer mode into another one
3281 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3282 dbg_info *dbgi, ir_node *block, ir_node *op,
3285 ir_graph *irg = current_ir_graph;
3286 int src_bits = get_mode_size_bits(src_mode);
3287 int tgt_bits = get_mode_size_bits(tgt_mode);
3288 ir_node *new_block = be_transform_node(block);
3290 ir_mode *smaller_mode;
3292 ia32_address_mode_t am;
3293 ia32_address_t *addr = &am.addr;
3296 if (src_bits < tgt_bits) {
3297 smaller_mode = src_mode;
3298 smaller_bits = src_bits;
3300 smaller_mode = tgt_mode;
3301 smaller_bits = tgt_bits;
3304 #ifdef DEBUG_libfirm
3306 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3311 match_arguments(&am, block, NULL, op, NULL,
3312 match_8bit | match_16bit |
3313 match_am | match_8bit_am | match_16bit_am);
3315 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3316 /* unnecessary conv. in theory it shouldn't have been AM */
3317 assert(is_ia32_NoReg_GP(addr->base));
3318 assert(is_ia32_NoReg_GP(addr->index));
3319 assert(is_NoMem(addr->mem));
3320 assert(am.addr.offset == 0);
3321 assert(am.addr.symconst_ent == NULL);
3325 if (smaller_bits == 8) {
3326 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3327 addr->index, addr->mem, am.new_op2,
3330 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3331 addr->index, addr->mem, am.new_op2,
3334 set_am_attributes(new_node, &am);
3335 /* match_arguments assume that out-mode = in-mode, this isn't true here
3337 set_ia32_ls_mode(new_node, smaller_mode);
3338 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3339 new_node = fix_mem_proj(new_node, &am);
3344 * Transforms a Conv node.
3346 * @return The created ia32 Conv node
3348 static ir_node *gen_Conv(ir_node *node) {
3349 ir_node *block = get_nodes_block(node);
3350 ir_node *new_block = be_transform_node(block);
3351 ir_node *op = get_Conv_op(node);
3352 ir_node *new_op = NULL;
3353 ir_graph *irg = current_ir_graph;
3354 dbg_info *dbgi = get_irn_dbg_info(node);
3355 ir_mode *src_mode = get_irn_mode(op);
3356 ir_mode *tgt_mode = get_irn_mode(node);
3357 int src_bits = get_mode_size_bits(src_mode);
3358 int tgt_bits = get_mode_size_bits(tgt_mode);
3359 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3360 ir_node *nomem = new_rd_NoMem(irg);
3361 ir_node *res = NULL;
3363 if (src_mode == mode_b) {
3364 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3365 /* nothing to do, we already model bools as 0/1 ints */
3366 return be_transform_node(op);
3369 if (src_mode == tgt_mode) {
3370 if (get_Conv_strict(node)) {
3371 if (ia32_cg_config.use_sse2) {
3372 /* when we are in SSE mode, we can kill all strict no-op conversion */
3373 return be_transform_node(op);
3376 /* this should be optimized already, but who knows... */
3377 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3378 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3379 return be_transform_node(op);
3383 if (mode_is_float(src_mode)) {
3384 new_op = be_transform_node(op);
3385 /* we convert from float ... */
3386 if (mode_is_float(tgt_mode)) {
3387 if(src_mode == mode_E && tgt_mode == mode_D
3388 && !get_Conv_strict(node)) {
3389 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3394 if (ia32_cg_config.use_sse2) {
3395 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3396 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3398 set_ia32_ls_mode(res, tgt_mode);
3400 if(get_Conv_strict(node)) {
3401 res = gen_x87_strict_conv(tgt_mode, new_op);
3402 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3405 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3410 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3411 if (ia32_cg_config.use_sse2) {
3412 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3414 set_ia32_ls_mode(res, src_mode);
3416 return gen_x87_fp_to_gp(node);
3420 /* we convert from int ... */
3421 if (mode_is_float(tgt_mode)) {
3423 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3424 if (ia32_cg_config.use_sse2) {
3425 new_op = be_transform_node(op);
3426 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3428 set_ia32_ls_mode(res, tgt_mode);
3430 res = gen_x87_gp_to_fp(node, src_mode);
3431 if(get_Conv_strict(node)) {
3432 /* The strict-Conv is only necessary, if the int mode has more bits
3433 * than the float mantissa */
3434 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3435 size_t float_mantissa;
3436 /* FIXME There is no way to get the mantissa size of a mode */
3437 switch (get_mode_size_bits(tgt_mode)) {
3438 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3439 case 64: float_mantissa = 52 + 1; break;
3441 case 96: float_mantissa = 64; break;
3442 default: float_mantissa = 0; break;
3444 if (float_mantissa < int_mantissa) {
3445 res = gen_x87_strict_conv(tgt_mode, res);
3446 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3451 } else if(tgt_mode == mode_b) {
3452 /* mode_b lowering already took care that we only have 0/1 values */
3453 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3454 src_mode, tgt_mode));
3455 return be_transform_node(op);
3458 if (src_bits == tgt_bits) {
3459 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3460 src_mode, tgt_mode));
3461 return be_transform_node(op);
3464 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3472 static ir_node *create_immediate_or_transform(ir_node *node,
3473 char immediate_constraint_type)
3475 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3476 if (new_node == NULL) {
3477 new_node = be_transform_node(node);
3483 * Transforms a FrameAddr into an ia32 Add.
3485 static ir_node *gen_be_FrameAddr(ir_node *node) {
3486 ir_node *block = be_transform_node(get_nodes_block(node));
3487 ir_node *op = be_get_FrameAddr_frame(node);
3488 ir_node *new_op = be_transform_node(op);
3489 ir_graph *irg = current_ir_graph;
3490 dbg_info *dbgi = get_irn_dbg_info(node);
3491 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3494 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3495 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3496 set_ia32_use_frame(new_node);
3498 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3504 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3506 static ir_node *gen_be_Return(ir_node *node) {
3507 ir_graph *irg = current_ir_graph;
3508 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3509 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3510 ir_entity *ent = get_irg_entity(irg);
3511 ir_type *tp = get_entity_type(ent);
3516 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3517 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3520 int pn_ret_val, pn_ret_mem, arity, i;
3522 assert(ret_val != NULL);
3523 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3524 return be_duplicate_node(node);
3527 res_type = get_method_res_type(tp, 0);
3529 if (! is_Primitive_type(res_type)) {
3530 return be_duplicate_node(node);
3533 mode = get_type_mode(res_type);
3534 if (! mode_is_float(mode)) {
3535 return be_duplicate_node(node);
3538 assert(get_method_n_ress(tp) == 1);
3540 pn_ret_val = get_Proj_proj(ret_val);
3541 pn_ret_mem = get_Proj_proj(ret_mem);
3543 /* get the Barrier */
3544 barrier = get_Proj_pred(ret_val);
3546 /* get result input of the Barrier */
3547 ret_val = get_irn_n(barrier, pn_ret_val);
3548 new_ret_val = be_transform_node(ret_val);
3550 /* get memory input of the Barrier */
3551 ret_mem = get_irn_n(barrier, pn_ret_mem);
3552 new_ret_mem = be_transform_node(ret_mem);
3554 frame = get_irg_frame(irg);
3556 dbgi = get_irn_dbg_info(barrier);
3557 block = be_transform_node(get_nodes_block(barrier));
3559 noreg = ia32_new_NoReg_gp(env_cg);
3561 /* store xmm0 onto stack */
3562 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3563 new_ret_mem, new_ret_val);
3564 set_ia32_ls_mode(sse_store, mode);
3565 set_ia32_op_type(sse_store, ia32_AddrModeD);
3566 set_ia32_use_frame(sse_store);
3568 /* load into x87 register */
3569 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3570 set_ia32_op_type(fld, ia32_AddrModeS);
3571 set_ia32_use_frame(fld);
3573 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3574 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3576 /* create a new barrier */
3577 arity = get_irn_arity(barrier);
3578 in = alloca(arity * sizeof(in[0]));
3579 for (i = 0; i < arity; ++i) {
3582 if (i == pn_ret_val) {
3584 } else if (i == pn_ret_mem) {
3587 ir_node *in = get_irn_n(barrier, i);
3588 new_in = be_transform_node(in);
3593 new_barrier = new_ir_node(dbgi, irg, block,
3594 get_irn_op(barrier), get_irn_mode(barrier),
3596 copy_node_attr(barrier, new_barrier);
3597 be_duplicate_deps(barrier, new_barrier);
3598 set_transformed_and_mark(barrier, new_barrier);
3600 /* transform normally */
3601 return be_duplicate_node(node);
3605 * Transform a be_AddSP into an ia32_SubSP.
3607 static ir_node *gen_be_AddSP(ir_node *node)
3609 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3610 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3612 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3613 match_am | match_immediate);
3617 * Transform a be_SubSP into an ia32_AddSP
3619 static ir_node *gen_be_SubSP(ir_node *node)
3621 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3622 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3624 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3625 match_am | match_immediate);
3629 * Change some phi modes
3631 static ir_node *gen_Phi(ir_node *node) {
3632 ir_node *block = be_transform_node(get_nodes_block(node));
3633 ir_graph *irg = current_ir_graph;
3634 dbg_info *dbgi = get_irn_dbg_info(node);
3635 ir_mode *mode = get_irn_mode(node);
3638 if(ia32_mode_needs_gp_reg(mode)) {
3639 /* we shouldn't have any 64bit stuff around anymore */
3640 assert(get_mode_size_bits(mode) <= 32);
3641 /* all integer operations are on 32bit registers now */
3643 } else if(mode_is_float(mode)) {
3644 if (ia32_cg_config.use_sse2) {
3651 /* phi nodes allow loops, so we use the old arguments for now
3652 * and fix this later */
3653 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3654 get_irn_in(node) + 1);
3655 copy_node_attr(node, phi);
3656 be_duplicate_deps(node, phi);
3658 be_set_transformed_node(node, phi);
3659 be_enqueue_preds(node);
3667 static ir_node *gen_IJmp(ir_node *node)
3669 ir_node *block = get_nodes_block(node);
3670 ir_node *new_block = be_transform_node(block);
3671 dbg_info *dbgi = get_irn_dbg_info(node);
3672 ir_node *op = get_IJmp_target(node);
3674 ia32_address_mode_t am;
3675 ia32_address_t *addr = &am.addr;
3677 assert(get_irn_mode(op) == mode_P);
3679 match_arguments(&am, block, NULL, op, NULL,
3680 match_am | match_8bit_am | match_16bit_am |
3681 match_immediate | match_8bit | match_16bit);
3683 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3684 addr->base, addr->index, addr->mem,
3686 set_am_attributes(new_node, &am);
3687 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3689 new_node = fix_mem_proj(new_node, &am);
3695 * Transform a Bound node.
3697 static ir_node *gen_Bound(ir_node *node)
3700 ir_node *lower = get_Bound_lower(node);
3701 dbg_info *dbgi = get_irn_dbg_info(node);
3703 if (is_Const_0(lower)) {
3704 /* typical case for Java */
3705 ir_node *sub, *res, *flags, *block;
3706 ir_graph *irg = current_ir_graph;
3708 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3709 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3711 block = get_nodes_block(res);
3712 if (! is_Proj(res)) {
3714 set_irn_mode(sub, mode_T);
3715 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3717 sub = get_Proj_pred(res);
3719 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3720 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3721 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3723 panic("generic Bound not supported in ia32 Backend");
3729 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3731 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3732 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3734 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3735 match_immediate | match_mode_neutral);
3738 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3740 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3741 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3742 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3746 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3748 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3749 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3750 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3754 static ir_node *gen_ia32_l_Add(ir_node *node) {
3755 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3756 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3757 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3758 match_commutative | match_am | match_immediate |
3759 match_mode_neutral);
3761 if(is_Proj(lowered)) {
3762 lowered = get_Proj_pred(lowered);
3764 assert(is_ia32_Add(lowered));
3765 set_irn_mode(lowered, mode_T);
3771 static ir_node *gen_ia32_l_Adc(ir_node *node)
3773 return gen_binop_flags(node, new_rd_ia32_Adc,
3774 match_commutative | match_am | match_immediate |
3775 match_mode_neutral);
3779 * Transforms a l_MulS into a "real" MulS node.
3781 * @return the created ia32 Mul node
3783 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3784 ir_node *left = get_binop_left(node);
3785 ir_node *right = get_binop_right(node);
3787 return gen_binop(node, left, right, new_rd_ia32_Mul,
3788 match_commutative | match_am | match_mode_neutral);
3792 * Transforms a l_IMulS into a "real" IMul1OPS node.
3794 * @return the created ia32 IMul1OP node
3796 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3797 ir_node *left = get_binop_left(node);
3798 ir_node *right = get_binop_right(node);
3800 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3801 match_commutative | match_am | match_mode_neutral);
3804 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3805 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3806 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3807 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3808 match_am | match_immediate | match_mode_neutral);
3810 if(is_Proj(lowered)) {
3811 lowered = get_Proj_pred(lowered);
3813 assert(is_ia32_Sub(lowered));
3814 set_irn_mode(lowered, mode_T);
3820 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3821 return gen_binop_flags(node, new_rd_ia32_Sbb,
3822 match_am | match_immediate | match_mode_neutral);
3826 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3827 * op1 - target to be shifted
3828 * op2 - contains bits to be shifted into target
3830 * Only op3 can be an immediate.
3832 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3833 ir_node *low, ir_node *count)
3835 ir_node *block = get_nodes_block(node);
3836 ir_node *new_block = be_transform_node(block);
3837 ir_graph *irg = current_ir_graph;
3838 dbg_info *dbgi = get_irn_dbg_info(node);
3839 ir_node *new_high = be_transform_node(high);
3840 ir_node *new_low = be_transform_node(low);
3844 /* the shift amount can be any mode that is bigger than 5 bits, since all
3845 * other bits are ignored anyway */
3846 while (is_Conv(count) &&
3847 get_irn_n_edges(count) == 1 &&
3848 mode_is_int(get_irn_mode(count))) {
3849 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3850 count = get_Conv_op(count);
3852 new_count = create_immediate_or_transform(count, 0);
3854 if (is_ia32_l_ShlD(node)) {
3855 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3858 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3861 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3866 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3868 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3869 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3870 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3871 return gen_lowered_64bit_shifts(node, high, low, count);
3874 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3876 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3877 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3878 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3879 return gen_lowered_64bit_shifts(node, high, low, count);
3882 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3883 ir_node *src_block = get_nodes_block(node);
3884 ir_node *block = be_transform_node(src_block);
3885 ir_graph *irg = current_ir_graph;
3886 dbg_info *dbgi = get_irn_dbg_info(node);
3887 ir_node *frame = get_irg_frame(irg);
3888 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3889 ir_node *nomem = new_NoMem();
3890 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3891 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3892 ir_node *new_val_low = be_transform_node(val_low);
3893 ir_node *new_val_high = be_transform_node(val_high);
3898 ir_node *store_high;
3900 if(!mode_is_signed(get_irn_mode(val_high))) {
3901 panic("unsigned long long -> float not supported yet (%+F)", node);
3905 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3907 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3909 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3910 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3912 set_ia32_use_frame(store_low);
3913 set_ia32_use_frame(store_high);
3914 set_ia32_op_type(store_low, ia32_AddrModeD);
3915 set_ia32_op_type(store_high, ia32_AddrModeD);
3916 set_ia32_ls_mode(store_low, mode_Iu);
3917 set_ia32_ls_mode(store_high, mode_Is);
3918 add_ia32_am_offs_int(store_high, 4);
3922 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3925 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3927 set_ia32_use_frame(fild);
3928 set_ia32_op_type(fild, ia32_AddrModeS);
3929 set_ia32_ls_mode(fild, mode_Ls);
3931 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3933 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3936 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3937 ir_node *src_block = get_nodes_block(node);
3938 ir_node *block = be_transform_node(src_block);
3939 ir_graph *irg = current_ir_graph;
3940 dbg_info *dbgi = get_irn_dbg_info(node);
3941 ir_node *frame = get_irg_frame(irg);
3942 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3943 ir_node *nomem = new_NoMem();
3944 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3945 ir_node *new_val = be_transform_node(val);
3946 ir_node *fist, *mem;
3948 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3949 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3950 set_ia32_use_frame(fist);
3951 set_ia32_op_type(fist, ia32_AddrModeD);
3952 set_ia32_ls_mode(fist, mode_Ls);
3958 * the BAD transformer.
3960 static ir_node *bad_transform(ir_node *node) {
3961 panic("No transform function for %+F available.", node);
3965 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
3966 ir_graph *irg = current_ir_graph;
3967 ir_node *block = be_transform_node(get_nodes_block(node));
3968 ir_node *pred = get_Proj_pred(node);
3969 ir_node *new_pred = be_transform_node(pred);
3970 ir_node *frame = get_irg_frame(irg);
3971 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3972 dbg_info *dbgi = get_irn_dbg_info(node);
3973 long pn = get_Proj_proj(node);
3978 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3979 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3980 set_ia32_use_frame(load);
3981 set_ia32_op_type(load, ia32_AddrModeS);
3982 set_ia32_ls_mode(load, mode_Iu);
3983 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3984 * 32 bit from it with this particular load */
3985 attr = get_ia32_attr(load);
3986 attr->data.need_64bit_stackent = 1;
3988 if (pn == pn_ia32_l_FloattoLL_res_high) {
3989 add_ia32_am_offs_int(load, 4);
3991 assert(pn == pn_ia32_l_FloattoLL_res_low);
3994 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4000 * Transform the Projs of an AddSP.
4002 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4003 ir_node *block = be_transform_node(get_nodes_block(node));
4004 ir_node *pred = get_Proj_pred(node);
4005 ir_node *new_pred = be_transform_node(pred);
4006 ir_graph *irg = current_ir_graph;
4007 dbg_info *dbgi = get_irn_dbg_info(node);
4008 long proj = get_Proj_proj(node);
4010 if (proj == pn_be_AddSP_sp) {
4011 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4012 pn_ia32_SubSP_stack);
4013 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4015 } else if(proj == pn_be_AddSP_res) {
4016 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4017 pn_ia32_SubSP_addr);
4018 } else if (proj == pn_be_AddSP_M) {
4019 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4022 panic("No idea how to transform proj->AddSP");
4026 * Transform the Projs of a SubSP.
4028 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4029 ir_node *block = be_transform_node(get_nodes_block(node));
4030 ir_node *pred = get_Proj_pred(node);
4031 ir_node *new_pred = be_transform_node(pred);
4032 ir_graph *irg = current_ir_graph;
4033 dbg_info *dbgi = get_irn_dbg_info(node);
4034 long proj = get_Proj_proj(node);
4036 if (proj == pn_be_SubSP_sp) {
4037 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4038 pn_ia32_AddSP_stack);
4039 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4041 } else if (proj == pn_be_SubSP_M) {
4042 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4045 panic("No idea how to transform proj->SubSP");
4049 * Transform and renumber the Projs from a Load.
4051 static ir_node *gen_Proj_Load(ir_node *node) {
4053 ir_node *block = be_transform_node(get_nodes_block(node));
4054 ir_node *pred = get_Proj_pred(node);
4055 ir_graph *irg = current_ir_graph;
4056 dbg_info *dbgi = get_irn_dbg_info(node);
4057 long proj = get_Proj_proj(node);
4059 /* loads might be part of source address mode matches, so we don't
4060 * transform the ProjMs yet (with the exception of loads whose result is
4063 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4066 /* this is needed, because sometimes we have loops that are only
4067 reachable through the ProjM */
4068 be_enqueue_preds(node);
4069 /* do it in 2 steps, to silence firm verifier */
4070 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4071 set_Proj_proj(res, pn_ia32_mem);
4075 /* renumber the proj */
4076 new_pred = be_transform_node(pred);
4077 if (is_ia32_Load(new_pred)) {
4080 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4082 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4083 case pn_Load_X_regular:
4084 return new_rd_Jmp(dbgi, irg, block);
4085 case pn_Load_X_except:
4086 /* This Load might raise an exception. Mark it. */
4087 set_ia32_exc_label(new_pred, 1);
4088 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4092 } else if (is_ia32_Conv_I2I(new_pred) ||
4093 is_ia32_Conv_I2I8Bit(new_pred)) {
4094 set_irn_mode(new_pred, mode_T);
4095 if (proj == pn_Load_res) {
4096 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4097 } else if (proj == pn_Load_M) {
4098 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4100 } else if (is_ia32_xLoad(new_pred)) {
4103 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4105 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4106 case pn_Load_X_regular:
4107 return new_rd_Jmp(dbgi, irg, block);
4108 case pn_Load_X_except:
4109 /* This Load might raise an exception. Mark it. */
4110 set_ia32_exc_label(new_pred, 1);
4111 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4115 } else if (is_ia32_vfld(new_pred)) {
4118 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4120 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4121 case pn_Load_X_regular:
4122 return new_rd_Jmp(dbgi, irg, block);
4123 case pn_Load_X_except:
4124 /* This Load might raise an exception. Mark it. */
4125 set_ia32_exc_label(new_pred, 1);
4126 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4131 /* can happen for ProJMs when source address mode happened for the
4134 /* however it should not be the result proj, as that would mean the
4135 load had multiple users and should not have been used for
4137 if (proj != pn_Load_M) {
4138 panic("internal error: transformed node not a Load");
4140 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4143 panic("No idea how to transform proj");
4147 * Transform and renumber the Projs from a DivMod like instruction.
4149 static ir_node *gen_Proj_DivMod(ir_node *node) {
4150 ir_node *block = be_transform_node(get_nodes_block(node));
4151 ir_node *pred = get_Proj_pred(node);
4152 ir_node *new_pred = be_transform_node(pred);
4153 ir_graph *irg = current_ir_graph;
4154 dbg_info *dbgi = get_irn_dbg_info(node);
4155 long proj = get_Proj_proj(node);
4157 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4159 switch (get_irn_opcode(pred)) {
4163 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4165 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4166 case pn_Div_X_regular:
4167 return new_rd_Jmp(dbgi, irg, block);
4168 case pn_Div_X_except:
4169 set_ia32_exc_label(new_pred, 1);
4170 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4178 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4180 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4181 case pn_Mod_X_except:
4182 set_ia32_exc_label(new_pred, 1);
4183 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4191 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4192 case pn_DivMod_res_div:
4193 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4194 case pn_DivMod_res_mod:
4195 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4196 case pn_DivMod_X_regular:
4197 return new_rd_Jmp(dbgi, irg, block);
4198 case pn_DivMod_X_except:
4199 set_ia32_exc_label(new_pred, 1);
4200 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4209 panic("No idea how to transform proj->DivMod");
4213 * Transform and renumber the Projs from a CopyB.
4215 static ir_node *gen_Proj_CopyB(ir_node *node) {
4216 ir_node *block = be_transform_node(get_nodes_block(node));
4217 ir_node *pred = get_Proj_pred(node);
4218 ir_node *new_pred = be_transform_node(pred);
4219 ir_graph *irg = current_ir_graph;
4220 dbg_info *dbgi = get_irn_dbg_info(node);
4221 long proj = get_Proj_proj(node);
4224 case pn_CopyB_M_regular:
4225 if (is_ia32_CopyB_i(new_pred)) {
4226 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4227 } else if (is_ia32_CopyB(new_pred)) {
4228 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4235 panic("No idea how to transform proj->CopyB");
4239 * Transform and renumber the Projs from a Quot.
4241 static ir_node *gen_Proj_Quot(ir_node *node) {
4242 ir_node *block = be_transform_node(get_nodes_block(node));
4243 ir_node *pred = get_Proj_pred(node);
4244 ir_node *new_pred = be_transform_node(pred);
4245 ir_graph *irg = current_ir_graph;
4246 dbg_info *dbgi = get_irn_dbg_info(node);
4247 long proj = get_Proj_proj(node);
4251 if (is_ia32_xDiv(new_pred)) {
4252 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4253 } else if (is_ia32_vfdiv(new_pred)) {
4254 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4258 if (is_ia32_xDiv(new_pred)) {
4259 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4260 } else if (is_ia32_vfdiv(new_pred)) {
4261 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4264 case pn_Quot_X_regular:
4265 case pn_Quot_X_except:
4270 panic("No idea how to transform proj->Quot");
4273 static ir_node *gen_be_Call(ir_node *node) {
4274 ir_node *res = be_duplicate_node(node);
4277 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4279 /* Run the x87 simulator if the call returns a float value */
4280 call_tp = be_Call_get_type(node);
4281 if (get_method_n_ress(call_tp) > 0) {
4282 ir_type *const res_type = get_method_res_type(call_tp, 0);
4283 ir_mode *const res_mode = get_type_mode(res_type);
4285 if (res_mode != NULL && mode_is_float(res_mode)) {
4286 env_cg->do_x87_sim = 1;
4293 static ir_node *gen_be_IncSP(ir_node *node) {
4294 ir_node *res = be_duplicate_node(node);
4295 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4301 * Transform the Projs from a be_Call.
4303 static ir_node *gen_Proj_be_Call(ir_node *node) {
4304 ir_node *block = be_transform_node(get_nodes_block(node));
4305 ir_node *call = get_Proj_pred(node);
4306 ir_node *new_call = be_transform_node(call);
4307 ir_graph *irg = current_ir_graph;
4308 dbg_info *dbgi = get_irn_dbg_info(node);
4309 ir_type *method_type = be_Call_get_type(call);
4310 int n_res = get_method_n_ress(method_type);
4311 long proj = get_Proj_proj(node);
4312 ir_mode *mode = get_irn_mode(node);
4314 const arch_register_class_t *cls;
4316 /* The following is kinda tricky: If we're using SSE, then we have to
4317 * move the result value of the call in floating point registers to an
4318 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4319 * after the call, we have to make sure to correctly make the
4320 * MemProj and the result Proj use these 2 nodes
4322 if (proj == pn_be_Call_M_regular) {
4323 // get new node for result, are we doing the sse load/store hack?
4324 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4325 ir_node *call_res_new;
4326 ir_node *call_res_pred = NULL;
4328 if (call_res != NULL) {
4329 call_res_new = be_transform_node(call_res);
4330 call_res_pred = get_Proj_pred(call_res_new);
4333 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4334 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4335 pn_be_Call_M_regular);
4337 assert(is_ia32_xLoad(call_res_pred));
4338 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4342 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4343 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4345 ir_node *frame = get_irg_frame(irg);
4346 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4348 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4351 /* in case there is no memory output: create one to serialize the copy
4353 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4354 pn_be_Call_M_regular);
4355 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4356 pn_be_Call_first_res);
4358 /* store st(0) onto stack */
4359 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4361 set_ia32_op_type(fstp, ia32_AddrModeD);
4362 set_ia32_use_frame(fstp);
4364 /* load into SSE register */
4365 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4367 set_ia32_op_type(sse_load, ia32_AddrModeS);
4368 set_ia32_use_frame(sse_load);
4370 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4376 /* transform call modes */
4377 if (mode_is_data(mode)) {
4378 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4382 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4386 * Transform the Projs from a Cmp.
4388 static ir_node *gen_Proj_Cmp(ir_node *node)
4390 /* this probably means not all mode_b nodes were lowered... */
4391 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4396 * Transform the Projs from a Bound.
4398 static ir_node *gen_Proj_Bound(ir_node *node)
4400 ir_node *new_node, *block;
4401 ir_node *pred = get_Proj_pred(node);
4403 switch (get_Proj_proj(node)) {
4405 return be_transform_node(get_Bound_mem(pred));
4406 case pn_Bound_X_regular:
4407 new_node = be_transform_node(pred);
4408 block = get_nodes_block(new_node);
4409 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4410 case pn_Bound_X_except:
4411 new_node = be_transform_node(pred);
4412 block = get_nodes_block(new_node);
4413 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4415 return be_transform_node(get_Bound_index(pred));
4417 panic("unsupported Proj from Bound");
4421 static ir_node *gen_Proj_ASM(ir_node *node)
4427 if (get_irn_mode(node) != mode_M)
4428 return be_duplicate_node(node);
4430 pred = get_Proj_pred(node);
4431 new_pred = be_transform_node(pred);
4432 block = get_nodes_block(new_pred);
4433 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4434 get_ia32_n_res(new_pred) + 1);
4438 * Transform and potentially renumber Proj nodes.
4440 static ir_node *gen_Proj(ir_node *node) {
4441 ir_node *pred = get_Proj_pred(node);
4444 switch (get_irn_opcode(pred)) {
4446 proj = get_Proj_proj(node);
4447 if (proj == pn_Store_M) {
4448 return be_transform_node(pred);
4450 panic("No idea how to transform proj->Store");
4453 return gen_Proj_Load(node);
4455 return gen_Proj_ASM(node);
4459 return gen_Proj_DivMod(node);
4461 return gen_Proj_CopyB(node);
4463 return gen_Proj_Quot(node);
4465 return gen_Proj_be_SubSP(node);
4467 return gen_Proj_be_AddSP(node);
4469 return gen_Proj_be_Call(node);
4471 return gen_Proj_Cmp(node);
4473 return gen_Proj_Bound(node);
4475 proj = get_Proj_proj(node);
4476 if (proj == pn_Start_X_initial_exec) {
4477 ir_node *block = get_nodes_block(pred);
4478 dbg_info *dbgi = get_irn_dbg_info(node);
4481 /* we exchange the ProjX with a jump */
4482 block = be_transform_node(block);
4483 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
4486 if (node == be_get_old_anchor(anchor_tls)) {
4487 return gen_Proj_tls(node);
4492 if (is_ia32_l_FloattoLL(pred)) {
4493 return gen_Proj_l_FloattoLL(node);
4495 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4499 ir_mode *mode = get_irn_mode(node);
4500 if (ia32_mode_needs_gp_reg(mode)) {
4501 ir_node *new_pred = be_transform_node(pred);
4502 ir_node *block = be_transform_node(get_nodes_block(node));
4503 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4504 mode_Iu, get_Proj_proj(node));
4505 #ifdef DEBUG_libfirm
4506 new_proj->node_nr = node->node_nr;
4512 return be_duplicate_node(node);
4516 * Enters all transform functions into the generic pointer
4518 static void register_transformers(void)
4522 /* first clear the generic function pointer for all ops */
4523 clear_irp_opcodes_generic_func();
4525 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4526 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4564 /* transform ops from intrinsic lowering */
4576 GEN(ia32_l_LLtoFloat);
4577 GEN(ia32_l_FloattoLL);
4583 /* we should never see these nodes */
4598 /* handle generic backend nodes */
4607 op_Mulh = get_op_Mulh();
4616 * Pre-transform all unknown and noreg nodes.
4618 static void ia32_pretransform_node(void *arch_cg) {
4619 ia32_code_gen_t *cg = arch_cg;
4621 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4622 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4623 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4624 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4625 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4626 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4631 * Walker, checks if all ia32 nodes producing more than one result have their
4632 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4634 static void add_missing_keep_walker(ir_node *node, void *data)
4637 unsigned found_projs = 0;
4638 const ir_edge_t *edge;
4639 ir_mode *mode = get_irn_mode(node);
4644 if(!is_ia32_irn(node))
4647 n_outs = get_ia32_n_res(node);
4650 if(is_ia32_SwitchJmp(node))
4653 assert(n_outs < (int) sizeof(unsigned) * 8);
4654 foreach_out_edge(node, edge) {
4655 ir_node *proj = get_edge_src_irn(edge);
4656 int pn = get_Proj_proj(proj);
4658 if (get_irn_mode(proj) == mode_M)
4661 assert(pn < n_outs);
4662 found_projs |= 1 << pn;
4666 /* are keeps missing? */
4668 for(i = 0; i < n_outs; ++i) {
4671 const arch_register_req_t *req;
4672 const arch_register_class_t *cls;
4674 if(found_projs & (1 << i)) {
4678 req = get_ia32_out_req(node, i);
4683 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4687 block = get_nodes_block(node);
4688 in[0] = new_r_Proj(current_ir_graph, block, node,
4689 arch_register_class_mode(cls), i);
4690 if(last_keep != NULL) {
4691 be_Keep_add_node(last_keep, cls, in[0]);
4693 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4694 if(sched_is_scheduled(node)) {
4695 sched_add_after(node, last_keep);
4702 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4705 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4707 ir_graph *irg = be_get_birg_irg(cg->birg);
4708 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4711 /* do the transformation */
4712 void ia32_transform_graph(ia32_code_gen_t *cg) {
4714 ir_graph *irg = cg->irg;
4716 register_transformers();
4718 initial_fpcw = NULL;
4720 BE_TIMER_PUSH(t_heights);
4721 heights = heights_new(irg);
4722 BE_TIMER_POP(t_heights);
4723 ia32_calculate_non_address_mode_nodes(cg->birg);
4725 /* the transform phase is not safe for CSE (yet) because several nodes get
4726 * attributes set after their creation */
4727 cse_last = get_opt_cse();
4730 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4732 set_opt_cse(cse_last);
4734 ia32_free_non_address_mode_nodes();
4735 heights_free(heights);
4739 void ia32_init_transform(void)
4741 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");