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];
437 * return true if the node is a Proj(Load) and could be used in source address
438 * mode for another node. Will return only true if the @p other node is not
439 * dependent on the memory of the Load (for binary operations use the other
440 * input here, for unary operations use NULL).
442 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
443 ir_node *other, ir_node *other2, match_flags_t flags)
448 /* float constants are always available */
449 if (is_Const(node)) {
450 ir_mode *mode = get_irn_mode(node);
451 if (mode_is_float(mode)) {
452 if (ia32_cg_config.use_sse2) {
453 if (is_simple_sse_Const(node))
456 if (is_simple_x87_Const(node))
459 if (get_irn_n_edges(node) > 1)
467 load = get_Proj_pred(node);
468 pn = get_Proj_proj(node);
469 if (!is_Load(load) || pn != pn_Load_res)
471 if (get_nodes_block(load) != block)
473 /* we only use address mode if we're the only user of the load */
474 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
476 /* in some edge cases with address mode we might reach the load normally
477 * and through some AM sequence, if it is already materialized then we
478 * can't create an AM node from it */
479 if (be_is_transformed(node))
482 /* don't do AM if other node inputs depend on the load (via mem-proj) */
483 if (other != NULL && prevents_AM(block, load, other))
486 if (other2 != NULL && prevents_AM(block, load, other2))
492 typedef struct ia32_address_mode_t ia32_address_mode_t;
493 struct ia32_address_mode_t {
498 ia32_op_type_t op_type;
502 unsigned commutative : 1;
503 unsigned ins_permuted : 1;
506 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
510 /* construct load address */
511 memset(addr, 0, sizeof(addr[0]));
512 ia32_create_address_mode(addr, ptr, /*force=*/0);
514 noreg_gp = ia32_new_NoReg_gp(env_cg);
515 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
516 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
517 addr->mem = be_transform_node(mem);
520 static void build_address(ia32_address_mode_t *am, ir_node *node)
522 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
523 ia32_address_t *addr = &am->addr;
529 if (is_Const(node)) {
530 ir_entity *entity = create_float_const_entity(node);
531 addr->base = noreg_gp;
532 addr->index = noreg_gp;
533 addr->mem = new_NoMem();
534 addr->symconst_ent = entity;
536 am->ls_mode = get_type_mode(get_entity_type(entity));
537 am->pinned = op_pin_state_floats;
541 load = get_Proj_pred(node);
542 ptr = get_Load_ptr(load);
543 mem = get_Load_mem(load);
544 new_mem = be_transform_node(mem);
545 am->pinned = get_irn_pinned(load);
546 am->ls_mode = get_Load_mode(load);
547 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
550 /* construct load address */
551 ia32_create_address_mode(addr, ptr, /*force=*/0);
553 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
554 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
558 static void set_address(ir_node *node, const ia32_address_t *addr)
560 set_ia32_am_scale(node, addr->scale);
561 set_ia32_am_sc(node, addr->symconst_ent);
562 set_ia32_am_offs_int(node, addr->offset);
563 if(addr->symconst_sign)
564 set_ia32_am_sc_sign(node);
566 set_ia32_use_frame(node);
567 set_ia32_frame_ent(node, addr->frame_entity);
571 * Apply attributes of a given address mode to a node.
573 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
575 set_address(node, &am->addr);
577 set_ia32_op_type(node, am->op_type);
578 set_ia32_ls_mode(node, am->ls_mode);
579 if (am->pinned == op_pin_state_pinned) {
580 /* beware: some nodes are already pinned and did not allow to change the state */
581 if (get_irn_pinned(node) != op_pin_state_pinned)
582 set_irn_pinned(node, op_pin_state_pinned);
585 set_ia32_commutative(node);
589 * Check, if a given node is a Down-Conv, ie. a integer Conv
590 * from a mode with a mode with more bits to a mode with lesser bits.
591 * Moreover, we return only true if the node has not more than 1 user.
593 * @param node the node
594 * @return non-zero if node is a Down-Conv
596 static int is_downconv(const ir_node *node)
604 /* we only want to skip the conv when we're the only user
605 * (not optimal but for now...)
607 if(get_irn_n_edges(node) > 1)
610 src_mode = get_irn_mode(get_Conv_op(node));
611 dest_mode = get_irn_mode(node);
612 return ia32_mode_needs_gp_reg(src_mode)
613 && ia32_mode_needs_gp_reg(dest_mode)
614 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
617 /* Skip all Down-Conv's on a given node and return the resulting node. */
618 ir_node *ia32_skip_downconv(ir_node *node) {
619 while (is_downconv(node))
620 node = get_Conv_op(node);
625 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
627 ir_mode *mode = get_irn_mode(node);
632 if(mode_is_signed(mode)) {
637 block = get_nodes_block(node);
638 dbgi = get_irn_dbg_info(node);
640 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
644 * matches operands of a node into ia32 addressing/operand modes. This covers
645 * usage of source address mode, immediates, operations with non 32-bit modes,
647 * The resulting data is filled into the @p am struct. block is the block
648 * of the node whose arguments are matched. op1, op2 are the first and second
649 * input that are matched (op1 may be NULL). other_op is another unrelated
650 * input that is not matched! but which is needed sometimes to check if AM
651 * for op1/op2 is legal.
652 * @p flags describes the supported modes of the operation in detail.
654 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
655 ir_node *op1, ir_node *op2, ir_node *other_op,
658 ia32_address_t *addr = &am->addr;
659 ir_mode *mode = get_irn_mode(op2);
660 int mode_bits = get_mode_size_bits(mode);
661 ir_node *noreg_gp, *new_op1, *new_op2;
663 unsigned commutative;
664 int use_am_and_immediates;
667 memset(am, 0, sizeof(am[0]));
669 commutative = (flags & match_commutative) != 0;
670 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
671 use_am = (flags & match_am) != 0;
672 use_immediate = (flags & match_immediate) != 0;
673 assert(!use_am_and_immediates || use_immediate);
676 assert(!commutative || op1 != NULL);
677 assert(use_am || !(flags & match_8bit_am));
678 assert(use_am || !(flags & match_16bit_am));
680 if (mode_bits == 8) {
681 if (!(flags & match_8bit_am))
683 /* we don't automatically add upconvs yet */
684 assert((flags & match_mode_neutral) || (flags & match_8bit));
685 } else if (mode_bits == 16) {
686 if (!(flags & match_16bit_am))
688 /* we don't automatically add upconvs yet */
689 assert((flags & match_mode_neutral) || (flags & match_16bit));
692 /* we can simply skip downconvs for mode neutral nodes: the upper bits
693 * can be random for these operations */
694 if (flags & match_mode_neutral) {
695 op2 = ia32_skip_downconv(op2);
697 op1 = ia32_skip_downconv(op1);
701 /* match immediates. firm nodes are normalized: constants are always on the
704 if (!(flags & match_try_am) && use_immediate) {
705 new_op2 = try_create_Immediate(op2, 0);
708 noreg_gp = ia32_new_NoReg_gp(env_cg);
709 if (new_op2 == NULL &&
710 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
711 build_address(am, op2);
712 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
713 if (mode_is_float(mode)) {
714 new_op2 = ia32_new_NoReg_vfp(env_cg);
718 am->op_type = ia32_AddrModeS;
719 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
721 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
723 build_address(am, op1);
725 if (mode_is_float(mode)) {
726 noreg = ia32_new_NoReg_vfp(env_cg);
731 if (new_op2 != NULL) {
734 new_op1 = be_transform_node(op2);
736 am->ins_permuted = 1;
738 am->op_type = ia32_AddrModeS;
740 am->op_type = ia32_Normal;
742 if (flags & match_try_am) {
748 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
750 new_op2 = be_transform_node(op2);
752 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
754 if (addr->base == NULL)
755 addr->base = noreg_gp;
756 if (addr->index == NULL)
757 addr->index = noreg_gp;
758 if (addr->mem == NULL)
759 addr->mem = new_NoMem();
761 am->new_op1 = new_op1;
762 am->new_op2 = new_op2;
763 am->commutative = commutative;
766 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
768 mark_irn_visited(old_node);
769 be_set_transformed_node(old_node, new_node);
772 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
777 if (am->mem_proj == NULL)
780 /* we have to create a mode_T so the old MemProj can attach to us */
781 mode = get_irn_mode(node);
782 load = get_Proj_pred(am->mem_proj);
784 set_transformed_and_mark(load, node);
786 if (mode != mode_T) {
787 set_irn_mode(node, mode_T);
788 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
795 * Construct a standard binary operation, set AM and immediate if required.
797 * @param node The original node for which the binop is created
798 * @param op1 The first operand
799 * @param op2 The second operand
800 * @param func The node constructor function
801 * @return The constructed ia32 node.
803 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
804 construct_binop_func *func, match_flags_t flags)
807 ir_node *block, *new_block, *new_node;
808 ia32_address_mode_t am;
809 ia32_address_t *addr = &am.addr;
811 block = get_nodes_block(node);
812 match_arguments(&am, block, op1, op2, NULL, flags);
814 dbgi = get_irn_dbg_info(node);
815 new_block = be_transform_node(block);
816 new_node = func(dbgi, current_ir_graph, new_block,
817 addr->base, addr->index, addr->mem,
818 am.new_op1, am.new_op2);
819 set_am_attributes(new_node, &am);
820 /* we can't use source address mode anymore when using immediates */
821 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
822 set_ia32_am_support(new_node, ia32_am_none);
823 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
825 new_node = fix_mem_proj(new_node, &am);
832 n_ia32_l_binop_right,
833 n_ia32_l_binop_eflags
835 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
836 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
837 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
838 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
839 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
840 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
843 * Construct a binary operation which also consumes the eflags.
845 * @param node The node to transform
846 * @param func The node constructor function
847 * @param flags The match flags
848 * @return The constructor ia32 node
850 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
853 ir_node *src_block = get_nodes_block(node);
854 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
855 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
856 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
858 ir_node *block, *new_node, *new_eflags;
859 ia32_address_mode_t am;
860 ia32_address_t *addr = &am.addr;
862 match_arguments(&am, src_block, op1, op2, eflags, flags);
864 dbgi = get_irn_dbg_info(node);
865 block = be_transform_node(src_block);
866 new_eflags = be_transform_node(eflags);
867 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
868 addr->mem, am.new_op1, am.new_op2, new_eflags);
869 set_am_attributes(new_node, &am);
870 /* we can't use source address mode anymore when using immediates */
871 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
872 set_ia32_am_support(new_node, ia32_am_none);
873 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
875 new_node = fix_mem_proj(new_node, &am);
880 static ir_node *get_fpcw(void)
883 if (initial_fpcw != NULL)
886 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
887 &ia32_fp_cw_regs[REG_FPCW]);
888 initial_fpcw = be_transform_node(fpcw);
894 * Construct a standard binary operation, set AM and immediate if required.
896 * @param op1 The first operand
897 * @param op2 The second operand
898 * @param func The node constructor function
899 * @return The constructed ia32 node.
901 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
902 construct_binop_float_func *func,
905 ir_mode *mode = get_irn_mode(node);
907 ir_node *block, *new_block, *new_node;
908 ia32_address_mode_t am;
909 ia32_address_t *addr = &am.addr;
911 /* cannot use address mode with long double on x87 */
912 if (get_mode_size_bits(mode) > 64)
915 block = get_nodes_block(node);
916 match_arguments(&am, block, op1, op2, NULL, flags);
918 dbgi = get_irn_dbg_info(node);
919 new_block = be_transform_node(block);
920 new_node = func(dbgi, current_ir_graph, new_block,
921 addr->base, addr->index, addr->mem,
922 am.new_op1, am.new_op2, get_fpcw());
923 set_am_attributes(new_node, &am);
925 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
927 new_node = fix_mem_proj(new_node, &am);
933 * Construct a shift/rotate binary operation, sets 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_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
941 construct_shift_func *func,
945 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
947 assert(! mode_is_float(get_irn_mode(node)));
948 assert(flags & match_immediate);
949 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
951 if (flags & match_mode_neutral) {
952 op1 = ia32_skip_downconv(op1);
953 new_op1 = be_transform_node(op1);
954 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
955 new_op1 = create_upconv(op1, node);
957 new_op1 = be_transform_node(op1);
960 /* the shift amount can be any mode that is bigger than 5 bits, since all
961 * other bits are ignored anyway */
962 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
963 ir_node *const op = get_Conv_op(op2);
964 if (mode_is_float(get_irn_mode(op)))
967 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
969 new_op2 = create_immediate_or_transform(op2, 0);
971 dbgi = get_irn_dbg_info(node);
972 block = get_nodes_block(node);
973 new_block = be_transform_node(block);
974 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
975 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
977 /* lowered shift instruction may have a dependency operand, handle it here */
978 if (get_irn_arity(node) == 3) {
979 /* we have a dependency */
980 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
981 add_irn_dep(new_node, new_dep);
989 * Construct a standard unary operation, set AM and immediate if required.
991 * @param op The operand
992 * @param func The node constructor function
993 * @return The constructed ia32 node.
995 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
999 ir_node *block, *new_block, *new_op, *new_node;
1001 assert(flags == 0 || flags == match_mode_neutral);
1002 if (flags & match_mode_neutral) {
1003 op = ia32_skip_downconv(op);
1006 new_op = be_transform_node(op);
1007 dbgi = get_irn_dbg_info(node);
1008 block = get_nodes_block(node);
1009 new_block = be_transform_node(block);
1010 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1012 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1017 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1018 ia32_address_t *addr)
1020 ir_node *base, *index, *res;
1024 base = ia32_new_NoReg_gp(env_cg);
1026 base = be_transform_node(base);
1029 index = addr->index;
1030 if (index == NULL) {
1031 index = ia32_new_NoReg_gp(env_cg);
1033 index = be_transform_node(index);
1036 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1037 set_address(res, addr);
1043 * Returns non-zero if a given address mode has a symbolic or
1044 * numerical offset != 0.
1046 static int am_has_immediates(const ia32_address_t *addr)
1048 return addr->offset != 0 || addr->symconst_ent != NULL
1049 || addr->frame_entity || addr->use_frame;
1053 * Creates an ia32 Add.
1055 * @return the created ia32 Add node
1057 static ir_node *gen_Add(ir_node *node) {
1058 ir_mode *mode = get_irn_mode(node);
1059 ir_node *op1 = get_Add_left(node);
1060 ir_node *op2 = get_Add_right(node);
1062 ir_node *block, *new_block, *new_node, *add_immediate_op;
1063 ia32_address_t addr;
1064 ia32_address_mode_t am;
1066 if (mode_is_float(mode)) {
1067 if (ia32_cg_config.use_sse2)
1068 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1069 match_commutative | match_am);
1071 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1072 match_commutative | match_am);
1075 ia32_mark_non_am(node);
1077 op2 = ia32_skip_downconv(op2);
1078 op1 = ia32_skip_downconv(op1);
1082 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1083 * 1. Add with immediate -> Lea
1084 * 2. Add with possible source address mode -> Add
1085 * 3. Otherwise -> Lea
1087 memset(&addr, 0, sizeof(addr));
1088 ia32_create_address_mode(&addr, node, /*force=*/1);
1089 add_immediate_op = NULL;
1091 dbgi = get_irn_dbg_info(node);
1092 block = get_nodes_block(node);
1093 new_block = be_transform_node(block);
1096 if(addr.base == NULL && addr.index == NULL) {
1097 ir_graph *irg = current_ir_graph;
1098 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1099 addr.symconst_sign, addr.offset);
1100 add_irn_dep(new_node, get_irg_frame(irg));
1101 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1104 /* add with immediate? */
1105 if(addr.index == NULL) {
1106 add_immediate_op = addr.base;
1107 } else if(addr.base == NULL && addr.scale == 0) {
1108 add_immediate_op = addr.index;
1111 if(add_immediate_op != NULL) {
1112 if(!am_has_immediates(&addr)) {
1113 #ifdef DEBUG_libfirm
1114 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1117 return be_transform_node(add_immediate_op);
1120 new_node = create_lea_from_address(dbgi, new_block, &addr);
1121 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1125 /* test if we can use source address mode */
1126 match_arguments(&am, block, op1, op2, NULL, match_commutative
1127 | match_mode_neutral | match_am | match_immediate | match_try_am);
1129 /* construct an Add with source address mode */
1130 if (am.op_type == ia32_AddrModeS) {
1131 ir_graph *irg = current_ir_graph;
1132 ia32_address_t *am_addr = &am.addr;
1133 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1134 am_addr->index, am_addr->mem, am.new_op1,
1136 set_am_attributes(new_node, &am);
1137 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1139 new_node = fix_mem_proj(new_node, &am);
1144 /* otherwise construct a lea */
1145 new_node = create_lea_from_address(dbgi, new_block, &addr);
1146 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1151 * Creates an ia32 Mul.
1153 * @return the created ia32 Mul node
1155 static ir_node *gen_Mul(ir_node *node) {
1156 ir_node *op1 = get_Mul_left(node);
1157 ir_node *op2 = get_Mul_right(node);
1158 ir_mode *mode = get_irn_mode(node);
1160 if (mode_is_float(mode)) {
1161 if (ia32_cg_config.use_sse2)
1162 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1163 match_commutative | match_am);
1165 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1166 match_commutative | match_am);
1168 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1169 match_commutative | match_am | match_mode_neutral |
1170 match_immediate | match_am_and_immediates);
1174 * Creates an ia32 Mulh.
1175 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1176 * this result while Mul returns the lower 32 bit.
1178 * @return the created ia32 Mulh node
1180 static ir_node *gen_Mulh(ir_node *node)
1182 ir_node *block = get_nodes_block(node);
1183 ir_node *new_block = be_transform_node(block);
1184 dbg_info *dbgi = get_irn_dbg_info(node);
1185 ir_node *op1 = get_Mulh_left(node);
1186 ir_node *op2 = get_Mulh_right(node);
1187 ir_mode *mode = get_irn_mode(node);
1188 construct_binop_func *func;
1190 ir_node *proj_res_high;
1192 func = mode_is_signed(mode) ? new_rd_ia32_IMul1OP : new_rd_ia32_Mul;
1193 new_node = gen_binop(node, op1, op2, func, match_commutative | match_am);
1195 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1196 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1197 mode_Iu, pn_ia32_IMul1OP_res_high);
1198 return proj_res_high;
1204 * Creates an ia32 And.
1206 * @return The created ia32 And node
1208 static ir_node *gen_And(ir_node *node) {
1209 ir_node *op1 = get_And_left(node);
1210 ir_node *op2 = get_And_right(node);
1211 assert(! mode_is_float(get_irn_mode(node)));
1213 /* is it a zero extension? */
1214 if (is_Const(op2)) {
1215 tarval *tv = get_Const_tarval(op2);
1216 long v = get_tarval_long(tv);
1218 if (v == 0xFF || v == 0xFFFF) {
1219 dbg_info *dbgi = get_irn_dbg_info(node);
1220 ir_node *block = get_nodes_block(node);
1227 assert(v == 0xFFFF);
1230 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1235 return gen_binop(node, op1, op2, new_rd_ia32_And,
1236 match_commutative | match_mode_neutral | match_am
1243 * Creates an ia32 Or.
1245 * @return The created ia32 Or node
1247 static ir_node *gen_Or(ir_node *node) {
1248 ir_node *op1 = get_Or_left(node);
1249 ir_node *op2 = get_Or_right(node);
1251 assert (! mode_is_float(get_irn_mode(node)));
1252 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1253 | match_mode_neutral | match_am | match_immediate);
1259 * Creates an ia32 Eor.
1261 * @return The created ia32 Eor node
1263 static ir_node *gen_Eor(ir_node *node) {
1264 ir_node *op1 = get_Eor_left(node);
1265 ir_node *op2 = get_Eor_right(node);
1267 assert(! mode_is_float(get_irn_mode(node)));
1268 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1269 | match_mode_neutral | match_am | match_immediate);
1274 * Creates an ia32 Sub.
1276 * @return The created ia32 Sub node
1278 static ir_node *gen_Sub(ir_node *node) {
1279 ir_node *op1 = get_Sub_left(node);
1280 ir_node *op2 = get_Sub_right(node);
1281 ir_mode *mode = get_irn_mode(node);
1283 if (mode_is_float(mode)) {
1284 if (ia32_cg_config.use_sse2)
1285 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1287 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1291 if (is_Const(op2)) {
1292 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1296 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1297 | match_am | match_immediate);
1300 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1301 ir_node *const src_val,
1302 ir_node *const src_mem,
1303 ir_node *const am_mem)
1305 if (is_NoMem(am_mem)) {
1306 return be_transform_node(src_mem);
1307 } else if (is_Proj(src_val) &&
1309 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1310 /* avoid memory loop */
1312 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1313 ir_node *const ptr_pred = get_Proj_pred(src_val);
1314 int const arity = get_Sync_n_preds(src_mem);
1319 NEW_ARR_A(ir_node*, ins, arity + 1);
1321 for (i = arity - 1; i >= 0; --i) {
1322 ir_node *const pred = get_Sync_pred(src_mem, i);
1324 /* avoid memory loop */
1325 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1328 ins[n++] = be_transform_node(pred);
1333 return new_r_Sync(irg, block, n, ins);
1337 ins[0] = be_transform_node(src_mem);
1339 return new_r_Sync(irg, block, 2, ins);
1344 * Generates an ia32 DivMod with additional infrastructure for the
1345 * register allocator if needed.
1347 static ir_node *create_Div(ir_node *node)
1349 ir_graph *irg = current_ir_graph;
1350 dbg_info *dbgi = get_irn_dbg_info(node);
1351 ir_node *block = get_nodes_block(node);
1352 ir_node *new_block = be_transform_node(block);
1359 ir_node *sign_extension;
1360 ia32_address_mode_t am;
1361 ia32_address_t *addr = &am.addr;
1363 /* the upper bits have random contents for smaller modes */
1364 switch (get_irn_opcode(node)) {
1366 op1 = get_Div_left(node);
1367 op2 = get_Div_right(node);
1368 mem = get_Div_mem(node);
1369 mode = get_Div_resmode(node);
1372 op1 = get_Mod_left(node);
1373 op2 = get_Mod_right(node);
1374 mem = get_Mod_mem(node);
1375 mode = get_Mod_resmode(node);
1378 op1 = get_DivMod_left(node);
1379 op2 = get_DivMod_right(node);
1380 mem = get_DivMod_mem(node);
1381 mode = get_DivMod_resmode(node);
1384 panic("invalid divmod node %+F", node);
1387 match_arguments(&am, block, op1, op2, NULL, match_am);
1389 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1390 is the memory of the consumed address. We can have only the second op as address
1391 in Div nodes, so check only op2. */
1392 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1394 if (mode_is_signed(mode)) {
1395 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1396 add_irn_dep(produceval, get_irg_frame(irg));
1397 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1400 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1401 addr->index, new_mem, am.new_op2,
1402 am.new_op1, sign_extension);
1404 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1405 add_irn_dep(sign_extension, get_irg_frame(irg));
1407 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1408 addr->index, new_mem, am.new_op2,
1409 am.new_op1, sign_extension);
1412 set_irn_pinned(new_node, get_irn_pinned(node));
1414 set_am_attributes(new_node, &am);
1415 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1417 new_node = fix_mem_proj(new_node, &am);
1423 static ir_node *gen_Mod(ir_node *node) {
1424 return create_Div(node);
1427 static ir_node *gen_Div(ir_node *node) {
1428 return create_Div(node);
1431 static ir_node *gen_DivMod(ir_node *node) {
1432 return create_Div(node);
1438 * Creates an ia32 floating Div.
1440 * @return The created ia32 xDiv node
1442 static ir_node *gen_Quot(ir_node *node)
1444 ir_node *op1 = get_Quot_left(node);
1445 ir_node *op2 = get_Quot_right(node);
1447 if (ia32_cg_config.use_sse2) {
1448 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1450 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1456 * Creates an ia32 Shl.
1458 * @return The created ia32 Shl node
1460 static ir_node *gen_Shl(ir_node *node) {
1461 ir_node *left = get_Shl_left(node);
1462 ir_node *right = get_Shl_right(node);
1464 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1465 match_mode_neutral | match_immediate);
1469 * Creates an ia32 Shr.
1471 * @return The created ia32 Shr node
1473 static ir_node *gen_Shr(ir_node *node) {
1474 ir_node *left = get_Shr_left(node);
1475 ir_node *right = get_Shr_right(node);
1477 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1483 * Creates an ia32 Sar.
1485 * @return The created ia32 Shrs node
1487 static ir_node *gen_Shrs(ir_node *node) {
1488 ir_node *left = get_Shrs_left(node);
1489 ir_node *right = get_Shrs_right(node);
1490 ir_mode *mode = get_irn_mode(node);
1492 if(is_Const(right) && mode == mode_Is) {
1493 tarval *tv = get_Const_tarval(right);
1494 long val = get_tarval_long(tv);
1496 /* this is a sign extension */
1497 ir_graph *irg = current_ir_graph;
1498 dbg_info *dbgi = get_irn_dbg_info(node);
1499 ir_node *block = be_transform_node(get_nodes_block(node));
1501 ir_node *new_op = be_transform_node(op);
1502 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1503 add_irn_dep(pval, get_irg_frame(irg));
1505 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1509 /* 8 or 16 bit sign extension? */
1510 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1511 ir_node *shl_left = get_Shl_left(left);
1512 ir_node *shl_right = get_Shl_right(left);
1513 if(is_Const(shl_right)) {
1514 tarval *tv1 = get_Const_tarval(right);
1515 tarval *tv2 = get_Const_tarval(shl_right);
1516 if(tv1 == tv2 && tarval_is_long(tv1)) {
1517 long val = get_tarval_long(tv1);
1518 if(val == 16 || val == 24) {
1519 dbg_info *dbgi = get_irn_dbg_info(node);
1520 ir_node *block = get_nodes_block(node);
1530 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1539 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1545 * Creates an ia32 Rol.
1547 * @param op1 The first operator
1548 * @param op2 The second operator
1549 * @return The created ia32 RotL node
1551 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1552 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1558 * Creates an ia32 Ror.
1559 * NOTE: There is no RotR with immediate because this would always be a RotL
1560 * "imm-mode_size_bits" which can be pre-calculated.
1562 * @param op1 The first operator
1563 * @param op2 The second operator
1564 * @return The created ia32 RotR node
1566 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1567 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1573 * Creates an ia32 RotR or RotL (depending on the found pattern).
1575 * @return The created ia32 RotL or RotR node
1577 static ir_node *gen_Rotl(ir_node *node) {
1578 ir_node *rotate = NULL;
1579 ir_node *op1 = get_Rotl_left(node);
1580 ir_node *op2 = get_Rotl_right(node);
1582 /* Firm has only RotL, so we are looking for a right (op2)
1583 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1584 that means we can create a RotR instead of an Add and a RotL */
1588 ir_node *left = get_Add_left(add);
1589 ir_node *right = get_Add_right(add);
1590 if (is_Const(right)) {
1591 tarval *tv = get_Const_tarval(right);
1592 ir_mode *mode = get_irn_mode(node);
1593 long bits = get_mode_size_bits(mode);
1595 if (is_Minus(left) &&
1596 tarval_is_long(tv) &&
1597 get_tarval_long(tv) == bits &&
1600 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1601 rotate = gen_Ror(node, op1, get_Minus_op(left));
1606 if (rotate == NULL) {
1607 rotate = gen_Rol(node, op1, op2);
1616 * Transforms a Minus node.
1618 * @return The created ia32 Minus node
1620 static ir_node *gen_Minus(ir_node *node)
1622 ir_node *op = get_Minus_op(node);
1623 ir_node *block = be_transform_node(get_nodes_block(node));
1624 ir_graph *irg = current_ir_graph;
1625 dbg_info *dbgi = get_irn_dbg_info(node);
1626 ir_mode *mode = get_irn_mode(node);
1631 if (mode_is_float(mode)) {
1632 ir_node *new_op = be_transform_node(op);
1633 if (ia32_cg_config.use_sse2) {
1634 /* TODO: non-optimal... if we have many xXors, then we should
1635 * rather create a load for the const and use that instead of
1636 * several AM nodes... */
1637 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1638 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1639 ir_node *nomem = new_rd_NoMem(irg);
1641 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1642 nomem, new_op, noreg_xmm);
1644 size = get_mode_size_bits(mode);
1645 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1647 set_ia32_am_sc(new_node, ent);
1648 set_ia32_op_type(new_node, ia32_AddrModeS);
1649 set_ia32_ls_mode(new_node, mode);
1651 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1654 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1657 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1663 * Transforms a Not node.
1665 * @return The created ia32 Not node
1667 static ir_node *gen_Not(ir_node *node) {
1668 ir_node *op = get_Not_op(node);
1670 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1671 assert (! mode_is_float(get_irn_mode(node)));
1673 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1679 * Transforms an Abs node.
1681 * @return The created ia32 Abs node
1683 static ir_node *gen_Abs(ir_node *node)
1685 ir_node *block = get_nodes_block(node);
1686 ir_node *new_block = be_transform_node(block);
1687 ir_node *op = get_Abs_op(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);
1691 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1692 ir_node *nomem = new_NoMem();
1698 if (mode_is_float(mode)) {
1699 new_op = be_transform_node(op);
1701 if (ia32_cg_config.use_sse2) {
1702 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1703 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1704 nomem, new_op, noreg_fp);
1706 size = get_mode_size_bits(mode);
1707 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1709 set_ia32_am_sc(new_node, ent);
1711 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1713 set_ia32_op_type(new_node, ia32_AddrModeS);
1714 set_ia32_ls_mode(new_node, mode);
1716 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1717 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1720 ir_node *xor, *pval, *sign_extension;
1722 if (get_mode_size_bits(mode) == 32) {
1723 new_op = be_transform_node(op);
1725 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1728 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1729 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1732 add_irn_dep(pval, get_irg_frame(irg));
1733 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1735 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1736 nomem, new_op, sign_extension);
1737 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1739 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1740 nomem, xor, sign_extension);
1741 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1748 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1750 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1751 dbg_info *dbgi = get_irn_dbg_info(cmp);
1752 ir_node *block = get_nodes_block(cmp);
1753 ir_node *new_block = be_transform_node(block);
1754 ir_node *op1 = be_transform_node(x);
1755 ir_node *op2 = be_transform_node(n);
1757 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1761 * Transform a node returning a "flag" result.
1763 * @param node the node to transform
1764 * @param pnc_out the compare mode to use
1766 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1775 /* we have a Cmp as input */
1776 if (is_Proj(node)) {
1777 ir_node *pred = get_Proj_pred(node);
1779 pn_Cmp pnc = get_Proj_proj(node);
1780 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1781 ir_node *l = get_Cmp_left(pred);
1782 ir_node *r = get_Cmp_right(pred);
1784 ir_node *la = get_And_left(l);
1785 ir_node *ra = get_And_right(l);
1787 ir_node *c = get_Shl_left(la);
1788 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1789 /* (1 << n) & ra) */
1790 ir_node *n = get_Shl_right(la);
1791 flags = gen_bt(pred, ra, n);
1792 /* we must generate a Jc/Jnc jump */
1793 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1796 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1801 ir_node *c = get_Shl_left(ra);
1802 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1803 /* la & (1 << n)) */
1804 ir_node *n = get_Shl_right(ra);
1805 flags = gen_bt(pred, la, n);
1806 /* we must generate a Jc/Jnc jump */
1807 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1810 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1816 flags = be_transform_node(pred);
1822 /* a mode_b value, we have to compare it against 0 */
1823 dbgi = get_irn_dbg_info(node);
1824 new_block = be_transform_node(get_nodes_block(node));
1825 new_op = be_transform_node(node);
1826 noreg = ia32_new_NoReg_gp(env_cg);
1827 nomem = new_NoMem();
1828 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1829 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1830 *pnc_out = pn_Cmp_Lg;
1835 * Transforms a Load.
1837 * @return the created ia32 Load node
1839 static ir_node *gen_Load(ir_node *node) {
1840 ir_node *old_block = get_nodes_block(node);
1841 ir_node *block = be_transform_node(old_block);
1842 ir_node *ptr = get_Load_ptr(node);
1843 ir_node *mem = get_Load_mem(node);
1844 ir_node *new_mem = be_transform_node(mem);
1847 ir_graph *irg = current_ir_graph;
1848 dbg_info *dbgi = get_irn_dbg_info(node);
1849 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1850 ir_mode *mode = get_Load_mode(node);
1853 ia32_address_t addr;
1855 /* construct load address */
1856 memset(&addr, 0, sizeof(addr));
1857 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1864 base = be_transform_node(base);
1870 index = be_transform_node(index);
1873 if (mode_is_float(mode)) {
1874 if (ia32_cg_config.use_sse2) {
1875 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1877 res_mode = mode_xmm;
1879 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1881 res_mode = mode_vfp;
1884 assert(mode != mode_b);
1886 /* create a conv node with address mode for smaller modes */
1887 if(get_mode_size_bits(mode) < 32) {
1888 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1889 new_mem, noreg, mode);
1891 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1896 set_irn_pinned(new_node, get_irn_pinned(node));
1897 set_ia32_op_type(new_node, ia32_AddrModeS);
1898 set_ia32_ls_mode(new_node, mode);
1899 set_address(new_node, &addr);
1901 if(get_irn_pinned(node) == op_pin_state_floats) {
1902 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1905 /* make sure we are scheduled behind the initial IncSP/Barrier
1906 * to avoid spills being placed before it
1908 if (block == get_irg_start_block(irg)) {
1909 add_irn_dep(new_node, get_irg_frame(irg));
1912 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1917 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1918 ir_node *ptr, ir_node *other)
1925 /* we only use address mode if we're the only user of the load */
1926 if (get_irn_n_edges(node) > 1)
1929 load = get_Proj_pred(node);
1932 if (get_nodes_block(load) != block)
1935 /* store should have the same pointer as the load */
1936 if (get_Load_ptr(load) != ptr)
1939 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1940 if (other != NULL &&
1941 get_nodes_block(other) == block &&
1942 heights_reachable_in_block(heights, other, load)) {
1949 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
1950 ir_node *const pred = get_Sync_pred(mem, i);
1952 if (is_Proj(pred) && get_Proj_pred(pred) == load)
1955 if (get_nodes_block(pred) == block &&
1956 heights_reachable_in_block(heights, pred, load)) {
1961 /* Store should be attached to the load */
1962 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
1969 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1970 ir_node *mem, ir_node *ptr, ir_mode *mode,
1971 construct_binop_dest_func *func,
1972 construct_binop_dest_func *func8bit,
1973 match_flags_t flags)
1975 ir_node *src_block = get_nodes_block(node);
1977 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1978 ir_graph *irg = current_ir_graph;
1985 ia32_address_mode_t am;
1986 ia32_address_t *addr = &am.addr;
1987 memset(&am, 0, sizeof(am));
1989 assert(flags & match_dest_am);
1990 assert(flags & match_immediate); /* there is no destam node without... */
1991 commutative = (flags & match_commutative) != 0;
1993 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
1994 build_address(&am, op1);
1995 new_op = create_immediate_or_transform(op2, 0);
1996 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1997 build_address(&am, op2);
1998 new_op = create_immediate_or_transform(op1, 0);
2003 if(addr->base == NULL)
2004 addr->base = noreg_gp;
2005 if(addr->index == NULL)
2006 addr->index = noreg_gp;
2007 if(addr->mem == NULL)
2008 addr->mem = new_NoMem();
2010 dbgi = get_irn_dbg_info(node);
2011 block = be_transform_node(src_block);
2012 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2014 if(get_mode_size_bits(mode) == 8) {
2015 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2018 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
2021 set_address(new_node, addr);
2022 set_ia32_op_type(new_node, ia32_AddrModeD);
2023 set_ia32_ls_mode(new_node, mode);
2024 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2026 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2027 mem_proj = be_transform_node(am.mem_proj);
2028 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2033 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2034 ir_node *ptr, ir_mode *mode,
2035 construct_unop_dest_func *func)
2037 ir_graph *irg = current_ir_graph;
2038 ir_node *src_block = get_nodes_block(node);
2044 ia32_address_mode_t am;
2045 ia32_address_t *addr = &am.addr;
2046 memset(&am, 0, sizeof(am));
2048 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2051 build_address(&am, op);
2053 dbgi = get_irn_dbg_info(node);
2054 block = be_transform_node(src_block);
2055 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2056 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2057 set_address(new_node, addr);
2058 set_ia32_op_type(new_node, ia32_AddrModeD);
2059 set_ia32_ls_mode(new_node, mode);
2060 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2062 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2063 mem_proj = be_transform_node(am.mem_proj);
2064 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2069 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2070 ir_mode *mode = get_irn_mode(node);
2071 ir_node *mux_true = get_Mux_true(node);
2072 ir_node *mux_false = get_Mux_false(node);
2083 ia32_address_t addr;
2085 if(get_mode_size_bits(mode) != 8)
2088 if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2090 } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2096 build_address_ptr(&addr, ptr, mem);
2098 irg = current_ir_graph;
2099 dbgi = get_irn_dbg_info(node);
2100 block = get_nodes_block(node);
2101 new_block = be_transform_node(block);
2102 cond = get_Mux_sel(node);
2103 flags = get_flags_node(cond, &pnc);
2104 new_mem = be_transform_node(mem);
2105 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2106 addr.index, addr.mem, flags, pnc, negated);
2107 set_address(new_node, &addr);
2108 set_ia32_op_type(new_node, ia32_AddrModeD);
2109 set_ia32_ls_mode(new_node, mode);
2110 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2115 static ir_node *try_create_dest_am(ir_node *node) {
2116 ir_node *val = get_Store_value(node);
2117 ir_node *mem = get_Store_mem(node);
2118 ir_node *ptr = get_Store_ptr(node);
2119 ir_mode *mode = get_irn_mode(val);
2120 unsigned bits = get_mode_size_bits(mode);
2125 /* handle only GP modes for now... */
2126 if(!ia32_mode_needs_gp_reg(mode))
2130 /* store must be the only user of the val node */
2131 if(get_irn_n_edges(val) > 1)
2133 /* skip pointless convs */
2135 ir_node *conv_op = get_Conv_op(val);
2136 ir_mode *pred_mode = get_irn_mode(conv_op);
2137 if (!ia32_mode_needs_gp_reg(pred_mode))
2139 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2147 /* value must be in the same block */
2148 if(get_nodes_block(node) != get_nodes_block(val))
2151 switch (get_irn_opcode(val)) {
2153 op1 = get_Add_left(val);
2154 op2 = get_Add_right(val);
2155 if(is_Const_1(op2)) {
2156 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2157 new_rd_ia32_IncMem);
2159 } else if(is_Const_Minus_1(op2)) {
2160 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2161 new_rd_ia32_DecMem);
2164 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2165 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2166 match_dest_am | match_commutative |
2170 op1 = get_Sub_left(val);
2171 op2 = get_Sub_right(val);
2172 if (is_Const(op2)) {
2173 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2175 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2176 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2177 match_dest_am | match_immediate |
2181 op1 = get_And_left(val);
2182 op2 = get_And_right(val);
2183 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2184 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2185 match_dest_am | match_commutative |
2189 op1 = get_Or_left(val);
2190 op2 = get_Or_right(val);
2191 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2192 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2193 match_dest_am | match_commutative |
2197 op1 = get_Eor_left(val);
2198 op2 = get_Eor_right(val);
2199 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2200 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2201 match_dest_am | match_commutative |
2205 op1 = get_Shl_left(val);
2206 op2 = get_Shl_right(val);
2207 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2208 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2209 match_dest_am | match_immediate);
2212 op1 = get_Shr_left(val);
2213 op2 = get_Shr_right(val);
2214 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2215 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2216 match_dest_am | match_immediate);
2219 op1 = get_Shrs_left(val);
2220 op2 = get_Shrs_right(val);
2221 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2222 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2223 match_dest_am | match_immediate);
2226 op1 = get_Rotl_left(val);
2227 op2 = get_Rotl_right(val);
2228 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2229 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2230 match_dest_am | match_immediate);
2232 /* TODO: match ROR patterns... */
2234 new_node = try_create_SetMem(val, ptr, mem);
2237 op1 = get_Minus_op(val);
2238 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2241 /* should be lowered already */
2242 assert(mode != mode_b);
2243 op1 = get_Not_op(val);
2244 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2250 if(new_node != NULL) {
2251 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2252 get_irn_pinned(node) == op_pin_state_pinned) {
2253 set_irn_pinned(new_node, op_pin_state_pinned);
2260 static int is_float_to_int32_conv(const ir_node *node)
2262 ir_mode *mode = get_irn_mode(node);
2266 if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode))
2268 /* don't report unsigned as conv to 32bit, because we really need to do
2269 * a vfist with 64bit signed in this case */
2270 if(!mode_is_signed(mode))
2275 conv_op = get_Conv_op(node);
2276 conv_mode = get_irn_mode(conv_op);
2278 if(!mode_is_float(conv_mode))
2285 * Transform a Store(floatConst).
2287 * @return the created ia32 Store node
2289 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2291 ir_mode *mode = get_irn_mode(cns);
2292 unsigned size = get_mode_size_bytes(mode);
2293 tarval *tv = get_Const_tarval(cns);
2294 ir_node *block = get_nodes_block(node);
2295 ir_node *new_block = be_transform_node(block);
2296 ir_node *ptr = get_Store_ptr(node);
2297 ir_node *mem = get_Store_mem(node);
2298 ir_graph *irg = current_ir_graph;
2299 dbg_info *dbgi = get_irn_dbg_info(node);
2303 ia32_address_t addr;
2305 assert(size % 4 == 0);
2308 build_address_ptr(&addr, ptr, mem);
2312 get_tarval_sub_bits(tv, ofs) |
2313 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2314 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2315 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2316 ir_node *imm = create_Immediate(NULL, 0, val);
2318 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2319 addr.index, addr.mem, imm);
2321 set_irn_pinned(new_node, get_irn_pinned(node));
2322 set_ia32_op_type(new_node, ia32_AddrModeD);
2323 set_ia32_ls_mode(new_node, mode_Iu);
2324 set_address(new_node, &addr);
2325 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2327 ins[i++] = new_node;
2332 } while (size != 0);
2334 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2338 * Generate a vfist or vfisttp instruction.
2340 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2341 ir_node *mem, ir_node *val, ir_node **fist)
2345 if (ia32_cg_config.use_fisttp) {
2346 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2347 if other users exists */
2348 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2349 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2350 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2351 be_new_Keep(reg_class, irg, block, 1, &value);
2353 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2356 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2359 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2365 * Transforms a normal Store.
2367 * @return the created ia32 Store node
2369 static ir_node *gen_normal_Store(ir_node *node)
2371 ir_node *val = get_Store_value(node);
2372 ir_mode *mode = get_irn_mode(val);
2373 ir_node *block = get_nodes_block(node);
2374 ir_node *new_block = be_transform_node(block);
2375 ir_node *ptr = get_Store_ptr(node);
2376 ir_node *mem = get_Store_mem(node);
2377 ir_graph *irg = current_ir_graph;
2378 dbg_info *dbgi = get_irn_dbg_info(node);
2379 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2380 ir_node *new_val, *new_node, *store;
2381 ia32_address_t addr;
2383 /* check for destination address mode */
2384 new_node = try_create_dest_am(node);
2385 if (new_node != NULL)
2388 /* construct store address */
2389 memset(&addr, 0, sizeof(addr));
2390 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2392 if (addr.base == NULL) {
2395 addr.base = be_transform_node(addr.base);
2398 if (addr.index == NULL) {
2401 addr.index = be_transform_node(addr.index);
2403 addr.mem = be_transform_node(mem);
2405 if (mode_is_float(mode)) {
2406 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2408 while (is_Conv(val) && mode == get_irn_mode(val)) {
2409 ir_node *op = get_Conv_op(val);
2410 if (!mode_is_float(get_irn_mode(op)))
2414 new_val = be_transform_node(val);
2415 if (ia32_cg_config.use_sse2) {
2416 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2417 addr.index, addr.mem, new_val);
2419 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2420 addr.index, addr.mem, new_val, mode);
2423 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2424 val = get_Conv_op(val);
2426 /* TODO: is this optimisation still necessary at all (middleend)? */
2427 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2428 while (is_Conv(val)) {
2429 ir_node *op = get_Conv_op(val);
2430 if (!mode_is_float(get_irn_mode(op)))
2432 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2436 new_val = be_transform_node(val);
2437 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2439 new_val = create_immediate_or_transform(val, 0);
2440 assert(mode != mode_b);
2442 if (get_mode_size_bits(mode) == 8) {
2443 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2444 addr.index, addr.mem, new_val);
2446 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2447 addr.index, addr.mem, new_val);
2452 set_irn_pinned(store, get_irn_pinned(node));
2453 set_ia32_op_type(store, ia32_AddrModeD);
2454 set_ia32_ls_mode(store, mode);
2456 set_address(store, &addr);
2457 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2463 * Transforms a Store.
2465 * @return the created ia32 Store node
2467 static ir_node *gen_Store(ir_node *node)
2469 ir_node *val = get_Store_value(node);
2470 ir_mode *mode = get_irn_mode(val);
2472 if (mode_is_float(mode) && is_Const(val)) {
2475 /* we are storing a floating point constant */
2476 if (ia32_cg_config.use_sse2) {
2477 transform = !is_simple_sse_Const(val);
2479 transform = !is_simple_x87_Const(val);
2482 return gen_float_const_Store(node, val);
2484 return gen_normal_Store(node);
2488 * Transforms a Switch.
2490 * @return the created ia32 SwitchJmp node
2492 static ir_node *create_Switch(ir_node *node)
2494 ir_graph *irg = current_ir_graph;
2495 dbg_info *dbgi = get_irn_dbg_info(node);
2496 ir_node *block = be_transform_node(get_nodes_block(node));
2497 ir_node *sel = get_Cond_selector(node);
2498 ir_node *new_sel = be_transform_node(sel);
2499 int switch_min = INT_MAX;
2500 int switch_max = INT_MIN;
2501 long default_pn = get_Cond_defaultProj(node);
2503 const ir_edge_t *edge;
2505 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2507 /* determine the smallest switch case value */
2508 foreach_out_edge(node, edge) {
2509 ir_node *proj = get_edge_src_irn(edge);
2510 long pn = get_Proj_proj(proj);
2511 if(pn == default_pn)
2520 if((unsigned) (switch_max - switch_min) > 256000) {
2521 panic("Size of switch %+F bigger than 256000", node);
2524 if (switch_min != 0) {
2525 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2527 /* if smallest switch case is not 0 we need an additional sub */
2528 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2529 add_ia32_am_offs_int(new_sel, -switch_min);
2530 set_ia32_op_type(new_sel, ia32_AddrModeS);
2532 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2535 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2536 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2542 * Transform a Cond node.
2544 static ir_node *gen_Cond(ir_node *node) {
2545 ir_node *block = get_nodes_block(node);
2546 ir_node *new_block = be_transform_node(block);
2547 ir_graph *irg = current_ir_graph;
2548 dbg_info *dbgi = get_irn_dbg_info(node);
2549 ir_node *sel = get_Cond_selector(node);
2550 ir_mode *sel_mode = get_irn_mode(sel);
2551 ir_node *flags = NULL;
2555 if (sel_mode != mode_b) {
2556 return create_Switch(node);
2559 /* we get flags from a Cmp */
2560 flags = get_flags_node(sel, &pnc);
2562 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2563 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2568 static ir_node *gen_be_Copy(ir_node *node)
2570 ir_node *new_node = be_duplicate_node(node);
2571 ir_mode *mode = get_irn_mode(new_node);
2573 if (ia32_mode_needs_gp_reg(mode)) {
2574 set_irn_mode(new_node, mode_Iu);
2580 static ir_node *create_Fucom(ir_node *node)
2582 ir_graph *irg = current_ir_graph;
2583 dbg_info *dbgi = get_irn_dbg_info(node);
2584 ir_node *block = get_nodes_block(node);
2585 ir_node *new_block = be_transform_node(block);
2586 ir_node *left = get_Cmp_left(node);
2587 ir_node *new_left = be_transform_node(left);
2588 ir_node *right = get_Cmp_right(node);
2592 if(ia32_cg_config.use_fucomi) {
2593 new_right = be_transform_node(right);
2594 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2596 set_ia32_commutative(new_node);
2597 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2599 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2600 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2603 new_right = be_transform_node(right);
2604 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2608 set_ia32_commutative(new_node);
2610 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2612 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2613 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2619 static ir_node *create_Ucomi(ir_node *node)
2621 ir_graph *irg = current_ir_graph;
2622 dbg_info *dbgi = get_irn_dbg_info(node);
2623 ir_node *src_block = get_nodes_block(node);
2624 ir_node *new_block = be_transform_node(src_block);
2625 ir_node *left = get_Cmp_left(node);
2626 ir_node *right = get_Cmp_right(node);
2628 ia32_address_mode_t am;
2629 ia32_address_t *addr = &am.addr;
2631 match_arguments(&am, src_block, left, right, NULL,
2632 match_commutative | match_am);
2634 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2635 addr->mem, am.new_op1, am.new_op2,
2637 set_am_attributes(new_node, &am);
2639 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2641 new_node = fix_mem_proj(new_node, &am);
2647 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2648 * to fold an and into a test node
2650 static bool can_fold_test_and(ir_node *node)
2652 const ir_edge_t *edge;
2654 /** we can only have eq and lg projs */
2655 foreach_out_edge(node, edge) {
2656 ir_node *proj = get_edge_src_irn(edge);
2657 pn_Cmp pnc = get_Proj_proj(proj);
2658 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2666 * returns true if it is assured, that the upper bits of a node are "clean"
2667 * which means for a 16 or 8 bit value, that the upper bits in the register
2668 * are 0 for unsigned and a copy of the last significant bit for unsigned
2671 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2673 assert(ia32_mode_needs_gp_reg(mode));
2674 if (get_mode_size_bits(mode) >= 32)
2677 if (is_Proj(transformed_node))
2678 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2680 if (is_ia32_Conv_I2I(transformed_node)
2681 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2682 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2683 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2685 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2691 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2692 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2693 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2694 const ia32_immediate_attr_t *attr
2695 = get_ia32_immediate_attr_const(right);
2696 if (attr->symconst == 0
2697 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2701 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2704 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2705 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2706 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2707 const ia32_immediate_attr_t *attr
2708 = get_ia32_immediate_attr_const(right);
2709 if (attr->symconst == 0
2710 && (unsigned) attr->offset
2711 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2718 /* TODO recurse on Or, Xor, ... if appropriate? */
2720 if (is_ia32_Immediate(transformed_node)
2721 || is_ia32_Const(transformed_node)) {
2722 const ia32_immediate_attr_t *attr
2723 = get_ia32_immediate_attr_const(transformed_node);
2724 if (mode_is_signed(mode)) {
2725 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2726 if (shifted == 0 || shifted == -1)
2729 unsigned long shifted = (unsigned long) attr->offset;
2730 shifted >>= get_mode_size_bits(mode);
2740 * Generate code for a Cmp.
2742 static ir_node *gen_Cmp(ir_node *node)
2744 ir_graph *irg = current_ir_graph;
2745 dbg_info *dbgi = get_irn_dbg_info(node);
2746 ir_node *block = get_nodes_block(node);
2747 ir_node *new_block = be_transform_node(block);
2748 ir_node *left = get_Cmp_left(node);
2749 ir_node *right = get_Cmp_right(node);
2750 ir_mode *cmp_mode = get_irn_mode(left);
2752 ia32_address_mode_t am;
2753 ia32_address_t *addr = &am.addr;
2756 if(mode_is_float(cmp_mode)) {
2757 if (ia32_cg_config.use_sse2) {
2758 return create_Ucomi(node);
2760 return create_Fucom(node);
2764 assert(ia32_mode_needs_gp_reg(cmp_mode));
2766 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2767 cmp_unsigned = !mode_is_signed(cmp_mode);
2768 if (is_Const_0(right) &&
2770 get_irn_n_edges(left) == 1 &&
2771 can_fold_test_and(node)) {
2772 /* Test(and_left, and_right) */
2773 ir_node *and_left = get_And_left(left);
2774 ir_node *and_right = get_And_right(left);
2776 /* matze: code here used mode instead of cmd_mode, I think it is always
2777 * the same as cmp_mode, but I leave this here to see if this is really
2780 assert(get_irn_mode(and_left) == cmp_mode);
2782 match_arguments(&am, block, and_left, and_right, NULL,
2784 match_am | match_8bit_am | match_16bit_am |
2785 match_am_and_immediates | match_immediate |
2786 match_8bit | match_16bit);
2788 /* use 32bit compare mode if possible since the opcode is smaller */
2789 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2790 upper_bits_clean(am.new_op2, cmp_mode)) {
2791 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2794 if (get_mode_size_bits(cmp_mode) == 8) {
2795 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2796 addr->index, addr->mem, am.new_op1,
2797 am.new_op2, am.ins_permuted,
2800 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2801 addr->index, addr->mem, am.new_op1,
2802 am.new_op2, am.ins_permuted,
2806 /* Cmp(left, right) */
2807 match_arguments(&am, block, left, right, NULL,
2808 match_commutative | match_am | match_8bit_am |
2809 match_16bit_am | match_am_and_immediates |
2810 match_immediate | match_8bit | match_16bit);
2811 /* use 32bit compare mode if possible since the opcode is smaller */
2812 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2813 upper_bits_clean(am.new_op2, cmp_mode)) {
2814 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2817 if (get_mode_size_bits(cmp_mode) == 8) {
2818 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2819 addr->index, addr->mem, am.new_op1,
2820 am.new_op2, am.ins_permuted,
2823 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2824 addr->index, addr->mem, am.new_op1,
2825 am.new_op2, am.ins_permuted, cmp_unsigned);
2828 set_am_attributes(new_node, &am);
2829 set_ia32_ls_mode(new_node, cmp_mode);
2831 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2833 new_node = fix_mem_proj(new_node, &am);
2838 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2841 ir_graph *irg = current_ir_graph;
2842 dbg_info *dbgi = get_irn_dbg_info(node);
2843 ir_node *block = get_nodes_block(node);
2844 ir_node *new_block = be_transform_node(block);
2845 ir_node *val_true = get_Mux_true(node);
2846 ir_node *val_false = get_Mux_false(node);
2848 match_flags_t match_flags;
2849 ia32_address_mode_t am;
2850 ia32_address_t *addr;
2852 assert(ia32_cg_config.use_cmov);
2853 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2857 match_flags = match_commutative | match_am | match_16bit_am |
2860 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2862 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2863 addr->mem, am.new_op1, am.new_op2, new_flags,
2864 am.ins_permuted, pnc);
2865 set_am_attributes(new_node, &am);
2867 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2869 new_node = fix_mem_proj(new_node, &am);
2875 * Creates a ia32 Setcc instruction.
2877 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2878 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2881 ir_graph *irg = current_ir_graph;
2882 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2883 ir_node *nomem = new_NoMem();
2884 ir_mode *mode = get_irn_mode(orig_node);
2887 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2888 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2890 /* we might need to conv the result up */
2891 if (get_mode_size_bits(mode) > 8) {
2892 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2893 nomem, new_node, mode_Bu);
2894 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2901 * Create instruction for an unsigned Difference or Zero.
2903 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2904 ir_graph *irg = current_ir_graph;
2905 ir_mode *mode = get_irn_mode(psi);
2906 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2909 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2910 match_mode_neutral | match_am | match_immediate | match_two_users);
2912 block = get_nodes_block(new_node);
2914 if (is_Proj(new_node)) {
2915 sub = get_Proj_pred(new_node);
2916 assert(is_ia32_Sub(sub));
2919 set_irn_mode(sub, mode_T);
2920 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2922 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2924 dbgi = get_irn_dbg_info(psi);
2925 noreg = ia32_new_NoReg_gp(env_cg);
2926 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2927 nomem = new_NoMem();
2928 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2930 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2931 set_ia32_commutative(new_node);
2936 * Transforms a Mux node into CMov.
2938 * @return The transformed node.
2940 static ir_node *gen_Mux(ir_node *node)
2942 dbg_info *dbgi = get_irn_dbg_info(node);
2943 ir_node *block = get_nodes_block(node);
2944 ir_node *new_block = be_transform_node(block);
2945 ir_node *mux_true = get_Mux_true(node);
2946 ir_node *mux_false = get_Mux_false(node);
2947 ir_node *cond = get_Mux_sel(node);
2948 ir_mode *mode = get_irn_mode(node);
2951 assert(get_irn_mode(cond) == mode_b);
2953 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2954 if (mode_is_float(mode)) {
2955 ir_node *cmp = get_Proj_pred(cond);
2956 ir_node *cmp_left = get_Cmp_left(cmp);
2957 ir_node *cmp_right = get_Cmp_right(cmp);
2958 pn_Cmp pnc = get_Proj_proj(cond);
2960 if (ia32_cg_config.use_sse2) {
2961 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2962 if (cmp_left == mux_true && cmp_right == mux_false) {
2963 /* Mux(a <= b, a, b) => MIN */
2964 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2965 match_commutative | match_am | match_two_users);
2966 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2967 /* Mux(a <= b, b, a) => MAX */
2968 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2969 match_commutative | match_am | match_two_users);
2971 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2972 if (cmp_left == mux_true && cmp_right == mux_false) {
2973 /* Mux(a >= b, a, b) => MAX */
2974 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2975 match_commutative | match_am | match_two_users);
2976 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2977 /* Mux(a >= b, b, a) => MIN */
2978 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2979 match_commutative | match_am | match_two_users);
2983 panic("cannot transform floating point Mux");
2989 assert(ia32_mode_needs_gp_reg(mode));
2991 if (is_Proj(cond)) {
2992 ir_node *cmp = get_Proj_pred(cond);
2994 ir_node *cmp_left = get_Cmp_left(cmp);
2995 ir_node *cmp_right = get_Cmp_right(cmp);
2996 pn_Cmp pnc = get_Proj_proj(cond);
2998 /* check for unsigned Doz first */
2999 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3000 is_Const_0(mux_false) && is_Sub(mux_true) &&
3001 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3002 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3003 return create_Doz(node, cmp_left, cmp_right);
3004 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3005 is_Const_0(mux_true) && is_Sub(mux_false) &&
3006 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3007 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3008 return create_Doz(node, cmp_left, cmp_right);
3013 flags = get_flags_node(cond, &pnc);
3015 if (is_Const(mux_true) && is_Const(mux_false)) {
3016 /* both are const, good */
3017 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3018 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3019 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3020 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3022 /* Not that simple. */
3027 new_node = create_CMov(node, cond, flags, pnc);
3035 * Create a conversion from x87 state register to general purpose.
3037 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3038 ir_node *block = be_transform_node(get_nodes_block(node));
3039 ir_node *op = get_Conv_op(node);
3040 ir_node *new_op = be_transform_node(op);
3041 ia32_code_gen_t *cg = env_cg;
3042 ir_graph *irg = current_ir_graph;
3043 dbg_info *dbgi = get_irn_dbg_info(node);
3044 ir_node *noreg = ia32_new_NoReg_gp(cg);
3045 ir_mode *mode = get_irn_mode(node);
3046 ir_node *fist, *load, *mem;
3048 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3049 set_irn_pinned(fist, op_pin_state_floats);
3050 set_ia32_use_frame(fist);
3051 set_ia32_op_type(fist, ia32_AddrModeD);
3053 assert(get_mode_size_bits(mode) <= 32);
3054 /* exception we can only store signed 32 bit integers, so for unsigned
3055 we store a 64bit (signed) integer and load the lower bits */
3056 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3057 set_ia32_ls_mode(fist, mode_Ls);
3059 set_ia32_ls_mode(fist, mode_Is);
3061 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3064 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3066 set_irn_pinned(load, op_pin_state_floats);
3067 set_ia32_use_frame(load);
3068 set_ia32_op_type(load, ia32_AddrModeS);
3069 set_ia32_ls_mode(load, mode_Is);
3070 if(get_ia32_ls_mode(fist) == mode_Ls) {
3071 ia32_attr_t *attr = get_ia32_attr(load);
3072 attr->data.need_64bit_stackent = 1;
3074 ia32_attr_t *attr = get_ia32_attr(load);
3075 attr->data.need_32bit_stackent = 1;
3077 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3079 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3083 * Creates a x87 strict Conv by placing a Store and a Load
3085 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3087 ir_node *block = get_nodes_block(node);
3088 ir_graph *irg = current_ir_graph;
3089 dbg_info *dbgi = get_irn_dbg_info(node);
3090 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3091 ir_node *nomem = new_NoMem();
3092 ir_node *frame = get_irg_frame(irg);
3093 ir_node *store, *load;
3096 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3098 set_ia32_use_frame(store);
3099 set_ia32_op_type(store, ia32_AddrModeD);
3100 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3102 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3104 set_ia32_use_frame(load);
3105 set_ia32_op_type(load, ia32_AddrModeS);
3106 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3108 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3113 * Create a conversion from general purpose to x87 register
3115 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3116 ir_node *src_block = get_nodes_block(node);
3117 ir_node *block = be_transform_node(src_block);
3118 ir_graph *irg = current_ir_graph;
3119 dbg_info *dbgi = get_irn_dbg_info(node);
3120 ir_node *op = get_Conv_op(node);
3121 ir_node *new_op = NULL;
3125 ir_mode *store_mode;
3131 /* fild can use source AM if the operand is a signed 32bit integer */
3132 if (src_mode == mode_Is) {
3133 ia32_address_mode_t am;
3135 match_arguments(&am, src_block, NULL, op, NULL,
3136 match_am | match_try_am);
3137 if (am.op_type == ia32_AddrModeS) {
3138 ia32_address_t *addr = &am.addr;
3140 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3141 addr->index, addr->mem);
3142 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3145 set_am_attributes(fild, &am);
3146 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3148 fix_mem_proj(fild, &am);
3153 if(new_op == NULL) {
3154 new_op = be_transform_node(op);
3157 noreg = ia32_new_NoReg_gp(env_cg);
3158 nomem = new_NoMem();
3159 mode = get_irn_mode(op);
3161 /* first convert to 32 bit signed if necessary */
3162 src_bits = get_mode_size_bits(src_mode);
3163 if (src_bits == 8) {
3164 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3166 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3168 } else if (src_bits < 32) {
3169 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3171 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3175 assert(get_mode_size_bits(mode) == 32);
3178 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3181 set_ia32_use_frame(store);
3182 set_ia32_op_type(store, ia32_AddrModeD);
3183 set_ia32_ls_mode(store, mode_Iu);
3185 /* exception for 32bit unsigned, do a 64bit spill+load */
3186 if(!mode_is_signed(mode)) {
3189 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3191 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3192 get_irg_frame(irg), noreg, nomem,
3195 set_ia32_use_frame(zero_store);
3196 set_ia32_op_type(zero_store, ia32_AddrModeD);
3197 add_ia32_am_offs_int(zero_store, 4);
3198 set_ia32_ls_mode(zero_store, mode_Iu);
3203 store = new_rd_Sync(dbgi, irg, block, 2, in);
3204 store_mode = mode_Ls;
3206 store_mode = mode_Is;
3210 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3212 set_ia32_use_frame(fild);
3213 set_ia32_op_type(fild, ia32_AddrModeS);
3214 set_ia32_ls_mode(fild, store_mode);
3216 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3222 * Create a conversion from one integer mode into another one
3224 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3225 dbg_info *dbgi, ir_node *block, ir_node *op,
3228 ir_graph *irg = current_ir_graph;
3229 int src_bits = get_mode_size_bits(src_mode);
3230 int tgt_bits = get_mode_size_bits(tgt_mode);
3231 ir_node *new_block = be_transform_node(block);
3233 ir_mode *smaller_mode;
3235 ia32_address_mode_t am;
3236 ia32_address_t *addr = &am.addr;
3239 if (src_bits < tgt_bits) {
3240 smaller_mode = src_mode;
3241 smaller_bits = src_bits;
3243 smaller_mode = tgt_mode;
3244 smaller_bits = tgt_bits;
3247 #ifdef DEBUG_libfirm
3249 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3254 match_arguments(&am, block, NULL, op, NULL,
3255 match_8bit | match_16bit |
3256 match_am | match_8bit_am | match_16bit_am);
3258 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3259 /* unnecessary conv. in theory it shouldn't have been AM */
3260 assert(is_ia32_NoReg_GP(addr->base));
3261 assert(is_ia32_NoReg_GP(addr->index));
3262 assert(is_NoMem(addr->mem));
3263 assert(am.addr.offset == 0);
3264 assert(am.addr.symconst_ent == NULL);
3268 if (smaller_bits == 8) {
3269 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3270 addr->index, addr->mem, am.new_op2,
3273 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3274 addr->index, addr->mem, am.new_op2,
3277 set_am_attributes(new_node, &am);
3278 /* match_arguments assume that out-mode = in-mode, this isn't true here
3280 set_ia32_ls_mode(new_node, smaller_mode);
3281 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3282 new_node = fix_mem_proj(new_node, &am);
3287 * Transforms a Conv node.
3289 * @return The created ia32 Conv node
3291 static ir_node *gen_Conv(ir_node *node) {
3292 ir_node *block = get_nodes_block(node);
3293 ir_node *new_block = be_transform_node(block);
3294 ir_node *op = get_Conv_op(node);
3295 ir_node *new_op = NULL;
3296 ir_graph *irg = current_ir_graph;
3297 dbg_info *dbgi = get_irn_dbg_info(node);
3298 ir_mode *src_mode = get_irn_mode(op);
3299 ir_mode *tgt_mode = get_irn_mode(node);
3300 int src_bits = get_mode_size_bits(src_mode);
3301 int tgt_bits = get_mode_size_bits(tgt_mode);
3302 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3303 ir_node *nomem = new_rd_NoMem(irg);
3304 ir_node *res = NULL;
3306 if (src_mode == mode_b) {
3307 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3308 /* nothing to do, we already model bools as 0/1 ints */
3309 return be_transform_node(op);
3312 if (src_mode == tgt_mode) {
3313 if (get_Conv_strict(node)) {
3314 if (ia32_cg_config.use_sse2) {
3315 /* when we are in SSE mode, we can kill all strict no-op conversion */
3316 return be_transform_node(op);
3319 /* this should be optimized already, but who knows... */
3320 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3321 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3322 return be_transform_node(op);
3326 if (mode_is_float(src_mode)) {
3327 new_op = be_transform_node(op);
3328 /* we convert from float ... */
3329 if (mode_is_float(tgt_mode)) {
3330 if(src_mode == mode_E && tgt_mode == mode_D
3331 && !get_Conv_strict(node)) {
3332 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3337 if (ia32_cg_config.use_sse2) {
3338 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3339 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3341 set_ia32_ls_mode(res, tgt_mode);
3343 if(get_Conv_strict(node)) {
3344 res = gen_x87_strict_conv(tgt_mode, new_op);
3345 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3348 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3353 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3354 if (ia32_cg_config.use_sse2) {
3355 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3357 set_ia32_ls_mode(res, src_mode);
3359 return gen_x87_fp_to_gp(node);
3363 /* we convert from int ... */
3364 if (mode_is_float(tgt_mode)) {
3366 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3367 if (ia32_cg_config.use_sse2) {
3368 new_op = be_transform_node(op);
3369 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3371 set_ia32_ls_mode(res, tgt_mode);
3373 res = gen_x87_gp_to_fp(node, src_mode);
3374 if(get_Conv_strict(node)) {
3375 /* The strict-Conv is only necessary, if the int mode has more bits
3376 * than the float mantissa */
3377 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3378 size_t float_mantissa;
3379 /* FIXME There is no way to get the mantissa size of a mode */
3380 switch (get_mode_size_bits(tgt_mode)) {
3381 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3382 case 64: float_mantissa = 52 + 1; break;
3384 case 96: float_mantissa = 64; break;
3385 default: float_mantissa = 0; break;
3387 if (float_mantissa < int_mantissa) {
3388 res = gen_x87_strict_conv(tgt_mode, res);
3389 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3394 } else if(tgt_mode == mode_b) {
3395 /* mode_b lowering already took care that we only have 0/1 values */
3396 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3397 src_mode, tgt_mode));
3398 return be_transform_node(op);
3401 if (src_bits == tgt_bits) {
3402 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3403 src_mode, tgt_mode));
3404 return be_transform_node(op);
3407 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3415 static ir_node *create_immediate_or_transform(ir_node *node,
3416 char immediate_constraint_type)
3418 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3419 if (new_node == NULL) {
3420 new_node = be_transform_node(node);
3426 * Transforms a FrameAddr into an ia32 Add.
3428 static ir_node *gen_be_FrameAddr(ir_node *node) {
3429 ir_node *block = be_transform_node(get_nodes_block(node));
3430 ir_node *op = be_get_FrameAddr_frame(node);
3431 ir_node *new_op = be_transform_node(op);
3432 ir_graph *irg = current_ir_graph;
3433 dbg_info *dbgi = get_irn_dbg_info(node);
3434 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3437 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3438 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3439 set_ia32_use_frame(new_node);
3441 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3447 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3449 static ir_node *gen_be_Return(ir_node *node) {
3450 ir_graph *irg = current_ir_graph;
3451 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3452 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3453 ir_entity *ent = get_irg_entity(irg);
3454 ir_type *tp = get_entity_type(ent);
3459 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3460 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3463 int pn_ret_val, pn_ret_mem, arity, i;
3465 assert(ret_val != NULL);
3466 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3467 return be_duplicate_node(node);
3470 res_type = get_method_res_type(tp, 0);
3472 if (! is_Primitive_type(res_type)) {
3473 return be_duplicate_node(node);
3476 mode = get_type_mode(res_type);
3477 if (! mode_is_float(mode)) {
3478 return be_duplicate_node(node);
3481 assert(get_method_n_ress(tp) == 1);
3483 pn_ret_val = get_Proj_proj(ret_val);
3484 pn_ret_mem = get_Proj_proj(ret_mem);
3486 /* get the Barrier */
3487 barrier = get_Proj_pred(ret_val);
3489 /* get result input of the Barrier */
3490 ret_val = get_irn_n(barrier, pn_ret_val);
3491 new_ret_val = be_transform_node(ret_val);
3493 /* get memory input of the Barrier */
3494 ret_mem = get_irn_n(barrier, pn_ret_mem);
3495 new_ret_mem = be_transform_node(ret_mem);
3497 frame = get_irg_frame(irg);
3499 dbgi = get_irn_dbg_info(barrier);
3500 block = be_transform_node(get_nodes_block(barrier));
3502 noreg = ia32_new_NoReg_gp(env_cg);
3504 /* store xmm0 onto stack */
3505 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3506 new_ret_mem, new_ret_val);
3507 set_ia32_ls_mode(sse_store, mode);
3508 set_ia32_op_type(sse_store, ia32_AddrModeD);
3509 set_ia32_use_frame(sse_store);
3511 /* load into x87 register */
3512 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3513 set_ia32_op_type(fld, ia32_AddrModeS);
3514 set_ia32_use_frame(fld);
3516 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3517 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3519 /* create a new barrier */
3520 arity = get_irn_arity(barrier);
3521 in = alloca(arity * sizeof(in[0]));
3522 for (i = 0; i < arity; ++i) {
3525 if (i == pn_ret_val) {
3527 } else if (i == pn_ret_mem) {
3530 ir_node *in = get_irn_n(barrier, i);
3531 new_in = be_transform_node(in);
3536 new_barrier = new_ir_node(dbgi, irg, block,
3537 get_irn_op(barrier), get_irn_mode(barrier),
3539 copy_node_attr(barrier, new_barrier);
3540 be_duplicate_deps(barrier, new_barrier);
3541 set_transformed_and_mark(barrier, new_barrier);
3543 /* transform normally */
3544 return be_duplicate_node(node);
3548 * Transform a be_AddSP into an ia32_SubSP.
3550 static ir_node *gen_be_AddSP(ir_node *node)
3552 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3553 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3555 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3556 match_am | match_immediate);
3560 * Transform a be_SubSP into an ia32_AddSP
3562 static ir_node *gen_be_SubSP(ir_node *node)
3564 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3565 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3567 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3568 match_am | match_immediate);
3572 * Change some phi modes
3574 static ir_node *gen_Phi(ir_node *node) {
3575 ir_node *block = be_transform_node(get_nodes_block(node));
3576 ir_graph *irg = current_ir_graph;
3577 dbg_info *dbgi = get_irn_dbg_info(node);
3578 ir_mode *mode = get_irn_mode(node);
3581 if(ia32_mode_needs_gp_reg(mode)) {
3582 /* we shouldn't have any 64bit stuff around anymore */
3583 assert(get_mode_size_bits(mode) <= 32);
3584 /* all integer operations are on 32bit registers now */
3586 } else if(mode_is_float(mode)) {
3587 if (ia32_cg_config.use_sse2) {
3594 /* phi nodes allow loops, so we use the old arguments for now
3595 * and fix this later */
3596 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3597 get_irn_in(node) + 1);
3598 copy_node_attr(node, phi);
3599 be_duplicate_deps(node, phi);
3601 be_set_transformed_node(node, phi);
3602 be_enqueue_preds(node);
3610 static ir_node *gen_IJmp(ir_node *node)
3612 ir_node *block = get_nodes_block(node);
3613 ir_node *new_block = be_transform_node(block);
3614 dbg_info *dbgi = get_irn_dbg_info(node);
3615 ir_node *op = get_IJmp_target(node);
3617 ia32_address_mode_t am;
3618 ia32_address_t *addr = &am.addr;
3620 assert(get_irn_mode(op) == mode_P);
3622 match_arguments(&am, block, NULL, op, NULL,
3623 match_am | match_8bit_am | match_16bit_am |
3624 match_immediate | match_8bit | match_16bit);
3626 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3627 addr->base, addr->index, addr->mem,
3629 set_am_attributes(new_node, &am);
3630 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3632 new_node = fix_mem_proj(new_node, &am);
3638 * Transform a Bound node.
3640 static ir_node *gen_Bound(ir_node *node)
3643 ir_node *lower = get_Bound_lower(node);
3644 dbg_info *dbgi = get_irn_dbg_info(node);
3646 if (is_Const_0(lower)) {
3647 /* typical case for Java */
3648 ir_node *sub, *res, *flags, *block;
3649 ir_graph *irg = current_ir_graph;
3651 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3652 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3654 block = get_nodes_block(res);
3655 if (! is_Proj(res)) {
3657 set_irn_mode(sub, mode_T);
3658 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3660 sub = get_Proj_pred(res);
3662 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3663 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3664 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3666 panic("generic Bound not supported in ia32 Backend");
3672 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3674 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3675 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3677 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3678 match_immediate | match_mode_neutral);
3681 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3683 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3684 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3685 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3689 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3691 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3692 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3693 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3697 static ir_node *gen_ia32_l_Add(ir_node *node) {
3698 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3699 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3700 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3701 match_commutative | match_am | match_immediate |
3702 match_mode_neutral);
3704 if(is_Proj(lowered)) {
3705 lowered = get_Proj_pred(lowered);
3707 assert(is_ia32_Add(lowered));
3708 set_irn_mode(lowered, mode_T);
3714 static ir_node *gen_ia32_l_Adc(ir_node *node)
3716 return gen_binop_flags(node, new_rd_ia32_Adc,
3717 match_commutative | match_am | match_immediate |
3718 match_mode_neutral);
3722 * Transforms a l_MulS into a "real" MulS node.
3724 * @return the created ia32 Mul node
3726 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3727 ir_node *left = get_binop_left(node);
3728 ir_node *right = get_binop_right(node);
3730 return gen_binop(node, left, right, new_rd_ia32_Mul,
3731 match_commutative | match_am | match_mode_neutral);
3735 * Transforms a l_IMulS into a "real" IMul1OPS node.
3737 * @return the created ia32 IMul1OP node
3739 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3740 ir_node *left = get_binop_left(node);
3741 ir_node *right = get_binop_right(node);
3743 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3744 match_commutative | match_am | match_mode_neutral);
3747 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3748 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3749 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3750 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3751 match_am | match_immediate | match_mode_neutral);
3753 if(is_Proj(lowered)) {
3754 lowered = get_Proj_pred(lowered);
3756 assert(is_ia32_Sub(lowered));
3757 set_irn_mode(lowered, mode_T);
3763 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3764 return gen_binop_flags(node, new_rd_ia32_Sbb,
3765 match_am | match_immediate | match_mode_neutral);
3769 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3770 * op1 - target to be shifted
3771 * op2 - contains bits to be shifted into target
3773 * Only op3 can be an immediate.
3775 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3776 ir_node *low, ir_node *count)
3778 ir_node *block = get_nodes_block(node);
3779 ir_node *new_block = be_transform_node(block);
3780 ir_graph *irg = current_ir_graph;
3781 dbg_info *dbgi = get_irn_dbg_info(node);
3782 ir_node *new_high = be_transform_node(high);
3783 ir_node *new_low = be_transform_node(low);
3787 /* the shift amount can be any mode that is bigger than 5 bits, since all
3788 * other bits are ignored anyway */
3789 while (is_Conv(count) &&
3790 get_irn_n_edges(count) == 1 &&
3791 mode_is_int(get_irn_mode(count))) {
3792 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3793 count = get_Conv_op(count);
3795 new_count = create_immediate_or_transform(count, 0);
3797 if (is_ia32_l_ShlD(node)) {
3798 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3801 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3804 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3809 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3811 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3812 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3813 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3814 return gen_lowered_64bit_shifts(node, high, low, count);
3817 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3819 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3820 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3821 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3822 return gen_lowered_64bit_shifts(node, high, low, count);
3825 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3826 ir_node *src_block = get_nodes_block(node);
3827 ir_node *block = be_transform_node(src_block);
3828 ir_graph *irg = current_ir_graph;
3829 dbg_info *dbgi = get_irn_dbg_info(node);
3830 ir_node *frame = get_irg_frame(irg);
3831 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3832 ir_node *nomem = new_NoMem();
3833 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3834 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3835 ir_node *new_val_low = be_transform_node(val_low);
3836 ir_node *new_val_high = be_transform_node(val_high);
3841 ir_node *store_high;
3843 if(!mode_is_signed(get_irn_mode(val_high))) {
3844 panic("unsigned long long -> float not supported yet (%+F)", node);
3848 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3850 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3852 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3853 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3855 set_ia32_use_frame(store_low);
3856 set_ia32_use_frame(store_high);
3857 set_ia32_op_type(store_low, ia32_AddrModeD);
3858 set_ia32_op_type(store_high, ia32_AddrModeD);
3859 set_ia32_ls_mode(store_low, mode_Iu);
3860 set_ia32_ls_mode(store_high, mode_Is);
3861 add_ia32_am_offs_int(store_high, 4);
3865 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3868 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3870 set_ia32_use_frame(fild);
3871 set_ia32_op_type(fild, ia32_AddrModeS);
3872 set_ia32_ls_mode(fild, mode_Ls);
3874 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3876 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3879 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3880 ir_node *src_block = get_nodes_block(node);
3881 ir_node *block = be_transform_node(src_block);
3882 ir_graph *irg = current_ir_graph;
3883 dbg_info *dbgi = get_irn_dbg_info(node);
3884 ir_node *frame = get_irg_frame(irg);
3885 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3886 ir_node *nomem = new_NoMem();
3887 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3888 ir_node *new_val = be_transform_node(val);
3889 ir_node *fist, *mem;
3891 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3892 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3893 set_ia32_use_frame(fist);
3894 set_ia32_op_type(fist, ia32_AddrModeD);
3895 set_ia32_ls_mode(fist, mode_Ls);
3901 * the BAD transformer.
3903 static ir_node *bad_transform(ir_node *node) {
3904 panic("No transform function for %+F available.", node);
3908 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
3909 ir_graph *irg = current_ir_graph;
3910 ir_node *block = be_transform_node(get_nodes_block(node));
3911 ir_node *pred = get_Proj_pred(node);
3912 ir_node *new_pred = be_transform_node(pred);
3913 ir_node *frame = get_irg_frame(irg);
3914 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3915 dbg_info *dbgi = get_irn_dbg_info(node);
3916 long pn = get_Proj_proj(node);
3921 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3922 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3923 set_ia32_use_frame(load);
3924 set_ia32_op_type(load, ia32_AddrModeS);
3925 set_ia32_ls_mode(load, mode_Iu);
3926 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3927 * 32 bit from it with this particular load */
3928 attr = get_ia32_attr(load);
3929 attr->data.need_64bit_stackent = 1;
3931 if (pn == pn_ia32_l_FloattoLL_res_high) {
3932 add_ia32_am_offs_int(load, 4);
3934 assert(pn == pn_ia32_l_FloattoLL_res_low);
3937 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3943 * Transform the Projs of an AddSP.
3945 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
3946 ir_node *block = be_transform_node(get_nodes_block(node));
3947 ir_node *pred = get_Proj_pred(node);
3948 ir_node *new_pred = be_transform_node(pred);
3949 ir_graph *irg = current_ir_graph;
3950 dbg_info *dbgi = get_irn_dbg_info(node);
3951 long proj = get_Proj_proj(node);
3953 if (proj == pn_be_AddSP_sp) {
3954 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3955 pn_ia32_SubSP_stack);
3956 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3958 } else if(proj == pn_be_AddSP_res) {
3959 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3960 pn_ia32_SubSP_addr);
3961 } else if (proj == pn_be_AddSP_M) {
3962 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3965 panic("No idea how to transform proj->AddSP");
3969 * Transform the Projs of a SubSP.
3971 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
3972 ir_node *block = be_transform_node(get_nodes_block(node));
3973 ir_node *pred = get_Proj_pred(node);
3974 ir_node *new_pred = be_transform_node(pred);
3975 ir_graph *irg = current_ir_graph;
3976 dbg_info *dbgi = get_irn_dbg_info(node);
3977 long proj = get_Proj_proj(node);
3979 if (proj == pn_be_SubSP_sp) {
3980 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3981 pn_ia32_AddSP_stack);
3982 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3984 } else if (proj == pn_be_SubSP_M) {
3985 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3988 panic("No idea how to transform proj->SubSP");
3992 * Transform and renumber the Projs from a Load.
3994 static ir_node *gen_Proj_Load(ir_node *node) {
3996 ir_node *block = be_transform_node(get_nodes_block(node));
3997 ir_node *pred = get_Proj_pred(node);
3998 ir_graph *irg = current_ir_graph;
3999 dbg_info *dbgi = get_irn_dbg_info(node);
4000 long proj = get_Proj_proj(node);
4002 /* loads might be part of source address mode matches, so we don't
4003 * transform the ProjMs yet (with the exception of loads whose result is
4006 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4009 /* this is needed, because sometimes we have loops that are only
4010 reachable through the ProjM */
4011 be_enqueue_preds(node);
4012 /* do it in 2 steps, to silence firm verifier */
4013 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4014 set_Proj_proj(res, pn_ia32_mem);
4018 /* renumber the proj */
4019 new_pred = be_transform_node(pred);
4020 if (is_ia32_Load(new_pred)) {
4023 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4025 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4026 case pn_Load_X_regular:
4027 return new_rd_Jmp(dbgi, irg, block);
4028 case pn_Load_X_except:
4029 /* This Load might raise an exception. Mark it. */
4030 set_ia32_exc_label(new_pred, 1);
4031 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4035 } else if (is_ia32_Conv_I2I(new_pred) ||
4036 is_ia32_Conv_I2I8Bit(new_pred)) {
4037 set_irn_mode(new_pred, mode_T);
4038 if (proj == pn_Load_res) {
4039 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4040 } else if (proj == pn_Load_M) {
4041 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4043 } else if (is_ia32_xLoad(new_pred)) {
4046 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4048 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4049 case pn_Load_X_regular:
4050 return new_rd_Jmp(dbgi, irg, block);
4051 case pn_Load_X_except:
4052 /* This Load might raise an exception. Mark it. */
4053 set_ia32_exc_label(new_pred, 1);
4054 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4058 } else if (is_ia32_vfld(new_pred)) {
4061 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4063 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4064 case pn_Load_X_regular:
4065 return new_rd_Jmp(dbgi, irg, block);
4066 case pn_Load_X_except:
4067 /* This Load might raise an exception. Mark it. */
4068 set_ia32_exc_label(new_pred, 1);
4069 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4074 /* can happen for ProJMs when source address mode happened for the
4077 /* however it should not be the result proj, as that would mean the
4078 load had multiple users and should not have been used for
4080 if (proj != pn_Load_M) {
4081 panic("internal error: transformed node not a Load");
4083 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4086 panic("No idea how to transform proj");
4090 * Transform and renumber the Projs from a DivMod like instruction.
4092 static ir_node *gen_Proj_DivMod(ir_node *node) {
4093 ir_node *block = be_transform_node(get_nodes_block(node));
4094 ir_node *pred = get_Proj_pred(node);
4095 ir_node *new_pred = be_transform_node(pred);
4096 ir_graph *irg = current_ir_graph;
4097 dbg_info *dbgi = get_irn_dbg_info(node);
4098 long proj = get_Proj_proj(node);
4100 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4102 switch (get_irn_opcode(pred)) {
4106 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4108 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4109 case pn_Div_X_regular:
4110 return new_rd_Jmp(dbgi, irg, block);
4111 case pn_Div_X_except:
4112 set_ia32_exc_label(new_pred, 1);
4113 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4121 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4123 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4124 case pn_Mod_X_except:
4125 set_ia32_exc_label(new_pred, 1);
4126 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4134 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4135 case pn_DivMod_res_div:
4136 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4137 case pn_DivMod_res_mod:
4138 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4139 case pn_DivMod_X_regular:
4140 return new_rd_Jmp(dbgi, irg, block);
4141 case pn_DivMod_X_except:
4142 set_ia32_exc_label(new_pred, 1);
4143 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4152 panic("No idea how to transform proj->DivMod");
4156 * Transform and renumber the Projs from a CopyB.
4158 static ir_node *gen_Proj_CopyB(ir_node *node) {
4159 ir_node *block = be_transform_node(get_nodes_block(node));
4160 ir_node *pred = get_Proj_pred(node);
4161 ir_node *new_pred = be_transform_node(pred);
4162 ir_graph *irg = current_ir_graph;
4163 dbg_info *dbgi = get_irn_dbg_info(node);
4164 long proj = get_Proj_proj(node);
4167 case pn_CopyB_M_regular:
4168 if (is_ia32_CopyB_i(new_pred)) {
4169 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4170 } else if (is_ia32_CopyB(new_pred)) {
4171 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4178 panic("No idea how to transform proj->CopyB");
4182 * Transform and renumber the Projs from a Quot.
4184 static ir_node *gen_Proj_Quot(ir_node *node) {
4185 ir_node *block = be_transform_node(get_nodes_block(node));
4186 ir_node *pred = get_Proj_pred(node);
4187 ir_node *new_pred = be_transform_node(pred);
4188 ir_graph *irg = current_ir_graph;
4189 dbg_info *dbgi = get_irn_dbg_info(node);
4190 long proj = get_Proj_proj(node);
4194 if (is_ia32_xDiv(new_pred)) {
4195 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4196 } else if (is_ia32_vfdiv(new_pred)) {
4197 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4201 if (is_ia32_xDiv(new_pred)) {
4202 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4203 } else if (is_ia32_vfdiv(new_pred)) {
4204 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4207 case pn_Quot_X_regular:
4208 case pn_Quot_X_except:
4213 panic("No idea how to transform proj->Quot");
4216 static ir_node *gen_be_Call(ir_node *node) {
4217 ir_node *res = be_duplicate_node(node);
4220 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4222 /* Run the x87 simulator if the call returns a float value */
4223 call_tp = be_Call_get_type(node);
4224 if (get_method_n_ress(call_tp) > 0) {
4225 ir_type *const res_type = get_method_res_type(call_tp, 0);
4226 ir_mode *const res_mode = get_type_mode(res_type);
4228 if (res_mode != NULL && mode_is_float(res_mode)) {
4229 env_cg->do_x87_sim = 1;
4236 static ir_node *gen_be_IncSP(ir_node *node) {
4237 ir_node *res = be_duplicate_node(node);
4238 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4244 * Transform the Projs from a be_Call.
4246 static ir_node *gen_Proj_be_Call(ir_node *node) {
4247 ir_node *block = be_transform_node(get_nodes_block(node));
4248 ir_node *call = get_Proj_pred(node);
4249 ir_node *new_call = be_transform_node(call);
4250 ir_graph *irg = current_ir_graph;
4251 dbg_info *dbgi = get_irn_dbg_info(node);
4252 ir_type *method_type = be_Call_get_type(call);
4253 int n_res = get_method_n_ress(method_type);
4254 long proj = get_Proj_proj(node);
4255 ir_mode *mode = get_irn_mode(node);
4257 const arch_register_class_t *cls;
4259 /* The following is kinda tricky: If we're using SSE, then we have to
4260 * move the result value of the call in floating point registers to an
4261 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4262 * after the call, we have to make sure to correctly make the
4263 * MemProj and the result Proj use these 2 nodes
4265 if (proj == pn_be_Call_M_regular) {
4266 // get new node for result, are we doing the sse load/store hack?
4267 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4268 ir_node *call_res_new;
4269 ir_node *call_res_pred = NULL;
4271 if (call_res != NULL) {
4272 call_res_new = be_transform_node(call_res);
4273 call_res_pred = get_Proj_pred(call_res_new);
4276 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4277 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4278 pn_be_Call_M_regular);
4280 assert(is_ia32_xLoad(call_res_pred));
4281 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4285 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4286 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4288 ir_node *frame = get_irg_frame(irg);
4289 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4291 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4294 /* in case there is no memory output: create one to serialize the copy
4296 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4297 pn_be_Call_M_regular);
4298 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4299 pn_be_Call_first_res);
4301 /* store st(0) onto stack */
4302 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4304 set_ia32_op_type(fstp, ia32_AddrModeD);
4305 set_ia32_use_frame(fstp);
4307 /* load into SSE register */
4308 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4310 set_ia32_op_type(sse_load, ia32_AddrModeS);
4311 set_ia32_use_frame(sse_load);
4313 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4319 /* transform call modes */
4320 if (mode_is_data(mode)) {
4321 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4325 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4329 * Transform the Projs from a Cmp.
4331 static ir_node *gen_Proj_Cmp(ir_node *node)
4333 /* this probably means not all mode_b nodes were lowered... */
4334 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4339 * Transform the Projs from a Bound.
4341 static ir_node *gen_Proj_Bound(ir_node *node)
4343 ir_node *new_node, *block;
4344 ir_node *pred = get_Proj_pred(node);
4346 switch (get_Proj_proj(node)) {
4348 return be_transform_node(get_Bound_mem(pred));
4349 case pn_Bound_X_regular:
4350 new_node = be_transform_node(pred);
4351 block = get_nodes_block(new_node);
4352 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4353 case pn_Bound_X_except:
4354 new_node = be_transform_node(pred);
4355 block = get_nodes_block(new_node);
4356 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4358 return be_transform_node(get_Bound_index(pred));
4360 panic("unsupported Proj from Bound");
4364 static ir_node *gen_Proj_ASM(ir_node *node)
4370 if (get_irn_mode(node) != mode_M)
4371 return be_duplicate_node(node);
4373 pred = get_Proj_pred(node);
4374 new_pred = be_transform_node(pred);
4375 block = get_nodes_block(new_pred);
4376 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4377 get_ia32_n_res(new_pred) + 1);
4381 * Transform and potentially renumber Proj nodes.
4383 static ir_node *gen_Proj(ir_node *node) {
4384 ir_node *pred = get_Proj_pred(node);
4387 switch (get_irn_opcode(pred)) {
4389 proj = get_Proj_proj(node);
4390 if (proj == pn_Store_M) {
4391 return be_transform_node(pred);
4393 panic("No idea how to transform proj->Store");
4396 return gen_Proj_Load(node);
4398 return gen_Proj_ASM(node);
4402 return gen_Proj_DivMod(node);
4404 return gen_Proj_CopyB(node);
4406 return gen_Proj_Quot(node);
4408 return gen_Proj_be_SubSP(node);
4410 return gen_Proj_be_AddSP(node);
4412 return gen_Proj_be_Call(node);
4414 return gen_Proj_Cmp(node);
4416 return gen_Proj_Bound(node);
4418 proj = get_Proj_proj(node);
4419 if (proj == pn_Start_X_initial_exec) {
4420 ir_node *block = get_nodes_block(pred);
4421 dbg_info *dbgi = get_irn_dbg_info(node);
4424 /* we exchange the ProjX with a jump */
4425 block = be_transform_node(block);
4426 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
4429 if (node == be_get_old_anchor(anchor_tls)) {
4430 return gen_Proj_tls(node);
4435 if (is_ia32_l_FloattoLL(pred)) {
4436 return gen_Proj_l_FloattoLL(node);
4438 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4442 ir_mode *mode = get_irn_mode(node);
4443 if (ia32_mode_needs_gp_reg(mode)) {
4444 ir_node *new_pred = be_transform_node(pred);
4445 ir_node *block = be_transform_node(get_nodes_block(node));
4446 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4447 mode_Iu, get_Proj_proj(node));
4448 #ifdef DEBUG_libfirm
4449 new_proj->node_nr = node->node_nr;
4455 return be_duplicate_node(node);
4459 * Enters all transform functions into the generic pointer
4461 static void register_transformers(void)
4465 /* first clear the generic function pointer for all ops */
4466 clear_irp_opcodes_generic_func();
4468 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4469 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4507 /* transform ops from intrinsic lowering */
4519 GEN(ia32_l_LLtoFloat);
4520 GEN(ia32_l_FloattoLL);
4526 /* we should never see these nodes */
4541 /* handle generic backend nodes */
4550 op_Mulh = get_op_Mulh();
4559 * Pre-transform all unknown and noreg nodes.
4561 static void ia32_pretransform_node(void *arch_cg) {
4562 ia32_code_gen_t *cg = arch_cg;
4564 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4565 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4566 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4567 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4568 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4569 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4574 * Walker, checks if all ia32 nodes producing more than one result have their
4575 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4577 static void add_missing_keep_walker(ir_node *node, void *data)
4580 unsigned found_projs = 0;
4581 const ir_edge_t *edge;
4582 ir_mode *mode = get_irn_mode(node);
4587 if(!is_ia32_irn(node))
4590 n_outs = get_ia32_n_res(node);
4593 if(is_ia32_SwitchJmp(node))
4596 assert(n_outs < (int) sizeof(unsigned) * 8);
4597 foreach_out_edge(node, edge) {
4598 ir_node *proj = get_edge_src_irn(edge);
4599 int pn = get_Proj_proj(proj);
4601 if (get_irn_mode(proj) == mode_M)
4604 assert(pn < n_outs);
4605 found_projs |= 1 << pn;
4609 /* are keeps missing? */
4611 for(i = 0; i < n_outs; ++i) {
4614 const arch_register_req_t *req;
4615 const arch_register_class_t *cls;
4617 if(found_projs & (1 << i)) {
4621 req = get_ia32_out_req(node, i);
4626 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4630 block = get_nodes_block(node);
4631 in[0] = new_r_Proj(current_ir_graph, block, node,
4632 arch_register_class_mode(cls), i);
4633 if(last_keep != NULL) {
4634 be_Keep_add_node(last_keep, cls, in[0]);
4636 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4637 if(sched_is_scheduled(node)) {
4638 sched_add_after(node, last_keep);
4645 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4648 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4650 ir_graph *irg = be_get_birg_irg(cg->birg);
4651 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4654 /* do the transformation */
4655 void ia32_transform_graph(ia32_code_gen_t *cg) {
4657 ir_graph *irg = cg->irg;
4659 register_transformers();
4661 initial_fpcw = NULL;
4663 BE_TIMER_PUSH(t_heights);
4664 heights = heights_new(irg);
4665 BE_TIMER_POP(t_heights);
4666 ia32_calculate_non_address_mode_nodes(cg->birg);
4668 /* the transform phase is not safe for CSE (yet) because several nodes get
4669 * attributes set after their creation */
4670 cse_last = get_opt_cse();
4673 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4675 set_opt_cse(cse_last);
4677 ia32_free_non_address_mode_nodes();
4678 heights_free(heights);
4682 void ia32_init_transform(void)
4684 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");