2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
35 #include "irgraph_t.h"
40 #include "iredges_t.h"
52 #include "../benode_t.h"
53 #include "../besched.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
60 #include "bearch_ia32_t.h"
61 #include "ia32_common_transform.h"
62 #include "ia32_nodes_attr.h"
63 #include "ia32_transform.h"
64 #include "ia32_new_nodes.h"
65 #include "ia32_map_regs.h"
66 #include "ia32_dbg_stat.h"
67 #include "ia32_optimize.h"
68 #include "ia32_util.h"
69 #include "ia32_address_mode.h"
70 #include "ia32_architecture.h"
72 #include "gen_ia32_regalloc_if.h"
74 #define SFP_SIGN "0x80000000"
75 #define DFP_SIGN "0x8000000000000000"
76 #define SFP_ABS "0x7FFFFFFF"
77 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
78 #define DFP_INTMAX "9223372036854775807"
80 #define TP_SFP_SIGN "ia32_sfp_sign"
81 #define TP_DFP_SIGN "ia32_dfp_sign"
82 #define TP_SFP_ABS "ia32_sfp_abs"
83 #define TP_DFP_ABS "ia32_dfp_abs"
84 #define TP_INT_MAX "ia32_int_max"
86 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
87 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
88 #define ENT_SFP_ABS "IA32_SFP_ABS"
89 #define ENT_DFP_ABS "IA32_DFP_ABS"
90 #define ENT_INT_MAX "IA32_INT_MAX"
92 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
93 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
95 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
97 static ir_node *initial_fpcw = NULL;
98 static heights_t *heights = NULL;
100 extern ir_op *get_op_Mulh(void);
102 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
103 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
104 ir_node *op1, ir_node *op2);
106 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
107 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
108 ir_node *op1, ir_node *op2, ir_node *flags);
110 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
111 ir_node *block, ir_node *op1, ir_node *op2);
113 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
114 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
117 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
118 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
120 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
121 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
122 ir_node *op1, ir_node *op2, ir_node *fpcw);
124 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
125 ir_node *block, ir_node *op);
127 static ir_node *create_immediate_or_transform(ir_node *node,
128 char immediate_constraint_type);
130 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
131 dbg_info *dbgi, ir_node *block,
132 ir_node *op, ir_node *orig_node);
134 /** Return non-zero is a node represents the 0 constant. */
135 static int is_Const_0(ir_node *node) {
136 return is_Const(node) && is_Const_null(node);
139 /** Return non-zero is a node represents the 1 constant. */
140 static int is_Const_1(ir_node *node) {
141 return is_Const(node) && is_Const_one(node);
144 /** Return non-zero is a node represents the -1 constant. */
145 static int is_Const_Minus_1(ir_node *node) {
146 return is_Const(node) && is_Const_all_one(node);
150 * returns true if constant can be created with a simple float command
152 static int is_simple_x87_Const(ir_node *node)
154 tarval *tv = get_Const_tarval(node);
155 if (tarval_is_null(tv) || tarval_is_one(tv))
158 /* TODO: match all the other float constants */
163 * returns true if constant can be created with a simple float command
165 static int is_simple_sse_Const(ir_node *node)
167 tarval *tv = get_Const_tarval(node);
168 ir_mode *mode = get_tarval_mode(tv);
173 if (tarval_is_null(tv) || tarval_is_one(tv))
176 if (mode == mode_D) {
177 unsigned val = get_tarval_sub_bits(tv, 0) |
178 (get_tarval_sub_bits(tv, 1) << 8) |
179 (get_tarval_sub_bits(tv, 2) << 16) |
180 (get_tarval_sub_bits(tv, 3) << 24);
182 /* lower 32bit are zero, really a 32bit constant */
186 /* TODO: match all the other float constants */
191 * Transforms a Const.
193 static ir_node *gen_Const(ir_node *node) {
194 ir_graph *irg = current_ir_graph;
195 ir_node *old_block = get_nodes_block(node);
196 ir_node *block = be_transform_node(old_block);
197 dbg_info *dbgi = get_irn_dbg_info(node);
198 ir_mode *mode = get_irn_mode(node);
200 assert(is_Const(node));
202 if (mode_is_float(mode)) {
204 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
205 ir_node *nomem = new_NoMem();
209 if (ia32_cg_config.use_sse2) {
210 tarval *tv = get_Const_tarval(node);
211 if (tarval_is_null(tv)) {
212 load = new_rd_ia32_xZero(dbgi, irg, block);
213 set_ia32_ls_mode(load, mode);
215 } else if (tarval_is_one(tv)) {
216 int cnst = mode == mode_F ? 26 : 55;
217 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
218 ir_node *imm2 = create_Immediate(NULL, 0, 2);
219 ir_node *pslld, *psrld;
221 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
222 set_ia32_ls_mode(load, mode);
223 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
224 set_ia32_ls_mode(pslld, mode);
225 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
226 set_ia32_ls_mode(psrld, mode);
228 } else if (mode == mode_F) {
229 /* we can place any 32bit constant by using a movd gp, sse */
230 unsigned val = get_tarval_sub_bits(tv, 0) |
231 (get_tarval_sub_bits(tv, 1) << 8) |
232 (get_tarval_sub_bits(tv, 2) << 16) |
233 (get_tarval_sub_bits(tv, 3) << 24);
234 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
235 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
236 set_ia32_ls_mode(load, mode);
239 if (mode == mode_D) {
240 unsigned val = get_tarval_sub_bits(tv, 0) |
241 (get_tarval_sub_bits(tv, 1) << 8) |
242 (get_tarval_sub_bits(tv, 2) << 16) |
243 (get_tarval_sub_bits(tv, 3) << 24);
245 ir_node *imm32 = create_Immediate(NULL, 0, 32);
246 ir_node *cnst, *psllq;
248 /* fine, lower 32bit are zero, produce 32bit value */
249 val = get_tarval_sub_bits(tv, 4) |
250 (get_tarval_sub_bits(tv, 5) << 8) |
251 (get_tarval_sub_bits(tv, 6) << 16) |
252 (get_tarval_sub_bits(tv, 7) << 24);
253 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
254 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
255 set_ia32_ls_mode(load, mode);
256 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
257 set_ia32_ls_mode(psllq, mode);
262 floatent = create_float_const_entity(node);
264 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
266 set_ia32_op_type(load, ia32_AddrModeS);
267 set_ia32_am_sc(load, floatent);
268 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
269 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
272 if (is_Const_null(node)) {
273 load = new_rd_ia32_vfldz(dbgi, irg, block);
275 set_ia32_ls_mode(load, mode);
276 } else if (is_Const_one(node)) {
277 load = new_rd_ia32_vfld1(dbgi, irg, block);
279 set_ia32_ls_mode(load, mode);
281 floatent = create_float_const_entity(node);
283 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
284 set_ia32_op_type(load, ia32_AddrModeS);
285 set_ia32_am_sc(load, floatent);
286 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
287 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
288 /* take the mode from the entity */
289 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
293 /* Const Nodes before the initial IncSP are a bad idea, because
294 * they could be spilled and we have no SP ready at that point yet.
295 * So add a dependency to the initial frame pointer calculation to
296 * avoid that situation.
298 if (get_irg_start_block(irg) == block) {
299 add_irn_dep(load, get_irg_frame(irg));
302 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
304 } else { /* non-float mode */
306 tarval *tv = get_Const_tarval(node);
309 tv = tarval_convert_to(tv, mode_Iu);
311 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
313 panic("couldn't convert constant tarval (%+F)", node);
315 val = get_tarval_long(tv);
317 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
318 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
321 if (get_irg_start_block(irg) == block) {
322 add_irn_dep(cnst, get_irg_frame(irg));
330 * Transforms a SymConst.
332 static ir_node *gen_SymConst(ir_node *node) {
333 ir_graph *irg = current_ir_graph;
334 ir_node *old_block = get_nodes_block(node);
335 ir_node *block = be_transform_node(old_block);
336 dbg_info *dbgi = get_irn_dbg_info(node);
337 ir_mode *mode = get_irn_mode(node);
340 if (mode_is_float(mode)) {
341 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
342 ir_node *nomem = new_NoMem();
344 if (ia32_cg_config.use_sse2)
345 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
347 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
348 set_ia32_am_sc(cnst, get_SymConst_entity(node));
349 set_ia32_use_frame(cnst);
353 if(get_SymConst_kind(node) != symconst_addr_ent) {
354 panic("backend only support symconst_addr_ent (at %+F)", node);
356 entity = get_SymConst_entity(node);
357 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
360 /* Const Nodes before the initial IncSP are a bad idea, because
361 * they could be spilled and we have no SP ready at that point yet
363 if (get_irg_start_block(irg) == block) {
364 add_irn_dep(cnst, get_irg_frame(irg));
367 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
372 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
373 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
374 static const struct {
376 const char *ent_name;
377 const char *cnst_str;
380 } names [ia32_known_const_max] = {
381 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
382 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
383 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
384 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
385 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
387 static ir_entity *ent_cache[ia32_known_const_max];
389 const char *tp_name, *ent_name, *cnst_str;
397 ent_name = names[kct].ent_name;
398 if (! ent_cache[kct]) {
399 tp_name = names[kct].tp_name;
400 cnst_str = names[kct].cnst_str;
402 switch (names[kct].mode) {
403 case 0: mode = mode_Iu; break;
404 case 1: mode = mode_Lu; break;
405 default: mode = mode_F; break;
407 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
408 tp = new_type_primitive(new_id_from_str(tp_name), mode);
409 /* set the specified alignment */
410 set_type_alignment_bytes(tp, names[kct].align);
412 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
414 set_entity_ld_ident(ent, get_entity_ident(ent));
415 set_entity_visibility(ent, visibility_local);
416 set_entity_variability(ent, variability_constant);
417 set_entity_allocation(ent, allocation_static);
419 /* we create a new entity here: It's initialization must resist on the
421 rem = current_ir_graph;
422 current_ir_graph = get_const_code_irg();
423 cnst = new_Const(mode, tv);
424 current_ir_graph = rem;
426 set_atomic_ent_value(ent, cnst);
428 /* cache the entry */
429 ent_cache[kct] = ent;
432 return ent_cache[kct];
436 * return true if the node is a Proj(Load) and could be used in source address
437 * mode for another node. Will return only true if the @p other node is not
438 * dependent on the memory of the Load (for binary operations use the other
439 * input here, for unary operations use NULL).
441 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
442 ir_node *other, ir_node *other2, match_flags_t flags)
447 /* float constants are always available */
448 if (is_Const(node)) {
449 ir_mode *mode = get_irn_mode(node);
450 if (mode_is_float(mode)) {
451 if (ia32_cg_config.use_sse2) {
452 if (is_simple_sse_Const(node))
455 if (is_simple_x87_Const(node))
458 if (get_irn_n_edges(node) > 1)
466 load = get_Proj_pred(node);
467 pn = get_Proj_proj(node);
468 if (!is_Load(load) || pn != pn_Load_res)
470 if (get_nodes_block(load) != block)
472 /* we only use address mode if we're the only user of the load */
473 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
475 /* in some edge cases with address mode we might reach the load normally
476 * and through some AM sequence, if it is already materialized then we
477 * can't create an AM node from it */
478 if (be_is_transformed(node))
481 /* don't do AM if other node inputs depend on the load (via mem-proj) */
482 if (other != NULL && get_nodes_block(other) == block &&
483 heights_reachable_in_block(heights, other, load))
485 if (other2 != NULL && get_nodes_block(other2) == block &&
486 heights_reachable_in_block(heights, other2, load))
492 typedef struct ia32_address_mode_t ia32_address_mode_t;
493 struct ia32_address_mode_t {
497 ia32_op_type_t op_type;
501 unsigned commutative : 1;
502 unsigned ins_permuted : 1;
505 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
509 /* construct load address */
510 memset(addr, 0, sizeof(addr[0]));
511 ia32_create_address_mode(addr, ptr, /*force=*/0);
513 noreg_gp = ia32_new_NoReg_gp(env_cg);
514 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
515 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
516 addr->mem = be_transform_node(mem);
519 static void build_address(ia32_address_mode_t *am, ir_node *node)
521 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
522 ia32_address_t *addr = &am->addr;
528 if (is_Const(node)) {
529 ir_entity *entity = create_float_const_entity(node);
530 addr->base = noreg_gp;
531 addr->index = noreg_gp;
532 addr->mem = new_NoMem();
533 addr->symconst_ent = entity;
535 am->ls_mode = get_type_mode(get_entity_type(entity));
536 am->pinned = op_pin_state_floats;
540 load = get_Proj_pred(node);
541 ptr = get_Load_ptr(load);
542 mem = get_Load_mem(load);
543 new_mem = be_transform_node(mem);
544 am->pinned = get_irn_pinned(load);
545 am->ls_mode = get_Load_mode(load);
546 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
548 /* construct load address */
549 ia32_create_address_mode(addr, ptr, /*force=*/0);
551 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
552 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
556 static void set_address(ir_node *node, const ia32_address_t *addr)
558 set_ia32_am_scale(node, addr->scale);
559 set_ia32_am_sc(node, addr->symconst_ent);
560 set_ia32_am_offs_int(node, addr->offset);
561 if(addr->symconst_sign)
562 set_ia32_am_sc_sign(node);
564 set_ia32_use_frame(node);
565 set_ia32_frame_ent(node, addr->frame_entity);
569 * Apply attributes of a given address mode to a node.
571 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
573 set_address(node, &am->addr);
575 set_ia32_op_type(node, am->op_type);
576 set_ia32_ls_mode(node, am->ls_mode);
577 if (am->pinned == op_pin_state_pinned) {
578 /* beware: some nodes are already pinned and did not allow to change the state */
579 if (get_irn_pinned(node) != op_pin_state_pinned)
580 set_irn_pinned(node, op_pin_state_pinned);
583 set_ia32_commutative(node);
587 * Check, if a given node is a Down-Conv, ie. a integer Conv
588 * from a mode with a mode with more bits to a mode with lesser bits.
589 * Moreover, we return only true if the node has not more than 1 user.
591 * @param node the node
592 * @return non-zero if node is a Down-Conv
594 static int is_downconv(const ir_node *node)
602 /* we only want to skip the conv when we're the only user
603 * (not optimal but for now...)
605 if(get_irn_n_edges(node) > 1)
608 src_mode = get_irn_mode(get_Conv_op(node));
609 dest_mode = get_irn_mode(node);
610 return ia32_mode_needs_gp_reg(src_mode)
611 && ia32_mode_needs_gp_reg(dest_mode)
612 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
615 /* Skip all Down-Conv's on a given node and return the resulting node. */
616 ir_node *ia32_skip_downconv(ir_node *node) {
617 while (is_downconv(node))
618 node = get_Conv_op(node);
623 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
625 ir_mode *mode = get_irn_mode(node);
630 if(mode_is_signed(mode)) {
635 block = get_nodes_block(node);
636 dbgi = get_irn_dbg_info(node);
638 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
642 * matches operands of a node into ia32 addressing/operand modes. This covers
643 * usage of source address mode, immediates, operations with non 32-bit modes,
645 * The resulting data is filled into the @p am struct. block is the block
646 * of the node whose arguments are matched. op1, op2 are the first and second
647 * input that are matched (op1 may be NULL). other_op is another unrelated
648 * input that is not matched! but which is needed sometimes to check if AM
649 * for op1/op2 is legal.
650 * @p flags describes the supported modes of the operation in detail.
652 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
653 ir_node *op1, ir_node *op2, ir_node *other_op,
656 ia32_address_t *addr = &am->addr;
657 ir_mode *mode = get_irn_mode(op2);
658 int mode_bits = get_mode_size_bits(mode);
659 ir_node *noreg_gp, *new_op1, *new_op2;
661 unsigned commutative;
662 int use_am_and_immediates;
665 memset(am, 0, sizeof(am[0]));
667 commutative = (flags & match_commutative) != 0;
668 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
669 use_am = (flags & match_am) != 0;
670 use_immediate = (flags & match_immediate) != 0;
671 assert(!use_am_and_immediates || use_immediate);
674 assert(!commutative || op1 != NULL);
675 assert(use_am || !(flags & match_8bit_am));
676 assert(use_am || !(flags & match_16bit_am));
678 if (mode_bits == 8) {
679 if (!(flags & match_8bit_am))
681 /* we don't automatically add upconvs yet */
682 assert((flags & match_mode_neutral) || (flags & match_8bit));
683 } else if (mode_bits == 16) {
684 if (!(flags & match_16bit_am))
686 /* we don't automatically add upconvs yet */
687 assert((flags & match_mode_neutral) || (flags & match_16bit));
690 /* we can simply skip downconvs for mode neutral nodes: the upper bits
691 * can be random for these operations */
692 if (flags & match_mode_neutral) {
693 op2 = ia32_skip_downconv(op2);
695 op1 = ia32_skip_downconv(op1);
699 /* match immediates. firm nodes are normalized: constants are always on the
702 if (!(flags & match_try_am) && use_immediate) {
703 new_op2 = try_create_Immediate(op2, 0);
706 noreg_gp = ia32_new_NoReg_gp(env_cg);
707 if (new_op2 == NULL &&
708 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
709 build_address(am, op2);
710 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
711 if (mode_is_float(mode)) {
712 new_op2 = ia32_new_NoReg_vfp(env_cg);
716 am->op_type = ia32_AddrModeS;
717 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
719 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
721 build_address(am, op1);
723 if (mode_is_float(mode)) {
724 noreg = ia32_new_NoReg_vfp(env_cg);
729 if (new_op2 != NULL) {
732 new_op1 = be_transform_node(op2);
734 am->ins_permuted = 1;
736 am->op_type = ia32_AddrModeS;
738 if (flags & match_try_am) {
741 am->op_type = ia32_Normal;
745 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
747 new_op2 = be_transform_node(op2);
748 am->op_type = ia32_Normal;
749 am->ls_mode = get_irn_mode(op2);
750 if (flags & match_mode_neutral)
751 am->ls_mode = mode_Iu;
753 if (addr->base == NULL)
754 addr->base = noreg_gp;
755 if (addr->index == NULL)
756 addr->index = noreg_gp;
757 if (addr->mem == NULL)
758 addr->mem = new_NoMem();
760 am->new_op1 = new_op1;
761 am->new_op2 = new_op2;
762 am->commutative = commutative;
765 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
770 if (am->mem_proj == NULL)
773 /* we have to create a mode_T so the old MemProj can attach to us */
774 mode = get_irn_mode(node);
775 load = get_Proj_pred(am->mem_proj);
777 mark_irn_visited(load);
778 be_set_transformed_node(load, node);
780 if (mode != mode_T) {
781 set_irn_mode(node, mode_T);
782 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
789 * Construct a standard binary operation, set AM and immediate if required.
791 * @param node The original node for which the binop is created
792 * @param op1 The first operand
793 * @param op2 The second operand
794 * @param func The node constructor function
795 * @return The constructed ia32 node.
797 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
798 construct_binop_func *func, match_flags_t flags)
801 ir_node *block, *new_block, *new_node;
802 ia32_address_mode_t am;
803 ia32_address_t *addr = &am.addr;
805 block = get_nodes_block(node);
806 match_arguments(&am, block, op1, op2, NULL, flags);
808 dbgi = get_irn_dbg_info(node);
809 new_block = be_transform_node(block);
810 new_node = func(dbgi, current_ir_graph, new_block,
811 addr->base, addr->index, addr->mem,
812 am.new_op1, am.new_op2);
813 set_am_attributes(new_node, &am);
814 /* we can't use source address mode anymore when using immediates */
815 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
816 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
817 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
819 new_node = fix_mem_proj(new_node, &am);
826 n_ia32_l_binop_right,
827 n_ia32_l_binop_eflags
829 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
830 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
831 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
832 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
833 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
834 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
837 * Construct a binary operation which also consumes the eflags.
839 * @param node The node to transform
840 * @param func The node constructor function
841 * @param flags The match flags
842 * @return The constructor ia32 node
844 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
847 ir_node *src_block = get_nodes_block(node);
848 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
849 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
851 ir_node *block, *new_node, *eflags, *new_eflags;
852 ia32_address_mode_t am;
853 ia32_address_t *addr = &am.addr;
855 match_arguments(&am, src_block, op1, op2, NULL, flags);
857 dbgi = get_irn_dbg_info(node);
858 block = be_transform_node(src_block);
859 eflags = get_irn_n(node, n_ia32_l_binop_eflags);
860 new_eflags = be_transform_node(eflags);
861 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
862 addr->mem, am.new_op1, am.new_op2, new_eflags);
863 set_am_attributes(new_node, &am);
864 /* we can't use source address mode anymore when using immediates */
865 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
866 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
867 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
869 new_node = fix_mem_proj(new_node, &am);
874 static ir_node *get_fpcw(void)
877 if (initial_fpcw != NULL)
880 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
881 &ia32_fp_cw_regs[REG_FPCW]);
882 initial_fpcw = be_transform_node(fpcw);
888 * Construct a standard binary operation, set AM and immediate if required.
890 * @param op1 The first operand
891 * @param op2 The second operand
892 * @param func The node constructor function
893 * @return The constructed ia32 node.
895 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
896 construct_binop_float_func *func,
899 ir_mode *mode = get_irn_mode(node);
901 ir_node *block, *new_block, *new_node;
902 ia32_address_mode_t am;
903 ia32_address_t *addr = &am.addr;
905 /* cannot use address mode with long double on x87 */
906 if (get_mode_size_bits(mode) > 64)
909 block = get_nodes_block(node);
910 match_arguments(&am, block, op1, op2, NULL, flags);
912 dbgi = get_irn_dbg_info(node);
913 new_block = be_transform_node(block);
914 new_node = func(dbgi, current_ir_graph, new_block,
915 addr->base, addr->index, addr->mem,
916 am.new_op1, am.new_op2, get_fpcw());
917 set_am_attributes(new_node, &am);
919 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
921 new_node = fix_mem_proj(new_node, &am);
927 * Construct a shift/rotate binary operation, sets AM and immediate if required.
929 * @param op1 The first operand
930 * @param op2 The second operand
931 * @param func The node constructor function
932 * @return The constructed ia32 node.
934 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
935 construct_shift_func *func,
939 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
941 assert(! mode_is_float(get_irn_mode(node)));
942 assert(flags & match_immediate);
943 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
945 if (flags & match_mode_neutral) {
946 op1 = ia32_skip_downconv(op1);
947 new_op1 = be_transform_node(op1);
948 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
949 new_op1 = create_upconv(op1, node);
951 new_op1 = be_transform_node(op1);
954 /* the shift amount can be any mode that is bigger than 5 bits, since all
955 * other bits are ignored anyway */
956 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
957 ir_node *const op = get_Conv_op(op2);
958 if (mode_is_float(get_irn_mode(op)))
961 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
963 new_op2 = create_immediate_or_transform(op2, 0);
965 dbgi = get_irn_dbg_info(node);
966 block = get_nodes_block(node);
967 new_block = be_transform_node(block);
968 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
969 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
971 /* lowered shift instruction may have a dependency operand, handle it here */
972 if (get_irn_arity(node) == 3) {
973 /* we have a dependency */
974 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
975 add_irn_dep(new_node, new_dep);
983 * Construct a standard unary operation, set AM and immediate if required.
985 * @param op The operand
986 * @param func The node constructor function
987 * @return The constructed ia32 node.
989 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
993 ir_node *block, *new_block, *new_op, *new_node;
995 assert(flags == 0 || flags == match_mode_neutral);
996 if (flags & match_mode_neutral) {
997 op = ia32_skip_downconv(op);
1000 new_op = be_transform_node(op);
1001 dbgi = get_irn_dbg_info(node);
1002 block = get_nodes_block(node);
1003 new_block = be_transform_node(block);
1004 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1006 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1011 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1012 ia32_address_t *addr)
1014 ir_node *base, *index, *res;
1018 base = ia32_new_NoReg_gp(env_cg);
1020 base = be_transform_node(base);
1023 index = addr->index;
1024 if (index == NULL) {
1025 index = ia32_new_NoReg_gp(env_cg);
1027 index = be_transform_node(index);
1030 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1031 set_address(res, addr);
1037 * Returns non-zero if a given address mode has a symbolic or
1038 * numerical offset != 0.
1040 static int am_has_immediates(const ia32_address_t *addr)
1042 return addr->offset != 0 || addr->symconst_ent != NULL
1043 || addr->frame_entity || addr->use_frame;
1047 * Creates an ia32 Add.
1049 * @return the created ia32 Add node
1051 static ir_node *gen_Add(ir_node *node) {
1052 ir_mode *mode = get_irn_mode(node);
1053 ir_node *op1 = get_Add_left(node);
1054 ir_node *op2 = get_Add_right(node);
1056 ir_node *block, *new_block, *new_node, *add_immediate_op;
1057 ia32_address_t addr;
1058 ia32_address_mode_t am;
1060 if (mode_is_float(mode)) {
1061 if (ia32_cg_config.use_sse2)
1062 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1063 match_commutative | match_am);
1065 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1066 match_commutative | match_am);
1069 ia32_mark_non_am(node);
1071 op2 = ia32_skip_downconv(op2);
1072 op1 = ia32_skip_downconv(op1);
1076 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1077 * 1. Add with immediate -> Lea
1078 * 2. Add with possible source address mode -> Add
1079 * 3. Otherwise -> Lea
1081 memset(&addr, 0, sizeof(addr));
1082 ia32_create_address_mode(&addr, node, /*force=*/1);
1083 add_immediate_op = NULL;
1085 dbgi = get_irn_dbg_info(node);
1086 block = get_nodes_block(node);
1087 new_block = be_transform_node(block);
1090 if(addr.base == NULL && addr.index == NULL) {
1091 ir_graph *irg = current_ir_graph;
1092 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1093 addr.symconst_sign, addr.offset);
1094 add_irn_dep(new_node, get_irg_frame(irg));
1095 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1098 /* add with immediate? */
1099 if(addr.index == NULL) {
1100 add_immediate_op = addr.base;
1101 } else if(addr.base == NULL && addr.scale == 0) {
1102 add_immediate_op = addr.index;
1105 if(add_immediate_op != NULL) {
1106 if(!am_has_immediates(&addr)) {
1107 #ifdef DEBUG_libfirm
1108 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1111 return be_transform_node(add_immediate_op);
1114 new_node = create_lea_from_address(dbgi, new_block, &addr);
1115 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1119 /* test if we can use source address mode */
1120 match_arguments(&am, block, op1, op2, NULL, match_commutative
1121 | match_mode_neutral | match_am | match_immediate | match_try_am);
1123 /* construct an Add with source address mode */
1124 if (am.op_type == ia32_AddrModeS) {
1125 ir_graph *irg = current_ir_graph;
1126 ia32_address_t *am_addr = &am.addr;
1127 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1128 am_addr->index, am_addr->mem, am.new_op1,
1130 set_am_attributes(new_node, &am);
1131 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1133 new_node = fix_mem_proj(new_node, &am);
1138 /* otherwise construct a lea */
1139 new_node = create_lea_from_address(dbgi, new_block, &addr);
1140 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1145 * Creates an ia32 Mul.
1147 * @return the created ia32 Mul node
1149 static ir_node *gen_Mul(ir_node *node) {
1150 ir_node *op1 = get_Mul_left(node);
1151 ir_node *op2 = get_Mul_right(node);
1152 ir_mode *mode = get_irn_mode(node);
1154 if (mode_is_float(mode)) {
1155 if (ia32_cg_config.use_sse2)
1156 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1157 match_commutative | match_am);
1159 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1160 match_commutative | match_am);
1162 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1163 match_commutative | match_am | match_mode_neutral |
1164 match_immediate | match_am_and_immediates);
1168 * Creates an ia32 Mulh.
1169 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1170 * this result while Mul returns the lower 32 bit.
1172 * @return the created ia32 Mulh node
1174 static ir_node *gen_Mulh(ir_node *node)
1176 ir_node *block = get_nodes_block(node);
1177 ir_node *new_block = be_transform_node(block);
1178 ir_graph *irg = current_ir_graph;
1179 dbg_info *dbgi = get_irn_dbg_info(node);
1180 ir_mode *mode = get_irn_mode(node);
1181 ir_node *op1 = get_Mulh_left(node);
1182 ir_node *op2 = get_Mulh_right(node);
1183 ir_node *proj_res_high;
1185 ia32_address_mode_t am;
1186 ia32_address_t *addr = &am.addr;
1188 assert(!mode_is_float(mode) && "Mulh with float not supported");
1189 assert(get_mode_size_bits(mode) == 32);
1191 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1193 if (mode_is_signed(mode)) {
1194 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1195 addr->index, addr->mem, am.new_op1,
1198 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1199 addr->index, addr->mem, am.new_op1,
1203 set_am_attributes(new_node, &am);
1204 /* we can't use source address mode anymore when using immediates */
1205 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1206 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1207 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1209 assert(get_irn_mode(new_node) == mode_T);
1211 fix_mem_proj(new_node, &am);
1213 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1214 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1215 mode_Iu, pn_ia32_IMul1OP_res_high);
1217 return proj_res_high;
1223 * Creates an ia32 And.
1225 * @return The created ia32 And node
1227 static ir_node *gen_And(ir_node *node) {
1228 ir_node *op1 = get_And_left(node);
1229 ir_node *op2 = get_And_right(node);
1230 assert(! mode_is_float(get_irn_mode(node)));
1232 /* is it a zero extension? */
1233 if (is_Const(op2)) {
1234 tarval *tv = get_Const_tarval(op2);
1235 long v = get_tarval_long(tv);
1237 if (v == 0xFF || v == 0xFFFF) {
1238 dbg_info *dbgi = get_irn_dbg_info(node);
1239 ir_node *block = get_nodes_block(node);
1246 assert(v == 0xFFFF);
1249 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1254 return gen_binop(node, op1, op2, new_rd_ia32_And,
1255 match_commutative | match_mode_neutral | match_am
1262 * Creates an ia32 Or.
1264 * @return The created ia32 Or node
1266 static ir_node *gen_Or(ir_node *node) {
1267 ir_node *op1 = get_Or_left(node);
1268 ir_node *op2 = get_Or_right(node);
1270 assert (! mode_is_float(get_irn_mode(node)));
1271 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1272 | match_mode_neutral | match_am | match_immediate);
1278 * Creates an ia32 Eor.
1280 * @return The created ia32 Eor node
1282 static ir_node *gen_Eor(ir_node *node) {
1283 ir_node *op1 = get_Eor_left(node);
1284 ir_node *op2 = get_Eor_right(node);
1286 assert(! mode_is_float(get_irn_mode(node)));
1287 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1288 | match_mode_neutral | match_am | match_immediate);
1293 * Creates an ia32 Sub.
1295 * @return The created ia32 Sub node
1297 static ir_node *gen_Sub(ir_node *node) {
1298 ir_node *op1 = get_Sub_left(node);
1299 ir_node *op2 = get_Sub_right(node);
1300 ir_mode *mode = get_irn_mode(node);
1302 if (mode_is_float(mode)) {
1303 if (ia32_cg_config.use_sse2)
1304 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1306 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1310 if (is_Const(op2)) {
1311 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1315 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1316 | match_am | match_immediate);
1320 * Generates an ia32 DivMod with additional infrastructure for the
1321 * register allocator if needed.
1323 static ir_node *create_Div(ir_node *node)
1325 ir_graph *irg = current_ir_graph;
1326 dbg_info *dbgi = get_irn_dbg_info(node);
1327 ir_node *block = get_nodes_block(node);
1328 ir_node *new_block = be_transform_node(block);
1335 ir_node *sign_extension;
1336 ia32_address_mode_t am;
1337 ia32_address_t *addr = &am.addr;
1339 /* the upper bits have random contents for smaller modes */
1340 switch (get_irn_opcode(node)) {
1342 op1 = get_Div_left(node);
1343 op2 = get_Div_right(node);
1344 mem = get_Div_mem(node);
1345 mode = get_Div_resmode(node);
1348 op1 = get_Mod_left(node);
1349 op2 = get_Mod_right(node);
1350 mem = get_Mod_mem(node);
1351 mode = get_Mod_resmode(node);
1354 op1 = get_DivMod_left(node);
1355 op2 = get_DivMod_right(node);
1356 mem = get_DivMod_mem(node);
1357 mode = get_DivMod_resmode(node);
1360 panic("invalid divmod node %+F", node);
1363 match_arguments(&am, block, op1, op2, NULL, match_am);
1365 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1366 is the memory of the consumed address. We can have only the second op as address
1367 in Div nodes, so check only op2. */
1368 if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1369 new_mem = be_transform_node(mem);
1370 if(!is_NoMem(addr->mem)) {
1374 new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1377 new_mem = addr->mem;
1380 if (mode_is_signed(mode)) {
1381 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1382 add_irn_dep(produceval, get_irg_frame(irg));
1383 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1386 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1387 addr->index, new_mem, am.new_op2,
1388 am.new_op1, sign_extension);
1390 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1391 add_irn_dep(sign_extension, get_irg_frame(irg));
1393 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1394 addr->index, new_mem, am.new_op2,
1395 am.new_op1, sign_extension);
1398 set_irn_pinned(new_node, get_irn_pinned(node));
1400 set_am_attributes(new_node, &am);
1401 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1403 new_node = fix_mem_proj(new_node, &am);
1409 static ir_node *gen_Mod(ir_node *node) {
1410 return create_Div(node);
1413 static ir_node *gen_Div(ir_node *node) {
1414 return create_Div(node);
1417 static ir_node *gen_DivMod(ir_node *node) {
1418 return create_Div(node);
1424 * Creates an ia32 floating Div.
1426 * @return The created ia32 xDiv node
1428 static ir_node *gen_Quot(ir_node *node)
1430 ir_node *op1 = get_Quot_left(node);
1431 ir_node *op2 = get_Quot_right(node);
1433 if (ia32_cg_config.use_sse2) {
1434 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1436 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1442 * Creates an ia32 Shl.
1444 * @return The created ia32 Shl node
1446 static ir_node *gen_Shl(ir_node *node) {
1447 ir_node *left = get_Shl_left(node);
1448 ir_node *right = get_Shl_right(node);
1450 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1451 match_mode_neutral | match_immediate);
1455 * Creates an ia32 Shr.
1457 * @return The created ia32 Shr node
1459 static ir_node *gen_Shr(ir_node *node) {
1460 ir_node *left = get_Shr_left(node);
1461 ir_node *right = get_Shr_right(node);
1463 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1469 * Creates an ia32 Sar.
1471 * @return The created ia32 Shrs node
1473 static ir_node *gen_Shrs(ir_node *node) {
1474 ir_node *left = get_Shrs_left(node);
1475 ir_node *right = get_Shrs_right(node);
1476 ir_mode *mode = get_irn_mode(node);
1478 if(is_Const(right) && mode == mode_Is) {
1479 tarval *tv = get_Const_tarval(right);
1480 long val = get_tarval_long(tv);
1482 /* this is a sign extension */
1483 ir_graph *irg = current_ir_graph;
1484 dbg_info *dbgi = get_irn_dbg_info(node);
1485 ir_node *block = be_transform_node(get_nodes_block(node));
1487 ir_node *new_op = be_transform_node(op);
1488 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1489 add_irn_dep(pval, get_irg_frame(irg));
1491 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1495 /* 8 or 16 bit sign extension? */
1496 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1497 ir_node *shl_left = get_Shl_left(left);
1498 ir_node *shl_right = get_Shl_right(left);
1499 if(is_Const(shl_right)) {
1500 tarval *tv1 = get_Const_tarval(right);
1501 tarval *tv2 = get_Const_tarval(shl_right);
1502 if(tv1 == tv2 && tarval_is_long(tv1)) {
1503 long val = get_tarval_long(tv1);
1504 if(val == 16 || val == 24) {
1505 dbg_info *dbgi = get_irn_dbg_info(node);
1506 ir_node *block = get_nodes_block(node);
1516 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1525 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1531 * Creates an ia32 Rol.
1533 * @param op1 The first operator
1534 * @param op2 The second operator
1535 * @return The created ia32 RotL node
1537 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1538 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1544 * Creates an ia32 Ror.
1545 * NOTE: There is no RotR with immediate because this would always be a RotL
1546 * "imm-mode_size_bits" which can be pre-calculated.
1548 * @param op1 The first operator
1549 * @param op2 The second operator
1550 * @return The created ia32 RotR node
1552 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1553 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1559 * Creates an ia32 RotR or RotL (depending on the found pattern).
1561 * @return The created ia32 RotL or RotR node
1563 static ir_node *gen_Rotl(ir_node *node) {
1564 ir_node *rotate = NULL;
1565 ir_node *op1 = get_Rotl_left(node);
1566 ir_node *op2 = get_Rotl_right(node);
1568 /* Firm has only RotL, so we are looking for a right (op2)
1569 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1570 that means we can create a RotR instead of an Add and a RotL */
1574 ir_node *left = get_Add_left(add);
1575 ir_node *right = get_Add_right(add);
1576 if (is_Const(right)) {
1577 tarval *tv = get_Const_tarval(right);
1578 ir_mode *mode = get_irn_mode(node);
1579 long bits = get_mode_size_bits(mode);
1581 if (is_Minus(left) &&
1582 tarval_is_long(tv) &&
1583 get_tarval_long(tv) == bits &&
1586 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1587 rotate = gen_Ror(node, op1, get_Minus_op(left));
1592 if (rotate == NULL) {
1593 rotate = gen_Rol(node, op1, op2);
1602 * Transforms a Minus node.
1604 * @return The created ia32 Minus node
1606 static ir_node *gen_Minus(ir_node *node)
1608 ir_node *op = get_Minus_op(node);
1609 ir_node *block = be_transform_node(get_nodes_block(node));
1610 ir_graph *irg = current_ir_graph;
1611 dbg_info *dbgi = get_irn_dbg_info(node);
1612 ir_mode *mode = get_irn_mode(node);
1617 if (mode_is_float(mode)) {
1618 ir_node *new_op = be_transform_node(op);
1619 if (ia32_cg_config.use_sse2) {
1620 /* TODO: non-optimal... if we have many xXors, then we should
1621 * rather create a load for the const and use that instead of
1622 * several AM nodes... */
1623 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1624 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1625 ir_node *nomem = new_rd_NoMem(irg);
1627 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1628 nomem, new_op, noreg_xmm);
1630 size = get_mode_size_bits(mode);
1631 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1633 set_ia32_am_sc(new_node, ent);
1634 set_ia32_op_type(new_node, ia32_AddrModeS);
1635 set_ia32_ls_mode(new_node, mode);
1637 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1640 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1643 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1649 * Transforms a Not node.
1651 * @return The created ia32 Not node
1653 static ir_node *gen_Not(ir_node *node) {
1654 ir_node *op = get_Not_op(node);
1656 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1657 assert (! mode_is_float(get_irn_mode(node)));
1659 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1665 * Transforms an Abs node.
1667 * @return The created ia32 Abs node
1669 static ir_node *gen_Abs(ir_node *node)
1671 ir_node *block = get_nodes_block(node);
1672 ir_node *new_block = be_transform_node(block);
1673 ir_node *op = get_Abs_op(node);
1674 ir_graph *irg = current_ir_graph;
1675 dbg_info *dbgi = get_irn_dbg_info(node);
1676 ir_mode *mode = get_irn_mode(node);
1677 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1678 ir_node *nomem = new_NoMem();
1684 if (mode_is_float(mode)) {
1685 new_op = be_transform_node(op);
1687 if (ia32_cg_config.use_sse2) {
1688 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1689 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1690 nomem, new_op, noreg_fp);
1692 size = get_mode_size_bits(mode);
1693 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1695 set_ia32_am_sc(new_node, ent);
1697 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1699 set_ia32_op_type(new_node, ia32_AddrModeS);
1700 set_ia32_ls_mode(new_node, mode);
1702 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1703 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1706 ir_node *xor, *pval, *sign_extension;
1708 if (get_mode_size_bits(mode) == 32) {
1709 new_op = be_transform_node(op);
1711 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1714 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1715 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1718 add_irn_dep(pval, get_irg_frame(irg));
1719 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1721 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1722 nomem, new_op, sign_extension);
1723 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1725 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1726 nomem, xor, sign_extension);
1727 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1734 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1736 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1737 dbg_info *dbgi = get_irn_dbg_info(cmp);
1738 ir_node *block = get_nodes_block(cmp);
1739 ir_node *new_block = be_transform_node(block);
1740 ir_node *op1 = be_transform_node(x);
1741 ir_node *op2 = be_transform_node(n);
1743 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1747 * Transform a node returning a "flag" result.
1749 * @param node the node to transform
1750 * @param pnc_out the compare mode to use
1752 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1761 /* we have a Cmp as input */
1762 if (is_Proj(node)) {
1763 ir_node *pred = get_Proj_pred(node);
1765 pn_Cmp pnc = get_Proj_proj(node);
1766 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1767 ir_node *l = get_Cmp_left(pred);
1768 ir_node *r = get_Cmp_right(pred);
1770 ir_node *la = get_And_left(l);
1771 ir_node *ra = get_And_right(l);
1773 ir_node *c = get_Shl_left(la);
1774 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1775 /* (1 << n) & ra) */
1776 ir_node *n = get_Shl_right(la);
1777 flags = gen_bt(pred, ra, n);
1778 /* we must generate a Jc/Jnc jump */
1779 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1782 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1787 ir_node *c = get_Shl_left(ra);
1788 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1789 /* la & (1 << n)) */
1790 ir_node *n = get_Shl_right(ra);
1791 flags = gen_bt(pred, la, 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;
1802 flags = be_transform_node(pred);
1808 /* a mode_b value, we have to compare it against 0 */
1809 dbgi = get_irn_dbg_info(node);
1810 new_block = be_transform_node(get_nodes_block(node));
1811 new_op = be_transform_node(node);
1812 noreg = ia32_new_NoReg_gp(env_cg);
1813 nomem = new_NoMem();
1814 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1815 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1816 *pnc_out = pn_Cmp_Lg;
1821 * Transforms a Load.
1823 * @return the created ia32 Load node
1825 static ir_node *gen_Load(ir_node *node) {
1826 ir_node *old_block = get_nodes_block(node);
1827 ir_node *block = be_transform_node(old_block);
1828 ir_node *ptr = get_Load_ptr(node);
1829 ir_node *mem = get_Load_mem(node);
1830 ir_node *new_mem = be_transform_node(mem);
1833 ir_graph *irg = current_ir_graph;
1834 dbg_info *dbgi = get_irn_dbg_info(node);
1835 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1836 ir_mode *mode = get_Load_mode(node);
1839 ia32_address_t addr;
1841 /* construct load address */
1842 memset(&addr, 0, sizeof(addr));
1843 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1850 base = be_transform_node(base);
1856 index = be_transform_node(index);
1859 if (mode_is_float(mode)) {
1860 if (ia32_cg_config.use_sse2) {
1861 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1863 res_mode = mode_xmm;
1865 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1867 res_mode = mode_vfp;
1870 assert(mode != mode_b);
1872 /* create a conv node with address mode for smaller modes */
1873 if(get_mode_size_bits(mode) < 32) {
1874 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1875 new_mem, noreg, mode);
1877 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1882 set_irn_pinned(new_node, get_irn_pinned(node));
1883 set_ia32_op_type(new_node, ia32_AddrModeS);
1884 set_ia32_ls_mode(new_node, mode);
1885 set_address(new_node, &addr);
1887 if(get_irn_pinned(node) == op_pin_state_floats) {
1888 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1891 /* make sure we are scheduled behind the initial IncSP/Barrier
1892 * to avoid spills being placed before it
1894 if (block == get_irg_start_block(irg)) {
1895 add_irn_dep(new_node, get_irg_frame(irg));
1898 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1903 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1904 ir_node *ptr, ir_node *other)
1911 /* we only use address mode if we're the only user of the load */
1912 if(get_irn_n_edges(node) > 1)
1915 load = get_Proj_pred(node);
1918 if(get_nodes_block(load) != block)
1921 /* Store should be attached to the load */
1922 if(!is_Proj(mem) || get_Proj_pred(mem) != load)
1924 /* store should have the same pointer as the load */
1925 if(get_Load_ptr(load) != ptr)
1928 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1929 if(other != NULL && get_nodes_block(other) == block
1930 && heights_reachable_in_block(heights, other, load))
1936 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
1938 mark_irn_visited(old_node);
1939 be_set_transformed_node(old_node, new_node);
1942 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1943 ir_node *mem, ir_node *ptr, ir_mode *mode,
1944 construct_binop_dest_func *func,
1945 construct_binop_dest_func *func8bit,
1946 match_flags_t flags)
1948 ir_node *src_block = get_nodes_block(node);
1950 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1951 ir_graph *irg = current_ir_graph;
1957 ia32_address_mode_t am;
1958 ia32_address_t *addr = &am.addr;
1959 memset(&am, 0, sizeof(am));
1961 assert(flags & match_dest_am);
1962 assert(flags & match_immediate); /* there is no destam node without... */
1963 commutative = (flags & match_commutative) != 0;
1965 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
1966 build_address(&am, op1);
1967 new_op = create_immediate_or_transform(op2, 0);
1968 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1969 build_address(&am, op2);
1970 new_op = create_immediate_or_transform(op1, 0);
1975 if(addr->base == NULL)
1976 addr->base = noreg_gp;
1977 if(addr->index == NULL)
1978 addr->index = noreg_gp;
1979 if(addr->mem == NULL)
1980 addr->mem = new_NoMem();
1982 dbgi = get_irn_dbg_info(node);
1983 block = be_transform_node(src_block);
1984 if(get_mode_size_bits(mode) == 8) {
1985 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
1988 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
1991 set_address(new_node, addr);
1992 set_ia32_op_type(new_node, ia32_AddrModeD);
1993 set_ia32_ls_mode(new_node, mode);
1994 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1996 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
1997 mem_proj = be_transform_node(am.mem_proj);
1998 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2003 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2004 ir_node *ptr, ir_mode *mode,
2005 construct_unop_dest_func *func)
2007 ir_graph *irg = current_ir_graph;
2008 ir_node *src_block = get_nodes_block(node);
2013 ia32_address_mode_t am;
2014 ia32_address_t *addr = &am.addr;
2015 memset(&am, 0, sizeof(am));
2017 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2020 build_address(&am, op);
2022 dbgi = get_irn_dbg_info(node);
2023 block = be_transform_node(src_block);
2024 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2025 set_address(new_node, addr);
2026 set_ia32_op_type(new_node, ia32_AddrModeD);
2027 set_ia32_ls_mode(new_node, mode);
2028 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2030 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2031 mem_proj = be_transform_node(am.mem_proj);
2032 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2037 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2038 ir_mode *mode = get_irn_mode(node);
2039 ir_node *mux_true = get_Mux_true(node);
2040 ir_node *mux_false = get_Mux_false(node);
2051 ia32_address_t addr;
2053 if(get_mode_size_bits(mode) != 8)
2056 if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2058 } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2064 build_address_ptr(&addr, ptr, mem);
2066 irg = current_ir_graph;
2067 dbgi = get_irn_dbg_info(node);
2068 block = get_nodes_block(node);
2069 new_block = be_transform_node(block);
2070 cond = get_Mux_sel(node);
2071 flags = get_flags_node(cond, &pnc);
2072 new_mem = be_transform_node(mem);
2073 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2074 addr.index, addr.mem, flags, pnc, negated);
2075 set_address(new_node, &addr);
2076 set_ia32_op_type(new_node, ia32_AddrModeD);
2077 set_ia32_ls_mode(new_node, mode);
2078 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2083 static ir_node *try_create_dest_am(ir_node *node) {
2084 ir_node *val = get_Store_value(node);
2085 ir_node *mem = get_Store_mem(node);
2086 ir_node *ptr = get_Store_ptr(node);
2087 ir_mode *mode = get_irn_mode(val);
2088 unsigned bits = get_mode_size_bits(mode);
2093 /* handle only GP modes for now... */
2094 if(!ia32_mode_needs_gp_reg(mode))
2098 /* store must be the only user of the val node */
2099 if(get_irn_n_edges(val) > 1)
2101 /* skip pointless convs */
2103 ir_node *conv_op = get_Conv_op(val);
2104 ir_mode *pred_mode = get_irn_mode(conv_op);
2105 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2113 /* value must be in the same block */
2114 if(get_nodes_block(node) != get_nodes_block(val))
2117 switch (get_irn_opcode(val)) {
2119 op1 = get_Add_left(val);
2120 op2 = get_Add_right(val);
2121 if(is_Const_1(op2)) {
2122 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2123 new_rd_ia32_IncMem);
2125 } else if(is_Const_Minus_1(op2)) {
2126 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2127 new_rd_ia32_DecMem);
2130 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2131 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2132 match_dest_am | match_commutative |
2136 op1 = get_Sub_left(val);
2137 op2 = get_Sub_right(val);
2139 ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2142 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2143 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2144 match_dest_am | match_immediate |
2148 op1 = get_And_left(val);
2149 op2 = get_And_right(val);
2150 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2151 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2152 match_dest_am | match_commutative |
2156 op1 = get_Or_left(val);
2157 op2 = get_Or_right(val);
2158 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2159 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2160 match_dest_am | match_commutative |
2164 op1 = get_Eor_left(val);
2165 op2 = get_Eor_right(val);
2166 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2167 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2168 match_dest_am | match_commutative |
2172 op1 = get_Shl_left(val);
2173 op2 = get_Shl_right(val);
2174 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2175 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2176 match_dest_am | match_immediate);
2179 op1 = get_Shr_left(val);
2180 op2 = get_Shr_right(val);
2181 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2182 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2183 match_dest_am | match_immediate);
2186 op1 = get_Shrs_left(val);
2187 op2 = get_Shrs_right(val);
2188 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2189 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2190 match_dest_am | match_immediate);
2193 op1 = get_Rotl_left(val);
2194 op2 = get_Rotl_right(val);
2195 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2196 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2197 match_dest_am | match_immediate);
2199 /* TODO: match ROR patterns... */
2201 new_node = try_create_SetMem(val, ptr, mem);
2204 op1 = get_Minus_op(val);
2205 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2208 /* should be lowered already */
2209 assert(mode != mode_b);
2210 op1 = get_Not_op(val);
2211 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2217 if(new_node != NULL) {
2218 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2219 get_irn_pinned(node) == op_pin_state_pinned) {
2220 set_irn_pinned(new_node, op_pin_state_pinned);
2227 static int is_float_to_int32_conv(const ir_node *node)
2229 ir_mode *mode = get_irn_mode(node);
2233 if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode))
2235 /* don't report unsigned as conv to 32bit, because we really need to do
2236 * a vfist with 64bit signed in this case */
2237 if(!mode_is_signed(mode))
2242 conv_op = get_Conv_op(node);
2243 conv_mode = get_irn_mode(conv_op);
2245 if(!mode_is_float(conv_mode))
2252 * Transform a Store(floatConst).
2254 * @return the created ia32 Store node
2256 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2257 ir_mode *mode = get_irn_mode(cns);
2258 int size = get_mode_size_bits(mode);
2259 tarval *tv = get_Const_tarval(cns);
2260 ir_node *block = get_nodes_block(node);
2261 ir_node *new_block = be_transform_node(block);
2262 ir_node *ptr = get_Store_ptr(node);
2263 ir_node *mem = get_Store_mem(node);
2264 ir_graph *irg = current_ir_graph;
2265 dbg_info *dbgi = get_irn_dbg_info(node);
2266 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2269 ia32_address_t addr;
2271 unsigned val = get_tarval_sub_bits(tv, 0) |
2272 (get_tarval_sub_bits(tv, 1) << 8) |
2273 (get_tarval_sub_bits(tv, 2) << 16) |
2274 (get_tarval_sub_bits(tv, 3) << 24);
2275 ir_node *imm = create_Immediate(NULL, 0, val);
2277 /* construct store address */
2278 memset(&addr, 0, sizeof(addr));
2279 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2281 if (addr.base == NULL) {
2284 addr.base = be_transform_node(addr.base);
2287 if (addr.index == NULL) {
2290 addr.index = be_transform_node(addr.index);
2292 addr.mem = be_transform_node(mem);
2294 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2295 addr.index, addr.mem, imm);
2297 set_irn_pinned(new_node, get_irn_pinned(node));
2298 set_ia32_op_type(new_node, ia32_AddrModeD);
2299 set_ia32_ls_mode(new_node, mode_Iu);
2301 set_address(new_node, &addr);
2303 /** add more stores if needed */
2305 unsigned val = get_tarval_sub_bits(tv, ofs) |
2306 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2307 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2308 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2309 ir_node *imm = create_Immediate(NULL, 0, val);
2312 addr.mem = new_node;
2314 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2315 addr.index, addr.mem, imm);
2317 set_irn_pinned(new_node, get_irn_pinned(node));
2318 set_ia32_op_type(new_node, ia32_AddrModeD);
2319 set_ia32_ls_mode(new_node, mode_Iu);
2321 set_address(new_node, &addr);
2326 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2331 * Generate a vfist or vfisttp instruction.
2333 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2334 ir_node *mem, ir_node *val, ir_node **fist)
2338 if (ia32_cg_config.use_fisttp) {
2339 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2340 if other users exists */
2341 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2342 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2343 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2344 be_new_Keep(reg_class, irg, block, 1, &value);
2346 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2349 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2352 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2358 * Transforms a normal Store.
2360 * @return the created ia32 Store node
2362 static ir_node *gen_normal_Store(ir_node *node)
2364 ir_node *val = get_Store_value(node);
2365 ir_mode *mode = get_irn_mode(val);
2366 ir_node *block = get_nodes_block(node);
2367 ir_node *new_block = be_transform_node(block);
2368 ir_node *ptr = get_Store_ptr(node);
2369 ir_node *mem = get_Store_mem(node);
2370 ir_graph *irg = current_ir_graph;
2371 dbg_info *dbgi = get_irn_dbg_info(node);
2372 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2373 ir_node *new_val, *new_node, *store;
2374 ia32_address_t addr;
2376 /* check for destination address mode */
2377 new_node = try_create_dest_am(node);
2378 if (new_node != NULL)
2381 /* construct store address */
2382 memset(&addr, 0, sizeof(addr));
2383 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2385 if (addr.base == NULL) {
2388 addr.base = be_transform_node(addr.base);
2391 if (addr.index == NULL) {
2394 addr.index = be_transform_node(addr.index);
2396 addr.mem = be_transform_node(mem);
2398 if (mode_is_float(mode)) {
2399 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2401 while (is_Conv(val) && mode == get_irn_mode(val)) {
2402 ir_node *op = get_Conv_op(val);
2403 if (!mode_is_float(get_irn_mode(op)))
2407 new_val = be_transform_node(val);
2408 if (ia32_cg_config.use_sse2) {
2409 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2410 addr.index, addr.mem, new_val);
2412 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2413 addr.index, addr.mem, new_val, mode);
2416 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2417 val = get_Conv_op(val);
2419 /* TODO: is this optimisation still necessary at all (middleend)? */
2420 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2421 while (is_Conv(val)) {
2422 ir_node *op = get_Conv_op(val);
2423 if (!mode_is_float(get_irn_mode(op)))
2425 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2429 new_val = be_transform_node(val);
2430 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2432 new_val = create_immediate_or_transform(val, 0);
2433 assert(mode != mode_b);
2435 if (get_mode_size_bits(mode) == 8) {
2436 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2437 addr.index, addr.mem, new_val);
2439 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2440 addr.index, addr.mem, new_val);
2445 set_irn_pinned(store, get_irn_pinned(node));
2446 set_ia32_op_type(store, ia32_AddrModeD);
2447 set_ia32_ls_mode(store, mode);
2449 set_address(store, &addr);
2450 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2456 * Transforms a Store.
2458 * @return the created ia32 Store node
2460 static ir_node *gen_Store(ir_node *node)
2462 ir_node *val = get_Store_value(node);
2463 ir_mode *mode = get_irn_mode(val);
2465 if (mode_is_float(mode) && is_Const(val)) {
2468 /* we are storing a floating point constant */
2469 if (ia32_cg_config.use_sse2) {
2470 transform = !is_simple_sse_Const(val);
2472 transform = !is_simple_x87_Const(val);
2475 return gen_float_const_Store(node, val);
2477 return gen_normal_Store(node);
2481 * Transforms a Switch.
2483 * @return the created ia32 SwitchJmp node
2485 static ir_node *create_Switch(ir_node *node)
2487 ir_graph *irg = current_ir_graph;
2488 dbg_info *dbgi = get_irn_dbg_info(node);
2489 ir_node *block = be_transform_node(get_nodes_block(node));
2490 ir_node *sel = get_Cond_selector(node);
2491 ir_node *new_sel = be_transform_node(sel);
2492 int switch_min = INT_MAX;
2493 int switch_max = INT_MIN;
2494 long default_pn = get_Cond_defaultProj(node);
2496 const ir_edge_t *edge;
2498 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2500 /* determine the smallest switch case value */
2501 foreach_out_edge(node, edge) {
2502 ir_node *proj = get_edge_src_irn(edge);
2503 long pn = get_Proj_proj(proj);
2504 if(pn == default_pn)
2513 if((unsigned) (switch_max - switch_min) > 256000) {
2514 panic("Size of switch %+F bigger than 256000", node);
2517 if (switch_min != 0) {
2518 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2520 /* if smallest switch case is not 0 we need an additional sub */
2521 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2522 add_ia32_am_offs_int(new_sel, -switch_min);
2523 set_ia32_op_type(new_sel, ia32_AddrModeS);
2525 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2528 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2529 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2535 * Transform a Cond node.
2537 static ir_node *gen_Cond(ir_node *node) {
2538 ir_node *block = get_nodes_block(node);
2539 ir_node *new_block = be_transform_node(block);
2540 ir_graph *irg = current_ir_graph;
2541 dbg_info *dbgi = get_irn_dbg_info(node);
2542 ir_node *sel = get_Cond_selector(node);
2543 ir_mode *sel_mode = get_irn_mode(sel);
2544 ir_node *flags = NULL;
2548 if (sel_mode != mode_b) {
2549 return create_Switch(node);
2552 /* we get flags from a Cmp */
2553 flags = get_flags_node(sel, &pnc);
2555 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2556 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2562 * Transforms a CopyB node.
2564 * @return The transformed node.
2566 static ir_node *gen_CopyB(ir_node *node) {
2567 ir_node *block = be_transform_node(get_nodes_block(node));
2568 ir_node *src = get_CopyB_src(node);
2569 ir_node *new_src = be_transform_node(src);
2570 ir_node *dst = get_CopyB_dst(node);
2571 ir_node *new_dst = be_transform_node(dst);
2572 ir_node *mem = get_CopyB_mem(node);
2573 ir_node *new_mem = be_transform_node(mem);
2574 ir_node *res = NULL;
2575 ir_graph *irg = current_ir_graph;
2576 dbg_info *dbgi = get_irn_dbg_info(node);
2577 int size = get_type_size_bytes(get_CopyB_type(node));
2580 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2581 /* then we need the size explicitly in ECX. */
2582 if (size >= 32 * 4) {
2583 rem = size & 0x3; /* size % 4 */
2586 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2587 add_irn_dep(res, get_irg_frame(irg));
2589 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2592 ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2595 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2598 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2603 static ir_node *gen_be_Copy(ir_node *node)
2605 ir_node *new_node = be_duplicate_node(node);
2606 ir_mode *mode = get_irn_mode(new_node);
2608 if (ia32_mode_needs_gp_reg(mode)) {
2609 set_irn_mode(new_node, mode_Iu);
2615 static ir_node *create_Fucom(ir_node *node)
2617 ir_graph *irg = current_ir_graph;
2618 dbg_info *dbgi = get_irn_dbg_info(node);
2619 ir_node *block = get_nodes_block(node);
2620 ir_node *new_block = be_transform_node(block);
2621 ir_node *left = get_Cmp_left(node);
2622 ir_node *new_left = be_transform_node(left);
2623 ir_node *right = get_Cmp_right(node);
2627 if(ia32_cg_config.use_fucomi) {
2628 new_right = be_transform_node(right);
2629 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2631 set_ia32_commutative(new_node);
2632 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2634 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2635 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2638 new_right = be_transform_node(right);
2639 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2643 set_ia32_commutative(new_node);
2645 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2647 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2648 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2654 static ir_node *create_Ucomi(ir_node *node)
2656 ir_graph *irg = current_ir_graph;
2657 dbg_info *dbgi = get_irn_dbg_info(node);
2658 ir_node *src_block = get_nodes_block(node);
2659 ir_node *new_block = be_transform_node(src_block);
2660 ir_node *left = get_Cmp_left(node);
2661 ir_node *right = get_Cmp_right(node);
2663 ia32_address_mode_t am;
2664 ia32_address_t *addr = &am.addr;
2666 match_arguments(&am, src_block, left, right, NULL,
2667 match_commutative | match_am);
2669 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2670 addr->mem, am.new_op1, am.new_op2,
2672 set_am_attributes(new_node, &am);
2674 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2676 new_node = fix_mem_proj(new_node, &am);
2682 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2683 * to fold an and into a test node
2685 static int can_fold_test_and(ir_node *node)
2687 const ir_edge_t *edge;
2689 /** we can only have eq and lg projs */
2690 foreach_out_edge(node, edge) {
2691 ir_node *proj = get_edge_src_irn(edge);
2692 pn_Cmp pnc = get_Proj_proj(proj);
2693 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2701 * Generate code for a Cmp.
2703 static ir_node *gen_Cmp(ir_node *node)
2705 ir_graph *irg = current_ir_graph;
2706 dbg_info *dbgi = get_irn_dbg_info(node);
2707 ir_node *block = get_nodes_block(node);
2708 ir_node *new_block = be_transform_node(block);
2709 ir_node *left = get_Cmp_left(node);
2710 ir_node *right = get_Cmp_right(node);
2711 ir_mode *cmp_mode = get_irn_mode(left);
2713 ia32_address_mode_t am;
2714 ia32_address_t *addr = &am.addr;
2717 if(mode_is_float(cmp_mode)) {
2718 if (ia32_cg_config.use_sse2) {
2719 return create_Ucomi(node);
2721 return create_Fucom(node);
2725 assert(ia32_mode_needs_gp_reg(cmp_mode));
2727 /* we prefer the Test instruction where possible except cases where
2728 * we can use SourceAM */
2729 cmp_unsigned = !mode_is_signed(cmp_mode);
2730 if (is_Const_0(right)) {
2732 get_irn_n_edges(left) == 1 &&
2733 can_fold_test_and(node)) {
2734 /* Test(and_left, and_right) */
2735 ir_node *and_left = get_And_left(left);
2736 ir_node *and_right = get_And_right(left);
2737 ir_mode *mode = get_irn_mode(and_left);
2739 match_arguments(&am, block, and_left, and_right, NULL,
2741 match_am | match_8bit_am | match_16bit_am |
2742 match_am_and_immediates | match_immediate |
2743 match_8bit | match_16bit);
2744 if (get_mode_size_bits(mode) == 8) {
2745 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2746 addr->index, addr->mem, am.new_op1,
2747 am.new_op2, am.ins_permuted,
2750 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2751 addr->index, addr->mem, am.new_op1,
2752 am.new_op2, am.ins_permuted, cmp_unsigned);
2755 match_arguments(&am, block, NULL, left, NULL,
2756 match_am | match_8bit_am | match_16bit_am |
2757 match_8bit | match_16bit);
2758 if (am.op_type == ia32_AddrModeS) {
2760 ir_node *imm_zero = try_create_Immediate(right, 0);
2761 if (get_mode_size_bits(cmp_mode) == 8) {
2762 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2763 addr->index, addr->mem, am.new_op2,
2764 imm_zero, am.ins_permuted,
2767 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2768 addr->index, addr->mem, am.new_op2,
2769 imm_zero, am.ins_permuted, cmp_unsigned);
2772 /* Test(left, left) */
2773 if (get_mode_size_bits(cmp_mode) == 8) {
2774 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2775 addr->index, addr->mem, am.new_op2,
2776 am.new_op2, am.ins_permuted,
2779 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2780 addr->index, addr->mem, am.new_op2,
2781 am.new_op2, am.ins_permuted,
2787 /* Cmp(left, right) */
2788 match_arguments(&am, block, left, right, NULL,
2789 match_commutative | match_am | match_8bit_am |
2790 match_16bit_am | match_am_and_immediates |
2791 match_immediate | match_8bit | match_16bit);
2792 if (get_mode_size_bits(cmp_mode) == 8) {
2793 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2794 addr->index, addr->mem, am.new_op1,
2795 am.new_op2, am.ins_permuted,
2798 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2799 addr->index, addr->mem, am.new_op1,
2800 am.new_op2, am.ins_permuted, cmp_unsigned);
2803 set_am_attributes(new_node, &am);
2804 assert(cmp_mode != NULL);
2805 set_ia32_ls_mode(new_node, cmp_mode);
2807 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2809 new_node = fix_mem_proj(new_node, &am);
2814 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2817 ir_graph *irg = current_ir_graph;
2818 dbg_info *dbgi = get_irn_dbg_info(node);
2819 ir_node *block = get_nodes_block(node);
2820 ir_node *new_block = be_transform_node(block);
2821 ir_node *val_true = get_Mux_true(node);
2822 ir_node *val_false = get_Mux_false(node);
2824 match_flags_t match_flags;
2825 ia32_address_mode_t am;
2826 ia32_address_t *addr;
2828 assert(ia32_cg_config.use_cmov);
2829 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2833 match_flags = match_commutative | match_am | match_16bit_am |
2836 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2838 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2839 addr->mem, am.new_op1, am.new_op2, new_flags,
2840 am.ins_permuted, pnc);
2841 set_am_attributes(new_node, &am);
2843 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2845 new_node = fix_mem_proj(new_node, &am);
2851 * Creates a ia32 Setcc instruction.
2853 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2854 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2857 ir_graph *irg = current_ir_graph;
2858 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2859 ir_node *nomem = new_NoMem();
2860 ir_mode *mode = get_irn_mode(orig_node);
2863 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2864 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2866 /* we might need to conv the result up */
2867 if (get_mode_size_bits(mode) > 8) {
2868 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2869 nomem, new_node, mode_Bu);
2870 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2877 * Create instruction for an unsigned Difference or Zero.
2879 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2880 ir_graph *irg = current_ir_graph;
2881 ir_mode *mode = get_irn_mode(psi);
2882 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2885 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2886 match_mode_neutral | match_am | match_immediate | match_two_users);
2888 block = get_nodes_block(new_node);
2890 if (is_Proj(new_node)) {
2891 sub = get_Proj_pred(new_node);
2892 assert(is_ia32_Sub(sub));
2895 set_irn_mode(sub, mode_T);
2896 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2898 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2900 dbgi = get_irn_dbg_info(psi);
2901 noreg = ia32_new_NoReg_gp(env_cg);
2902 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2903 nomem = new_NoMem();
2904 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2906 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2907 set_ia32_commutative(new_node);
2912 * Transforms a Mux node into CMov.
2914 * @return The transformed node.
2916 static ir_node *gen_Mux(ir_node *node)
2918 dbg_info *dbgi = get_irn_dbg_info(node);
2919 ir_node *block = get_nodes_block(node);
2920 ir_node *new_block = be_transform_node(block);
2921 ir_node *mux_true = get_Mux_true(node);
2922 ir_node *mux_false = get_Mux_false(node);
2923 ir_node *cond = get_Mux_sel(node);
2924 ir_mode *mode = get_irn_mode(node);
2927 assert(get_irn_mode(cond) == mode_b);
2929 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2930 if (mode_is_float(mode)) {
2931 ir_node *cmp = get_Proj_pred(cond);
2932 ir_node *cmp_left = get_Cmp_left(cmp);
2933 ir_node *cmp_right = get_Cmp_right(cmp);
2934 pn_Cmp pnc = get_Proj_proj(cond);
2936 if (ia32_cg_config.use_sse2) {
2937 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2938 if (cmp_left == mux_true && cmp_right == mux_false) {
2939 /* Mux(a <= b, a, b) => MIN */
2940 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2941 match_commutative | match_am | match_two_users);
2942 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2943 /* Mux(a <= b, b, a) => MAX */
2944 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2945 match_commutative | match_am | match_two_users);
2947 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2948 if (cmp_left == mux_true && cmp_right == mux_false) {
2949 /* Mux(a >= b, a, b) => MAX */
2950 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2951 match_commutative | match_am | match_two_users);
2952 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2953 /* Mux(a >= b, b, a) => MIN */
2954 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2955 match_commutative | match_am | match_two_users);
2959 panic("cannot transform floating point Mux");
2965 assert(ia32_mode_needs_gp_reg(mode));
2967 if (is_Proj(cond)) {
2968 ir_node *cmp = get_Proj_pred(cond);
2970 ir_node *cmp_left = get_Cmp_left(cmp);
2971 ir_node *cmp_right = get_Cmp_right(cmp);
2972 pn_Cmp pnc = get_Proj_proj(cond);
2974 /* check for unsigned Doz first */
2975 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2976 is_Const_0(mux_false) && is_Sub(mux_true) &&
2977 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2978 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2979 return create_Doz(node, cmp_left, cmp_right);
2980 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2981 is_Const_0(mux_true) && is_Sub(mux_false) &&
2982 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2983 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2984 return create_Doz(node, cmp_left, cmp_right);
2989 flags = get_flags_node(cond, &pnc);
2991 if (is_Const(mux_true) && is_Const(mux_false)) {
2992 /* both are const, good */
2993 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2994 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2995 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2996 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2998 /* Not that simple. */
3003 new_node = create_CMov(node, cond, flags, pnc);
3011 * Create a conversion from x87 state register to general purpose.
3013 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3014 ir_node *block = be_transform_node(get_nodes_block(node));
3015 ir_node *op = get_Conv_op(node);
3016 ir_node *new_op = be_transform_node(op);
3017 ia32_code_gen_t *cg = env_cg;
3018 ir_graph *irg = current_ir_graph;
3019 dbg_info *dbgi = get_irn_dbg_info(node);
3020 ir_node *noreg = ia32_new_NoReg_gp(cg);
3021 ir_mode *mode = get_irn_mode(node);
3022 ir_node *fist, *load, *mem;
3024 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3025 set_irn_pinned(fist, op_pin_state_floats);
3026 set_ia32_use_frame(fist);
3027 set_ia32_op_type(fist, ia32_AddrModeD);
3029 assert(get_mode_size_bits(mode) <= 32);
3030 /* exception we can only store signed 32 bit integers, so for unsigned
3031 we store a 64bit (signed) integer and load the lower bits */
3032 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3033 set_ia32_ls_mode(fist, mode_Ls);
3035 set_ia32_ls_mode(fist, mode_Is);
3037 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3040 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3042 set_irn_pinned(load, op_pin_state_floats);
3043 set_ia32_use_frame(load);
3044 set_ia32_op_type(load, ia32_AddrModeS);
3045 set_ia32_ls_mode(load, mode_Is);
3046 if(get_ia32_ls_mode(fist) == mode_Ls) {
3047 ia32_attr_t *attr = get_ia32_attr(load);
3048 attr->data.need_64bit_stackent = 1;
3050 ia32_attr_t *attr = get_ia32_attr(load);
3051 attr->data.need_32bit_stackent = 1;
3053 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3055 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3059 * Creates a x87 strict Conv by placing a Store and a Load
3061 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3063 ir_node *block = get_nodes_block(node);
3064 ir_graph *irg = current_ir_graph;
3065 dbg_info *dbgi = get_irn_dbg_info(node);
3066 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3067 ir_node *nomem = new_NoMem();
3068 ir_node *frame = get_irg_frame(irg);
3069 ir_node *store, *load;
3072 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3074 set_ia32_use_frame(store);
3075 set_ia32_op_type(store, ia32_AddrModeD);
3076 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3078 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3080 set_ia32_use_frame(load);
3081 set_ia32_op_type(load, ia32_AddrModeS);
3082 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3084 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3089 * Create a conversion from general purpose to x87 register
3091 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3092 ir_node *src_block = get_nodes_block(node);
3093 ir_node *block = be_transform_node(src_block);
3094 ir_graph *irg = current_ir_graph;
3095 dbg_info *dbgi = get_irn_dbg_info(node);
3096 ir_node *op = get_Conv_op(node);
3097 ir_node *new_op = NULL;
3101 ir_mode *store_mode;
3107 /* fild can use source AM if the operand is a signed 32bit integer */
3108 if (src_mode == mode_Is) {
3109 ia32_address_mode_t am;
3111 match_arguments(&am, src_block, NULL, op, NULL,
3112 match_am | match_try_am);
3113 if (am.op_type == ia32_AddrModeS) {
3114 ia32_address_t *addr = &am.addr;
3116 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3117 addr->index, addr->mem);
3118 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3121 set_am_attributes(fild, &am);
3122 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3124 fix_mem_proj(fild, &am);
3129 if(new_op == NULL) {
3130 new_op = be_transform_node(op);
3133 noreg = ia32_new_NoReg_gp(env_cg);
3134 nomem = new_NoMem();
3135 mode = get_irn_mode(op);
3137 /* first convert to 32 bit signed if necessary */
3138 src_bits = get_mode_size_bits(src_mode);
3139 if (src_bits == 8) {
3140 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3142 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3144 } else if (src_bits < 32) {
3145 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3147 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3151 assert(get_mode_size_bits(mode) == 32);
3154 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3157 set_ia32_use_frame(store);
3158 set_ia32_op_type(store, ia32_AddrModeD);
3159 set_ia32_ls_mode(store, mode_Iu);
3161 /* exception for 32bit unsigned, do a 64bit spill+load */
3162 if(!mode_is_signed(mode)) {
3165 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3167 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3168 get_irg_frame(irg), noreg, nomem,
3171 set_ia32_use_frame(zero_store);
3172 set_ia32_op_type(zero_store, ia32_AddrModeD);
3173 add_ia32_am_offs_int(zero_store, 4);
3174 set_ia32_ls_mode(zero_store, mode_Iu);
3179 store = new_rd_Sync(dbgi, irg, block, 2, in);
3180 store_mode = mode_Ls;
3182 store_mode = mode_Is;
3186 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3188 set_ia32_use_frame(fild);
3189 set_ia32_op_type(fild, ia32_AddrModeS);
3190 set_ia32_ls_mode(fild, store_mode);
3192 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3198 * Create a conversion from one integer mode into another one
3200 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3201 dbg_info *dbgi, ir_node *block, ir_node *op,
3204 ir_graph *irg = current_ir_graph;
3205 int src_bits = get_mode_size_bits(src_mode);
3206 int tgt_bits = get_mode_size_bits(tgt_mode);
3207 ir_node *new_block = be_transform_node(block);
3209 ir_mode *smaller_mode;
3211 ia32_address_mode_t am;
3212 ia32_address_t *addr = &am.addr;
3215 if (src_bits < tgt_bits) {
3216 smaller_mode = src_mode;
3217 smaller_bits = src_bits;
3219 smaller_mode = tgt_mode;
3220 smaller_bits = tgt_bits;
3223 #ifdef DEBUG_libfirm
3225 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3230 match_arguments(&am, block, NULL, op, NULL,
3231 match_8bit | match_16bit |
3232 match_am | match_8bit_am | match_16bit_am);
3233 if (smaller_bits == 8) {
3234 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3235 addr->index, addr->mem, am.new_op2,
3238 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3239 addr->index, addr->mem, am.new_op2,
3242 set_am_attributes(new_node, &am);
3243 /* match_arguments assume that out-mode = in-mode, this isn't true here
3245 set_ia32_ls_mode(new_node, smaller_mode);
3246 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3247 new_node = fix_mem_proj(new_node, &am);
3252 * Transforms a Conv node.
3254 * @return The created ia32 Conv node
3256 static ir_node *gen_Conv(ir_node *node) {
3257 ir_node *block = get_nodes_block(node);
3258 ir_node *new_block = be_transform_node(block);
3259 ir_node *op = get_Conv_op(node);
3260 ir_node *new_op = NULL;
3261 ir_graph *irg = current_ir_graph;
3262 dbg_info *dbgi = get_irn_dbg_info(node);
3263 ir_mode *src_mode = get_irn_mode(op);
3264 ir_mode *tgt_mode = get_irn_mode(node);
3265 int src_bits = get_mode_size_bits(src_mode);
3266 int tgt_bits = get_mode_size_bits(tgt_mode);
3267 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3268 ir_node *nomem = new_rd_NoMem(irg);
3269 ir_node *res = NULL;
3271 if (src_mode == mode_b) {
3272 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3273 /* nothing to do, we already model bools as 0/1 ints */
3274 return be_transform_node(op);
3277 if (src_mode == tgt_mode) {
3278 if (get_Conv_strict(node)) {
3279 if (ia32_cg_config.use_sse2) {
3280 /* when we are in SSE mode, we can kill all strict no-op conversion */
3281 return be_transform_node(op);
3284 /* this should be optimized already, but who knows... */
3285 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3286 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3287 return be_transform_node(op);
3291 if (mode_is_float(src_mode)) {
3292 new_op = be_transform_node(op);
3293 /* we convert from float ... */
3294 if (mode_is_float(tgt_mode)) {
3295 if(src_mode == mode_E && tgt_mode == mode_D
3296 && !get_Conv_strict(node)) {
3297 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3302 if (ia32_cg_config.use_sse2) {
3303 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3304 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3306 set_ia32_ls_mode(res, tgt_mode);
3308 if(get_Conv_strict(node)) {
3309 res = gen_x87_strict_conv(tgt_mode, new_op);
3310 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3313 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3318 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3319 if (ia32_cg_config.use_sse2) {
3320 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3322 set_ia32_ls_mode(res, src_mode);
3324 return gen_x87_fp_to_gp(node);
3328 /* we convert from int ... */
3329 if (mode_is_float(tgt_mode)) {
3331 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3332 if (ia32_cg_config.use_sse2) {
3333 new_op = be_transform_node(op);
3334 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3336 set_ia32_ls_mode(res, tgt_mode);
3338 res = gen_x87_gp_to_fp(node, src_mode);
3339 if(get_Conv_strict(node)) {
3340 /* The strict-Conv is only necessary, if the int mode has more bits
3341 * than the float mantissa */
3342 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3343 size_t float_mantissa;
3344 /* FIXME There is no way to get the mantissa size of a mode */
3345 switch (get_mode_size_bits(tgt_mode)) {
3346 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3347 case 64: float_mantissa = 52 + 1; break;
3348 case 80: float_mantissa = 64 + 1; break;
3349 default: float_mantissa = 0; break;
3351 if (float_mantissa < int_mantissa) {
3352 res = gen_x87_strict_conv(tgt_mode, res);
3353 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3358 } else if(tgt_mode == mode_b) {
3359 /* mode_b lowering already took care that we only have 0/1 values */
3360 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3361 src_mode, tgt_mode));
3362 return be_transform_node(op);
3365 if (src_bits == tgt_bits) {
3366 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3367 src_mode, tgt_mode));
3368 return be_transform_node(op);
3371 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3379 static ir_node *create_immediate_or_transform(ir_node *node,
3380 char immediate_constraint_type)
3382 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3383 if (new_node == NULL) {
3384 new_node = be_transform_node(node);
3390 * Transforms a FrameAddr into an ia32 Add.
3392 static ir_node *gen_be_FrameAddr(ir_node *node) {
3393 ir_node *block = be_transform_node(get_nodes_block(node));
3394 ir_node *op = be_get_FrameAddr_frame(node);
3395 ir_node *new_op = be_transform_node(op);
3396 ir_graph *irg = current_ir_graph;
3397 dbg_info *dbgi = get_irn_dbg_info(node);
3398 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3401 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3402 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3403 set_ia32_use_frame(new_node);
3405 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3411 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3413 static ir_node *gen_be_Return(ir_node *node) {
3414 ir_graph *irg = current_ir_graph;
3415 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3416 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3417 ir_entity *ent = get_irg_entity(irg);
3418 ir_type *tp = get_entity_type(ent);
3423 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3424 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3427 int pn_ret_val, pn_ret_mem, arity, i;
3429 assert(ret_val != NULL);
3430 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3431 return be_duplicate_node(node);
3434 res_type = get_method_res_type(tp, 0);
3436 if (! is_Primitive_type(res_type)) {
3437 return be_duplicate_node(node);
3440 mode = get_type_mode(res_type);
3441 if (! mode_is_float(mode)) {
3442 return be_duplicate_node(node);
3445 assert(get_method_n_ress(tp) == 1);
3447 pn_ret_val = get_Proj_proj(ret_val);
3448 pn_ret_mem = get_Proj_proj(ret_mem);
3450 /* get the Barrier */
3451 barrier = get_Proj_pred(ret_val);
3453 /* get result input of the Barrier */
3454 ret_val = get_irn_n(barrier, pn_ret_val);
3455 new_ret_val = be_transform_node(ret_val);
3457 /* get memory input of the Barrier */
3458 ret_mem = get_irn_n(barrier, pn_ret_mem);
3459 new_ret_mem = be_transform_node(ret_mem);
3461 frame = get_irg_frame(irg);
3463 dbgi = get_irn_dbg_info(barrier);
3464 block = be_transform_node(get_nodes_block(barrier));
3466 noreg = ia32_new_NoReg_gp(env_cg);
3468 /* store xmm0 onto stack */
3469 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3470 new_ret_mem, new_ret_val);
3471 set_ia32_ls_mode(sse_store, mode);
3472 set_ia32_op_type(sse_store, ia32_AddrModeD);
3473 set_ia32_use_frame(sse_store);
3475 /* load into x87 register */
3476 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3477 set_ia32_op_type(fld, ia32_AddrModeS);
3478 set_ia32_use_frame(fld);
3480 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3481 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3483 /* create a new barrier */
3484 arity = get_irn_arity(barrier);
3485 in = alloca(arity * sizeof(in[0]));
3486 for (i = 0; i < arity; ++i) {
3489 if (i == pn_ret_val) {
3491 } else if (i == pn_ret_mem) {
3494 ir_node *in = get_irn_n(barrier, i);
3495 new_in = be_transform_node(in);
3500 new_barrier = new_ir_node(dbgi, irg, block,
3501 get_irn_op(barrier), get_irn_mode(barrier),
3503 copy_node_attr(barrier, new_barrier);
3504 be_duplicate_deps(barrier, new_barrier);
3505 be_set_transformed_node(barrier, new_barrier);
3506 mark_irn_visited(barrier);
3508 /* transform normally */
3509 return be_duplicate_node(node);
3513 * Transform a be_AddSP into an ia32_SubSP.
3515 static ir_node *gen_be_AddSP(ir_node *node)
3517 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3518 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3520 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
3524 * Transform a be_SubSP into an ia32_AddSP
3526 static ir_node *gen_be_SubSP(ir_node *node)
3528 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3529 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3531 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
3535 * Change some phi modes
3537 static ir_node *gen_Phi(ir_node *node) {
3538 ir_node *block = be_transform_node(get_nodes_block(node));
3539 ir_graph *irg = current_ir_graph;
3540 dbg_info *dbgi = get_irn_dbg_info(node);
3541 ir_mode *mode = get_irn_mode(node);
3544 if(ia32_mode_needs_gp_reg(mode)) {
3545 /* we shouldn't have any 64bit stuff around anymore */
3546 assert(get_mode_size_bits(mode) <= 32);
3547 /* all integer operations are on 32bit registers now */
3549 } else if(mode_is_float(mode)) {
3550 if (ia32_cg_config.use_sse2) {
3557 /* phi nodes allow loops, so we use the old arguments for now
3558 * and fix this later */
3559 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3560 get_irn_in(node) + 1);
3561 copy_node_attr(node, phi);
3562 be_duplicate_deps(node, phi);
3564 be_set_transformed_node(node, phi);
3565 be_enqueue_preds(node);
3573 static ir_node *gen_IJmp(ir_node *node)
3575 ir_node *block = get_nodes_block(node);
3576 ir_node *new_block = be_transform_node(block);
3577 dbg_info *dbgi = get_irn_dbg_info(node);
3578 ir_node *op = get_IJmp_target(node);
3580 ia32_address_mode_t am;
3581 ia32_address_t *addr = &am.addr;
3583 assert(get_irn_mode(op) == mode_P);
3585 match_arguments(&am, block, NULL, op, NULL,
3586 match_am | match_8bit_am | match_16bit_am |
3587 match_immediate | match_8bit | match_16bit);
3589 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3590 addr->base, addr->index, addr->mem,
3592 set_am_attributes(new_node, &am);
3593 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3595 new_node = fix_mem_proj(new_node, &am);
3601 * Transform a Bound node.
3603 static ir_node *gen_Bound(ir_node *node)
3606 ir_node *lower = get_Bound_lower(node);
3607 dbg_info *dbgi = get_irn_dbg_info(node);
3609 if (is_Const_0(lower)) {
3610 /* typical case for Java */
3611 ir_node *sub, *res, *flags, *block;
3612 ir_graph *irg = current_ir_graph;
3614 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3615 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3617 block = get_nodes_block(res);
3618 if (! is_Proj(res)) {
3620 set_irn_mode(sub, mode_T);
3621 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3623 sub = get_Proj_pred(res);
3625 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3626 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3627 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3629 panic("generic Bound not supported in ia32 Backend");
3635 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3638 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3639 ir_node *val, ir_node *mem);
3642 * Transforms a lowered Load into a "real" one.
3644 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
3646 ir_node *block = be_transform_node(get_nodes_block(node));
3647 ir_node *ptr = get_irn_n(node, 0);
3648 ir_node *new_ptr = be_transform_node(ptr);
3649 ir_node *mem = get_irn_n(node, 1);
3650 ir_node *new_mem = be_transform_node(mem);
3651 ir_graph *irg = current_ir_graph;
3652 dbg_info *dbgi = get_irn_dbg_info(node);
3653 ir_mode *mode = get_ia32_ls_mode(node);
3654 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3657 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
3659 set_ia32_op_type(new_op, ia32_AddrModeS);
3660 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
3661 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
3662 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
3663 if (is_ia32_am_sc_sign(node))
3664 set_ia32_am_sc_sign(new_op);
3665 set_ia32_ls_mode(new_op, mode);
3666 if (is_ia32_use_frame(node)) {
3667 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3668 set_ia32_use_frame(new_op);
3671 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3677 * Transforms a lowered Store into a "real" one.
3679 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
3681 ir_node *block = be_transform_node(get_nodes_block(node));
3682 ir_node *ptr = get_irn_n(node, 0);
3683 ir_node *new_ptr = be_transform_node(ptr);
3684 ir_node *val = get_irn_n(node, 1);
3685 ir_node *new_val = be_transform_node(val);
3686 ir_node *mem = get_irn_n(node, 2);
3687 ir_node *new_mem = be_transform_node(mem);
3688 ir_graph *irg = current_ir_graph;
3689 dbg_info *dbgi = get_irn_dbg_info(node);
3690 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3691 ir_mode *mode = get_ia32_ls_mode(node);
3695 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
3697 am_offs = get_ia32_am_offs_int(node);
3698 add_ia32_am_offs_int(new_op, am_offs);
3700 set_ia32_op_type(new_op, ia32_AddrModeD);
3701 set_ia32_ls_mode(new_op, mode);
3702 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3703 set_ia32_use_frame(new_op);
3705 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3710 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3712 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3713 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3715 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3716 match_immediate | match_mode_neutral);
3719 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3721 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3722 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3723 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3727 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3729 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3730 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3731 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3735 static ir_node *gen_ia32_l_Add(ir_node *node) {
3736 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3737 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3738 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3739 match_commutative | match_am | match_immediate |
3740 match_mode_neutral);
3742 if(is_Proj(lowered)) {
3743 lowered = get_Proj_pred(lowered);
3745 assert(is_ia32_Add(lowered));
3746 set_irn_mode(lowered, mode_T);
3752 static ir_node *gen_ia32_l_Adc(ir_node *node)
3754 return gen_binop_flags(node, new_rd_ia32_Adc,
3755 match_commutative | match_am | match_immediate |
3756 match_mode_neutral);
3760 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
3762 * @param node The node to transform
3763 * @return the created ia32 vfild node
3765 static ir_node *gen_ia32_l_vfild(ir_node *node) {
3766 return gen_lowered_Load(node, new_rd_ia32_vfild);
3770 * Transforms an ia32_l_Load into a "real" ia32_Load node
3772 * @param node The node to transform
3773 * @return the created ia32 Load node
3775 static ir_node *gen_ia32_l_Load(ir_node *node) {
3776 return gen_lowered_Load(node, new_rd_ia32_Load);
3780 * Transforms an ia32_l_Store into a "real" ia32_Store node
3782 * @param node The node to transform
3783 * @return the created ia32 Store node
3785 static ir_node *gen_ia32_l_Store(ir_node *node) {
3786 return gen_lowered_Store(node, new_rd_ia32_Store);
3790 * Transforms a l_vfist into a "real" vfist node.
3792 * @param node The node to transform
3793 * @return the created ia32 vfist node
3795 static ir_node *gen_ia32_l_vfist(ir_node *node) {
3796 ir_node *block = be_transform_node(get_nodes_block(node));
3797 ir_node *ptr = get_irn_n(node, 0);
3798 ir_node *new_ptr = be_transform_node(ptr);
3799 ir_node *val = get_irn_n(node, 1);
3800 ir_node *new_val = be_transform_node(val);
3801 ir_node *mem = get_irn_n(node, 2);
3802 ir_node *new_mem = be_transform_node(mem);
3803 ir_graph *irg = current_ir_graph;
3804 dbg_info *dbgi = get_irn_dbg_info(node);
3805 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3806 ir_mode *mode = get_ia32_ls_mode(node);
3807 ir_node *memres, *fist;
3810 memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
3811 am_offs = get_ia32_am_offs_int(node);
3812 add_ia32_am_offs_int(fist, am_offs);
3814 set_ia32_op_type(fist, ia32_AddrModeD);
3815 set_ia32_ls_mode(fist, mode);
3816 set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
3817 set_ia32_use_frame(fist);
3819 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3825 * Transforms a l_MulS into a "real" MulS node.
3827 * @return the created ia32 Mul node
3829 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3830 ir_node *left = get_binop_left(node);
3831 ir_node *right = get_binop_right(node);
3833 return gen_binop(node, left, right, new_rd_ia32_Mul,
3834 match_commutative | match_am | match_mode_neutral);
3838 * Transforms a l_IMulS into a "real" IMul1OPS node.
3840 * @return the created ia32 IMul1OP node
3842 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3843 ir_node *left = get_binop_left(node);
3844 ir_node *right = get_binop_right(node);
3846 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3847 match_commutative | match_am | match_mode_neutral);
3850 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3851 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3852 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3853 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3854 match_am | match_immediate | match_mode_neutral);
3856 if(is_Proj(lowered)) {
3857 lowered = get_Proj_pred(lowered);
3859 assert(is_ia32_Sub(lowered));
3860 set_irn_mode(lowered, mode_T);
3866 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3867 return gen_binop_flags(node, new_rd_ia32_Sbb,
3868 match_am | match_immediate | match_mode_neutral);
3872 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3873 * op1 - target to be shifted
3874 * op2 - contains bits to be shifted into target
3876 * Only op3 can be an immediate.
3878 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3879 ir_node *low, ir_node *count)
3881 ir_node *block = get_nodes_block(node);
3882 ir_node *new_block = be_transform_node(block);
3883 ir_graph *irg = current_ir_graph;
3884 dbg_info *dbgi = get_irn_dbg_info(node);
3885 ir_node *new_high = be_transform_node(high);
3886 ir_node *new_low = be_transform_node(low);
3890 /* the shift amount can be any mode that is bigger than 5 bits, since all
3891 * other bits are ignored anyway */
3892 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
3893 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3894 count = get_Conv_op(count);
3896 new_count = create_immediate_or_transform(count, 0);
3898 if (is_ia32_l_ShlD(node)) {
3899 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3902 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3905 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3910 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3912 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3913 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3914 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3915 return gen_lowered_64bit_shifts(node, high, low, count);
3918 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3920 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3921 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3922 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3923 return gen_lowered_64bit_shifts(node, high, low, count);
3926 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3927 ir_node *src_block = get_nodes_block(node);
3928 ir_node *block = be_transform_node(src_block);
3929 ir_graph *irg = current_ir_graph;
3930 dbg_info *dbgi = get_irn_dbg_info(node);
3931 ir_node *frame = get_irg_frame(irg);
3932 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3933 ir_node *nomem = new_NoMem();
3934 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3935 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3936 ir_node *new_val_low = be_transform_node(val_low);
3937 ir_node *new_val_high = be_transform_node(val_high);
3942 ir_node *store_high;
3944 if(!mode_is_signed(get_irn_mode(val_high))) {
3945 panic("unsigned long long -> float not supported yet (%+F)", node);
3949 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3951 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3953 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3954 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3956 set_ia32_use_frame(store_low);
3957 set_ia32_use_frame(store_high);
3958 set_ia32_op_type(store_low, ia32_AddrModeD);
3959 set_ia32_op_type(store_high, ia32_AddrModeD);
3960 set_ia32_ls_mode(store_low, mode_Iu);
3961 set_ia32_ls_mode(store_high, mode_Is);
3962 add_ia32_am_offs_int(store_high, 4);
3966 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3969 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3971 set_ia32_use_frame(fild);
3972 set_ia32_op_type(fild, ia32_AddrModeS);
3973 set_ia32_ls_mode(fild, mode_Ls);
3975 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3977 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3980 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3981 ir_node *src_block = get_nodes_block(node);
3982 ir_node *block = be_transform_node(src_block);
3983 ir_graph *irg = current_ir_graph;
3984 dbg_info *dbgi = get_irn_dbg_info(node);
3985 ir_node *frame = get_irg_frame(irg);
3986 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3987 ir_node *nomem = new_NoMem();
3988 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3989 ir_node *new_val = be_transform_node(val);
3990 ir_node *fist, *mem;
3992 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3993 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3994 set_ia32_use_frame(fist);
3995 set_ia32_op_type(fist, ia32_AddrModeD);
3996 set_ia32_ls_mode(fist, mode_Ls);
4002 * the BAD transformer.
4004 static ir_node *bad_transform(ir_node *node) {
4005 panic("No transform function for %+F available.\n", node);
4009 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4010 ir_graph *irg = current_ir_graph;
4011 ir_node *block = be_transform_node(get_nodes_block(node));
4012 ir_node *pred = get_Proj_pred(node);
4013 ir_node *new_pred = be_transform_node(pred);
4014 ir_node *frame = get_irg_frame(irg);
4015 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4016 dbg_info *dbgi = get_irn_dbg_info(node);
4017 long pn = get_Proj_proj(node);
4022 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4023 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4024 set_ia32_use_frame(load);
4025 set_ia32_op_type(load, ia32_AddrModeS);
4026 set_ia32_ls_mode(load, mode_Iu);
4027 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4028 * 32 bit from it with this particular load */
4029 attr = get_ia32_attr(load);
4030 attr->data.need_64bit_stackent = 1;
4032 if (pn == pn_ia32_l_FloattoLL_res_high) {
4033 add_ia32_am_offs_int(load, 4);
4035 assert(pn == pn_ia32_l_FloattoLL_res_low);
4038 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4044 * Transform the Projs of an AddSP.
4046 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4047 ir_node *block = be_transform_node(get_nodes_block(node));
4048 ir_node *pred = get_Proj_pred(node);
4049 ir_node *new_pred = be_transform_node(pred);
4050 ir_graph *irg = current_ir_graph;
4051 dbg_info *dbgi = get_irn_dbg_info(node);
4052 long proj = get_Proj_proj(node);
4054 if (proj == pn_be_AddSP_sp) {
4055 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4056 pn_ia32_SubSP_stack);
4057 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4059 } else if(proj == pn_be_AddSP_res) {
4060 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4061 pn_ia32_SubSP_addr);
4062 } else if (proj == pn_be_AddSP_M) {
4063 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4067 return new_rd_Unknown(irg, get_irn_mode(node));
4071 * Transform the Projs of a SubSP.
4073 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4074 ir_node *block = be_transform_node(get_nodes_block(node));
4075 ir_node *pred = get_Proj_pred(node);
4076 ir_node *new_pred = be_transform_node(pred);
4077 ir_graph *irg = current_ir_graph;
4078 dbg_info *dbgi = get_irn_dbg_info(node);
4079 long proj = get_Proj_proj(node);
4081 if (proj == pn_be_SubSP_sp) {
4082 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4083 pn_ia32_AddSP_stack);
4084 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4086 } else if (proj == pn_be_SubSP_M) {
4087 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4091 return new_rd_Unknown(irg, get_irn_mode(node));
4095 * Transform and renumber the Projs from a Load.
4097 static ir_node *gen_Proj_Load(ir_node *node) {
4099 ir_node *block = be_transform_node(get_nodes_block(node));
4100 ir_node *pred = get_Proj_pred(node);
4101 ir_graph *irg = current_ir_graph;
4102 dbg_info *dbgi = get_irn_dbg_info(node);
4103 long proj = get_Proj_proj(node);
4105 /* loads might be part of source address mode matches, so we don't
4106 * transform the ProjMs yet (with the exception of loads whose result is
4109 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4112 /* this is needed, because sometimes we have loops that are only
4113 reachable through the ProjM */
4114 be_enqueue_preds(node);
4115 /* do it in 2 steps, to silence firm verifier */
4116 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4117 set_Proj_proj(res, pn_ia32_mem);
4121 /* renumber the proj */
4122 new_pred = be_transform_node(pred);
4123 if (is_ia32_Load(new_pred)) {
4126 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4128 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4129 case pn_Load_X_regular:
4130 return new_rd_Jmp(dbgi, irg, block);
4131 case pn_Load_X_except:
4132 /* This Load might raise an exception. Mark it. */
4133 set_ia32_exc_label(new_pred, 1);
4134 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4138 } else if (is_ia32_Conv_I2I(new_pred) ||
4139 is_ia32_Conv_I2I8Bit(new_pred)) {
4140 set_irn_mode(new_pred, mode_T);
4141 if (proj == pn_Load_res) {
4142 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4143 } else if (proj == pn_Load_M) {
4144 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4146 } else if (is_ia32_xLoad(new_pred)) {
4149 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4151 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4152 case pn_Load_X_regular:
4153 return new_rd_Jmp(dbgi, irg, block);
4154 case pn_Load_X_except:
4155 /* This Load might raise an exception. Mark it. */
4156 set_ia32_exc_label(new_pred, 1);
4157 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4161 } else if (is_ia32_vfld(new_pred)) {
4164 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4166 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4167 case pn_Load_X_regular:
4168 return new_rd_Jmp(dbgi, irg, block);
4169 case pn_Load_X_except:
4170 /* This Load might raise an exception. Mark it. */
4171 set_ia32_exc_label(new_pred, 1);
4172 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4177 /* can happen for ProJMs when source address mode happened for the
4180 /* however it should not be the result proj, as that would mean the
4181 load had multiple users and should not have been used for
4183 if (proj != pn_Load_M) {
4184 panic("internal error: transformed node not a Load");
4186 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4190 return new_rd_Unknown(irg, get_irn_mode(node));
4194 * Transform and renumber the Projs from a DivMod like instruction.
4196 static ir_node *gen_Proj_DivMod(ir_node *node) {
4197 ir_node *block = be_transform_node(get_nodes_block(node));
4198 ir_node *pred = get_Proj_pred(node);
4199 ir_node *new_pred = be_transform_node(pred);
4200 ir_graph *irg = current_ir_graph;
4201 dbg_info *dbgi = get_irn_dbg_info(node);
4202 ir_mode *mode = get_irn_mode(node);
4203 long proj = get_Proj_proj(node);
4205 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4207 switch (get_irn_opcode(pred)) {
4211 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4213 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4214 case pn_Div_X_regular:
4215 return new_rd_Jmp(dbgi, irg, block);
4216 case pn_Div_X_except:
4217 set_ia32_exc_label(new_pred, 1);
4218 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4226 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4228 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4229 case pn_Mod_X_except:
4230 set_ia32_exc_label(new_pred, 1);
4231 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4239 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4240 case pn_DivMod_res_div:
4241 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4242 case pn_DivMod_res_mod:
4243 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4244 case pn_DivMod_X_regular:
4245 return new_rd_Jmp(dbgi, irg, block);
4246 case pn_DivMod_X_except:
4247 set_ia32_exc_label(new_pred, 1);
4248 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4258 return new_rd_Unknown(irg, mode);
4262 * Transform and renumber the Projs from a CopyB.
4264 static ir_node *gen_Proj_CopyB(ir_node *node) {
4265 ir_node *block = be_transform_node(get_nodes_block(node));
4266 ir_node *pred = get_Proj_pred(node);
4267 ir_node *new_pred = be_transform_node(pred);
4268 ir_graph *irg = current_ir_graph;
4269 dbg_info *dbgi = get_irn_dbg_info(node);
4270 ir_mode *mode = get_irn_mode(node);
4271 long proj = get_Proj_proj(node);
4274 case pn_CopyB_M_regular:
4275 if (is_ia32_CopyB_i(new_pred)) {
4276 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4277 } else if (is_ia32_CopyB(new_pred)) {
4278 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4286 return new_rd_Unknown(irg, mode);
4290 * Transform and renumber the Projs from a Quot.
4292 static ir_node *gen_Proj_Quot(ir_node *node) {
4293 ir_node *block = be_transform_node(get_nodes_block(node));
4294 ir_node *pred = get_Proj_pred(node);
4295 ir_node *new_pred = be_transform_node(pred);
4296 ir_graph *irg = current_ir_graph;
4297 dbg_info *dbgi = get_irn_dbg_info(node);
4298 ir_mode *mode = get_irn_mode(node);
4299 long proj = get_Proj_proj(node);
4303 if (is_ia32_xDiv(new_pred)) {
4304 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4305 } else if (is_ia32_vfdiv(new_pred)) {
4306 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4310 if (is_ia32_xDiv(new_pred)) {
4311 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4312 } else if (is_ia32_vfdiv(new_pred)) {
4313 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4316 case pn_Quot_X_regular:
4317 case pn_Quot_X_except:
4323 return new_rd_Unknown(irg, mode);
4327 * Transform the Thread Local Storage Proj.
4329 static ir_node *gen_Proj_tls(ir_node *node) {
4330 ir_node *block = be_transform_node(get_nodes_block(node));
4331 ir_graph *irg = current_ir_graph;
4332 dbg_info *dbgi = NULL;
4333 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4338 static ir_node *gen_be_Call(ir_node *node) {
4339 ir_node *res = be_duplicate_node(node);
4340 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4345 static ir_node *gen_be_IncSP(ir_node *node) {
4346 ir_node *res = be_duplicate_node(node);
4347 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4353 * Transform the Projs from a be_Call.
4355 static ir_node *gen_Proj_be_Call(ir_node *node) {
4356 ir_node *block = be_transform_node(get_nodes_block(node));
4357 ir_node *call = get_Proj_pred(node);
4358 ir_node *new_call = be_transform_node(call);
4359 ir_graph *irg = current_ir_graph;
4360 dbg_info *dbgi = get_irn_dbg_info(node);
4361 ir_type *method_type = be_Call_get_type(call);
4362 int n_res = get_method_n_ress(method_type);
4363 long proj = get_Proj_proj(node);
4364 ir_mode *mode = get_irn_mode(node);
4366 const arch_register_class_t *cls;
4368 /* The following is kinda tricky: If we're using SSE, then we have to
4369 * move the result value of the call in floating point registers to an
4370 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4371 * after the call, we have to make sure to correctly make the
4372 * MemProj and the result Proj use these 2 nodes
4374 if (proj == pn_be_Call_M_regular) {
4375 // get new node for result, are we doing the sse load/store hack?
4376 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4377 ir_node *call_res_new;
4378 ir_node *call_res_pred = NULL;
4380 if (call_res != NULL) {
4381 call_res_new = be_transform_node(call_res);
4382 call_res_pred = get_Proj_pred(call_res_new);
4385 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4386 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4387 pn_be_Call_M_regular);
4389 assert(is_ia32_xLoad(call_res_pred));
4390 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4394 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4395 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4397 ir_node *frame = get_irg_frame(irg);
4398 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4400 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4403 /* in case there is no memory output: create one to serialize the copy
4405 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4406 pn_be_Call_M_regular);
4407 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4408 pn_be_Call_first_res);
4410 /* store st(0) onto stack */
4411 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4413 set_ia32_op_type(fstp, ia32_AddrModeD);
4414 set_ia32_use_frame(fstp);
4416 /* load into SSE register */
4417 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4419 set_ia32_op_type(sse_load, ia32_AddrModeS);
4420 set_ia32_use_frame(sse_load);
4422 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4428 /* transform call modes */
4429 if (mode_is_data(mode)) {
4430 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4434 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4438 * Transform the Projs from a Cmp.
4440 static ir_node *gen_Proj_Cmp(ir_node *node)
4442 /* this probably means not all mode_b nodes were lowered... */
4443 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4448 * Transform the Projs from a Bound.
4450 static ir_node *gen_Proj_Bound(ir_node *node)
4452 ir_node *new_node, *block;
4453 ir_node *pred = get_Proj_pred(node);
4455 switch (get_Proj_proj(node)) {
4457 return be_transform_node(get_Bound_mem(pred));
4458 case pn_Bound_X_regular:
4459 new_node = be_transform_node(pred);
4460 block = get_nodes_block(new_node);
4461 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4462 case pn_Bound_X_except:
4463 new_node = be_transform_node(pred);
4464 block = get_nodes_block(new_node);
4465 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4467 return be_transform_node(get_Bound_index(pred));
4469 panic("unsupported Proj from Bound");
4473 static ir_node *gen_Proj_ASM(ir_node *node)
4479 if (get_irn_mode(node) != mode_M)
4480 return be_duplicate_node(node);
4482 pred = get_Proj_pred(node);
4483 new_pred = be_transform_node(pred);
4484 block = get_nodes_block(new_pred);
4485 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4486 get_ia32_n_res(new_pred) + 1);
4490 * Transform and potentially renumber Proj nodes.
4492 static ir_node *gen_Proj(ir_node *node) {
4493 ir_node *pred = get_Proj_pred(node);
4496 switch (get_irn_opcode(pred)) {
4498 proj = get_Proj_proj(node);
4499 if (proj == pn_Store_M) {
4500 return be_transform_node(pred);
4503 return new_r_Bad(current_ir_graph);
4506 return gen_Proj_Load(node);
4508 return gen_Proj_ASM(node);
4512 return gen_Proj_DivMod(node);
4514 return gen_Proj_CopyB(node);
4516 return gen_Proj_Quot(node);
4518 return gen_Proj_be_SubSP(node);
4520 return gen_Proj_be_AddSP(node);
4522 return gen_Proj_be_Call(node);
4524 return gen_Proj_Cmp(node);
4526 return gen_Proj_Bound(node);
4528 proj = get_Proj_proj(node);
4529 if (proj == pn_Start_X_initial_exec) {
4530 ir_node *block = get_nodes_block(pred);
4531 dbg_info *dbgi = get_irn_dbg_info(node);
4534 /* we exchange the ProjX with a jump */
4535 block = be_transform_node(block);
4536 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
4539 if (node == be_get_old_anchor(anchor_tls)) {
4540 return gen_Proj_tls(node);
4545 if (is_ia32_l_FloattoLL(pred)) {
4546 return gen_Proj_l_FloattoLL(node);
4548 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4552 ir_mode *mode = get_irn_mode(node);
4553 if (ia32_mode_needs_gp_reg(mode)) {
4554 ir_node *new_pred = be_transform_node(pred);
4555 ir_node *block = be_transform_node(get_nodes_block(node));
4556 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4557 mode_Iu, get_Proj_proj(node));
4558 #ifdef DEBUG_libfirm
4559 new_proj->node_nr = node->node_nr;
4565 return be_duplicate_node(node);
4569 * Enters all transform functions into the generic pointer
4571 static void register_transformers(void)
4575 /* first clear the generic function pointer for all ops */
4576 clear_irp_opcodes_generic_func();
4578 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4579 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4617 /* transform ops from intrinsic lowering */
4633 GEN(ia32_l_LLtoFloat);
4634 GEN(ia32_l_FloattoLL);
4640 /* we should never see these nodes */
4655 /* handle generic backend nodes */
4664 op_Mulh = get_op_Mulh();
4673 * Pre-transform all unknown and noreg nodes.
4675 static void ia32_pretransform_node(void *arch_cg) {
4676 ia32_code_gen_t *cg = arch_cg;
4678 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4679 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4680 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4681 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4682 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4683 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4688 * Walker, checks if all ia32 nodes producing more than one result have
4689 * its Projs, otherwise creates new Projs and keep them using a be_Keep node.
4691 static void add_missing_keep_walker(ir_node *node, void *data)
4694 unsigned found_projs = 0;
4695 const ir_edge_t *edge;
4696 ir_mode *mode = get_irn_mode(node);
4701 if(!is_ia32_irn(node))
4704 n_outs = get_ia32_n_res(node);
4707 if(is_ia32_SwitchJmp(node))
4710 assert(n_outs < (int) sizeof(unsigned) * 8);
4711 foreach_out_edge(node, edge) {
4712 ir_node *proj = get_edge_src_irn(edge);
4713 int pn = get_Proj_proj(proj);
4715 if (get_irn_mode(proj) == mode_M)
4718 assert(pn < n_outs);
4719 found_projs |= 1 << pn;
4723 /* are keeps missing? */
4725 for(i = 0; i < n_outs; ++i) {
4728 const arch_register_req_t *req;
4729 const arch_register_class_t *cls;
4731 if(found_projs & (1 << i)) {
4735 req = get_ia32_out_req(node, i);
4740 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4744 block = get_nodes_block(node);
4745 in[0] = new_r_Proj(current_ir_graph, block, node,
4746 arch_register_class_mode(cls), i);
4747 if(last_keep != NULL) {
4748 be_Keep_add_node(last_keep, cls, in[0]);
4750 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4751 if(sched_is_scheduled(node)) {
4752 sched_add_after(node, last_keep);
4759 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4762 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4764 ir_graph *irg = be_get_birg_irg(cg->birg);
4765 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4768 /* do the transformation */
4769 void ia32_transform_graph(ia32_code_gen_t *cg) {
4771 ir_graph *irg = cg->irg;
4773 register_transformers();
4775 initial_fpcw = NULL;
4777 BE_TIMER_PUSH(t_heights);
4778 heights = heights_new(irg);
4779 BE_TIMER_POP(t_heights);
4780 ia32_calculate_non_address_mode_nodes(cg->birg);
4782 /* the transform phase is not safe for CSE (yet) because several nodes get
4783 * attributes set after their creation */
4784 cse_last = get_opt_cse();
4787 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4789 set_opt_cse(cse_last);
4791 ia32_free_non_address_mode_nodes();
4792 heights_free(heights);
4796 void ia32_init_transform(void)
4798 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");