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;
99 extern ir_op *get_op_Mulh(void);
101 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
102 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
103 ir_node *op1, ir_node *op2);
105 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
106 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
107 ir_node *op1, ir_node *op2, ir_node *flags);
109 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
110 ir_node *block, ir_node *op1, ir_node *op2);
112 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
113 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
116 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
117 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
119 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
120 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
121 ir_node *op1, ir_node *op2, ir_node *fpcw);
123 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
124 ir_node *block, ir_node *op);
126 static ir_node *create_immediate_or_transform(ir_node *node,
127 char immediate_constraint_type);
129 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
130 dbg_info *dbgi, ir_node *block,
131 ir_node *op, ir_node *orig_node);
133 /** Return non-zero is a node represents the 0 constant. */
134 static int is_Const_0(ir_node *node) {
135 return is_Const(node) && is_Const_null(node);
138 /** Return non-zero is a node represents the 1 constant. */
139 static int is_Const_1(ir_node *node) {
140 return is_Const(node) && is_Const_one(node);
143 /** Return non-zero is a node represents the -1 constant. */
144 static int is_Const_Minus_1(ir_node *node) {
145 return is_Const(node) && is_Const_all_one(node);
149 * returns true if constant can be created with a simple float command
151 static int is_simple_x87_Const(ir_node *node)
153 tarval *tv = get_Const_tarval(node);
154 if (tarval_is_null(tv) || tarval_is_one(tv))
157 /* TODO: match all the other float constants */
162 * returns true if constant can be created with a simple float command
164 static int is_simple_sse_Const(ir_node *node)
166 tarval *tv = get_Const_tarval(node);
167 ir_mode *mode = get_tarval_mode(tv);
172 if (tarval_is_null(tv) || tarval_is_one(tv))
175 if (mode == mode_D) {
176 unsigned val = get_tarval_sub_bits(tv, 0) |
177 (get_tarval_sub_bits(tv, 1) << 8) |
178 (get_tarval_sub_bits(tv, 2) << 16) |
179 (get_tarval_sub_bits(tv, 3) << 24);
181 /* lower 32bit are zero, really a 32bit constant */
185 /* TODO: match all the other float constants */
190 * Transforms a Const.
192 static ir_node *gen_Const(ir_node *node) {
193 ir_graph *irg = current_ir_graph;
194 ir_node *old_block = get_nodes_block(node);
195 ir_node *block = be_transform_node(old_block);
196 dbg_info *dbgi = get_irn_dbg_info(node);
197 ir_mode *mode = get_irn_mode(node);
199 assert(is_Const(node));
201 if (mode_is_float(mode)) {
203 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
204 ir_node *nomem = new_NoMem();
208 if (ia32_cg_config.use_sse2) {
209 tarval *tv = get_Const_tarval(node);
210 if (tarval_is_null(tv)) {
211 load = new_rd_ia32_xZero(dbgi, irg, block);
212 set_ia32_ls_mode(load, mode);
214 } else if (tarval_is_one(tv)) {
215 int cnst = mode == mode_F ? 26 : 55;
216 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
217 ir_node *imm2 = create_Immediate(NULL, 0, 2);
218 ir_node *pslld, *psrld;
220 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
221 set_ia32_ls_mode(load, mode);
222 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
223 set_ia32_ls_mode(pslld, mode);
224 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
225 set_ia32_ls_mode(psrld, mode);
227 } else if (mode == mode_F) {
228 /* we can place any 32bit constant by using a movd gp, sse */
229 unsigned val = get_tarval_sub_bits(tv, 0) |
230 (get_tarval_sub_bits(tv, 1) << 8) |
231 (get_tarval_sub_bits(tv, 2) << 16) |
232 (get_tarval_sub_bits(tv, 3) << 24);
233 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
234 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
235 set_ia32_ls_mode(load, mode);
238 if (mode == mode_D) {
239 unsigned val = get_tarval_sub_bits(tv, 0) |
240 (get_tarval_sub_bits(tv, 1) << 8) |
241 (get_tarval_sub_bits(tv, 2) << 16) |
242 (get_tarval_sub_bits(tv, 3) << 24);
244 ir_node *imm32 = create_Immediate(NULL, 0, 32);
245 ir_node *cnst, *psllq;
247 /* fine, lower 32bit are zero, produce 32bit value */
248 val = get_tarval_sub_bits(tv, 4) |
249 (get_tarval_sub_bits(tv, 5) << 8) |
250 (get_tarval_sub_bits(tv, 6) << 16) |
251 (get_tarval_sub_bits(tv, 7) << 24);
252 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
253 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
254 set_ia32_ls_mode(load, mode);
255 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
256 set_ia32_ls_mode(psllq, mode);
261 floatent = create_float_const_entity(node);
263 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
265 set_ia32_op_type(load, ia32_AddrModeS);
266 set_ia32_am_sc(load, floatent);
267 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
268 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
271 if (is_Const_null(node)) {
272 load = new_rd_ia32_vfldz(dbgi, irg, block);
274 set_ia32_ls_mode(load, mode);
275 } else if (is_Const_one(node)) {
276 load = new_rd_ia32_vfld1(dbgi, irg, block);
278 set_ia32_ls_mode(load, mode);
280 floatent = create_float_const_entity(node);
282 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
283 set_ia32_op_type(load, ia32_AddrModeS);
284 set_ia32_am_sc(load, floatent);
285 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
286 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
287 /* take the mode from the entity */
288 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
292 /* Const Nodes before the initial IncSP are a bad idea, because
293 * they could be spilled and we have no SP ready at that point yet.
294 * So add a dependency to the initial frame pointer calculation to
295 * avoid that situation.
297 if (get_irg_start_block(irg) == block) {
298 add_irn_dep(load, get_irg_frame(irg));
301 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
303 } else { /* non-float mode */
305 tarval *tv = get_Const_tarval(node);
308 tv = tarval_convert_to(tv, mode_Iu);
310 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
312 panic("couldn't convert constant tarval (%+F)", node);
314 val = get_tarval_long(tv);
316 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
317 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
320 if (get_irg_start_block(irg) == block) {
321 add_irn_dep(cnst, get_irg_frame(irg));
329 * Transforms a SymConst.
331 static ir_node *gen_SymConst(ir_node *node) {
332 ir_graph *irg = current_ir_graph;
333 ir_node *old_block = get_nodes_block(node);
334 ir_node *block = be_transform_node(old_block);
335 dbg_info *dbgi = get_irn_dbg_info(node);
336 ir_mode *mode = get_irn_mode(node);
339 if (mode_is_float(mode)) {
340 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
341 ir_node *nomem = new_NoMem();
343 if (ia32_cg_config.use_sse2)
344 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
346 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
347 set_ia32_am_sc(cnst, get_SymConst_entity(node));
348 set_ia32_use_frame(cnst);
352 if(get_SymConst_kind(node) != symconst_addr_ent) {
353 panic("backend only support symconst_addr_ent (at %+F)", node);
355 entity = get_SymConst_entity(node);
356 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
359 /* Const Nodes before the initial IncSP are a bad idea, because
360 * they could be spilled and we have no SP ready at that point yet
362 if (get_irg_start_block(irg) == block) {
363 add_irn_dep(cnst, get_irg_frame(irg));
366 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
371 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
372 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
373 static const struct {
375 const char *ent_name;
376 const char *cnst_str;
379 } names [ia32_known_const_max] = {
380 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
381 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
382 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
383 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
384 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
386 static ir_entity *ent_cache[ia32_known_const_max];
388 const char *tp_name, *ent_name, *cnst_str;
396 ent_name = names[kct].ent_name;
397 if (! ent_cache[kct]) {
398 tp_name = names[kct].tp_name;
399 cnst_str = names[kct].cnst_str;
401 switch (names[kct].mode) {
402 case 0: mode = mode_Iu; break;
403 case 1: mode = mode_Lu; break;
404 default: mode = mode_F; break;
406 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
407 tp = new_type_primitive(new_id_from_str(tp_name), mode);
408 /* set the specified alignment */
409 set_type_alignment_bytes(tp, names[kct].align);
411 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
413 set_entity_ld_ident(ent, get_entity_ident(ent));
414 set_entity_visibility(ent, visibility_local);
415 set_entity_variability(ent, variability_constant);
416 set_entity_allocation(ent, allocation_static);
418 /* we create a new entity here: It's initialization must resist on the
420 rem = current_ir_graph;
421 current_ir_graph = get_const_code_irg();
422 cnst = new_Const(mode, tv);
423 current_ir_graph = rem;
425 set_atomic_ent_value(ent, cnst);
427 /* cache the entry */
428 ent_cache[kct] = ent;
431 return ent_cache[kct];
434 static int prevents_AM(ir_node *const block, ir_node *const am_candidate,
435 ir_node *const other)
437 if (get_nodes_block(other) != block)
440 if (is_Sync(other)) {
443 for (i = get_Sync_n_preds(other) - 1; i >= 0; --i) {
444 ir_node *const pred = get_Sync_pred(other, i);
446 if (get_nodes_block(pred) != block)
449 /* Do not block ourselves from getting eaten */
450 if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate)
453 if (!heights_reachable_in_block(heights, pred, am_candidate))
461 /* Do not block ourselves from getting eaten */
462 if (is_Proj(other) && get_Proj_pred(other) == am_candidate)
465 if (!heights_reachable_in_block(heights, other, am_candidate))
473 * return true if the node is a Proj(Load) and could be used in source address
474 * mode for another node. Will return only true if the @p other node is not
475 * dependent on the memory of the Load (for binary operations use the other
476 * input here, for unary operations use NULL).
478 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
479 ir_node *other, ir_node *other2, match_flags_t flags)
484 /* float constants are always available */
485 if (is_Const(node)) {
486 ir_mode *mode = get_irn_mode(node);
487 if (mode_is_float(mode)) {
488 if (ia32_cg_config.use_sse2) {
489 if (is_simple_sse_Const(node))
492 if (is_simple_x87_Const(node))
495 if (get_irn_n_edges(node) > 1)
503 load = get_Proj_pred(node);
504 pn = get_Proj_proj(node);
505 if (!is_Load(load) || pn != pn_Load_res)
507 if (get_nodes_block(load) != block)
509 /* we only use address mode if we're the only user of the load */
510 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
512 /* in some edge cases with address mode we might reach the load normally
513 * and through some AM sequence, if it is already materialized then we
514 * can't create an AM node from it */
515 if (be_is_transformed(node))
518 /* don't do AM if other node inputs depend on the load (via mem-proj) */
519 if (other != NULL && prevents_AM(block, load, other))
522 if (other2 != NULL && prevents_AM(block, load, other2))
528 typedef struct ia32_address_mode_t ia32_address_mode_t;
529 struct ia32_address_mode_t {
533 ia32_op_type_t op_type;
537 unsigned commutative : 1;
538 unsigned ins_permuted : 1;
541 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
545 /* construct load address */
546 memset(addr, 0, sizeof(addr[0]));
547 ia32_create_address_mode(addr, ptr, /*force=*/0);
549 noreg_gp = ia32_new_NoReg_gp(env_cg);
550 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
551 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
552 addr->mem = be_transform_node(mem);
555 static void build_address(ia32_address_mode_t *am, ir_node *node)
557 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
558 ia32_address_t *addr = &am->addr;
564 if (is_Const(node)) {
565 ir_entity *entity = create_float_const_entity(node);
566 addr->base = noreg_gp;
567 addr->index = noreg_gp;
568 addr->mem = new_NoMem();
569 addr->symconst_ent = entity;
571 am->ls_mode = get_type_mode(get_entity_type(entity));
572 am->pinned = op_pin_state_floats;
576 load = get_Proj_pred(node);
577 ptr = get_Load_ptr(load);
578 mem = get_Load_mem(load);
579 new_mem = be_transform_node(mem);
580 am->pinned = get_irn_pinned(load);
581 am->ls_mode = get_Load_mode(load);
582 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
584 /* construct load address */
585 ia32_create_address_mode(addr, ptr, /*force=*/0);
587 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
588 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
592 static void set_address(ir_node *node, const ia32_address_t *addr)
594 set_ia32_am_scale(node, addr->scale);
595 set_ia32_am_sc(node, addr->symconst_ent);
596 set_ia32_am_offs_int(node, addr->offset);
597 if(addr->symconst_sign)
598 set_ia32_am_sc_sign(node);
600 set_ia32_use_frame(node);
601 set_ia32_frame_ent(node, addr->frame_entity);
605 * Apply attributes of a given address mode to a node.
607 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
609 set_address(node, &am->addr);
611 set_ia32_op_type(node, am->op_type);
612 set_ia32_ls_mode(node, am->ls_mode);
613 if (am->pinned == op_pin_state_pinned) {
614 /* beware: some nodes are already pinned and did not allow to change the state */
615 if (get_irn_pinned(node) != op_pin_state_pinned)
616 set_irn_pinned(node, op_pin_state_pinned);
619 set_ia32_commutative(node);
623 * Check, if a given node is a Down-Conv, ie. a integer Conv
624 * from a mode with a mode with more bits to a mode with lesser bits.
625 * Moreover, we return only true if the node has not more than 1 user.
627 * @param node the node
628 * @return non-zero if node is a Down-Conv
630 static int is_downconv(const ir_node *node)
638 /* we only want to skip the conv when we're the only user
639 * (not optimal but for now...)
641 if(get_irn_n_edges(node) > 1)
644 src_mode = get_irn_mode(get_Conv_op(node));
645 dest_mode = get_irn_mode(node);
646 return ia32_mode_needs_gp_reg(src_mode)
647 && ia32_mode_needs_gp_reg(dest_mode)
648 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
651 /* Skip all Down-Conv's on a given node and return the resulting node. */
652 ir_node *ia32_skip_downconv(ir_node *node) {
653 while (is_downconv(node))
654 node = get_Conv_op(node);
659 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
661 ir_mode *mode = get_irn_mode(node);
666 if(mode_is_signed(mode)) {
671 block = get_nodes_block(node);
672 dbgi = get_irn_dbg_info(node);
674 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
678 * matches operands of a node into ia32 addressing/operand modes. This covers
679 * usage of source address mode, immediates, operations with non 32-bit modes,
681 * The resulting data is filled into the @p am struct. block is the block
682 * of the node whose arguments are matched. op1, op2 are the first and second
683 * input that are matched (op1 may be NULL). other_op is another unrelated
684 * input that is not matched! but which is needed sometimes to check if AM
685 * for op1/op2 is legal.
686 * @p flags describes the supported modes of the operation in detail.
688 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
689 ir_node *op1, ir_node *op2, ir_node *other_op,
692 ia32_address_t *addr = &am->addr;
693 ir_mode *mode = get_irn_mode(op2);
694 int mode_bits = get_mode_size_bits(mode);
695 ir_node *noreg_gp, *new_op1, *new_op2;
697 unsigned commutative;
698 int use_am_and_immediates;
701 memset(am, 0, sizeof(am[0]));
703 commutative = (flags & match_commutative) != 0;
704 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
705 use_am = (flags & match_am) != 0;
706 use_immediate = (flags & match_immediate) != 0;
707 assert(!use_am_and_immediates || use_immediate);
710 assert(!commutative || op1 != NULL);
711 assert(use_am || !(flags & match_8bit_am));
712 assert(use_am || !(flags & match_16bit_am));
714 if (mode_bits == 8) {
715 if (!(flags & match_8bit_am))
717 /* we don't automatically add upconvs yet */
718 assert((flags & match_mode_neutral) || (flags & match_8bit));
719 } else if (mode_bits == 16) {
720 if (!(flags & match_16bit_am))
722 /* we don't automatically add upconvs yet */
723 assert((flags & match_mode_neutral) || (flags & match_16bit));
726 /* we can simply skip downconvs for mode neutral nodes: the upper bits
727 * can be random for these operations */
728 if (flags & match_mode_neutral) {
729 op2 = ia32_skip_downconv(op2);
731 op1 = ia32_skip_downconv(op1);
735 /* match immediates. firm nodes are normalized: constants are always on the
738 if (!(flags & match_try_am) && use_immediate) {
739 new_op2 = try_create_Immediate(op2, 0);
742 noreg_gp = ia32_new_NoReg_gp(env_cg);
743 if (new_op2 == NULL &&
744 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
745 build_address(am, op2);
746 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
747 if (mode_is_float(mode)) {
748 new_op2 = ia32_new_NoReg_vfp(env_cg);
752 am->op_type = ia32_AddrModeS;
753 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
755 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
757 build_address(am, op1);
759 if (mode_is_float(mode)) {
760 noreg = ia32_new_NoReg_vfp(env_cg);
765 if (new_op2 != NULL) {
768 new_op1 = be_transform_node(op2);
770 am->ins_permuted = 1;
772 am->op_type = ia32_AddrModeS;
774 if (flags & match_try_am) {
777 am->op_type = ia32_Normal;
781 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
783 new_op2 = be_transform_node(op2);
784 am->op_type = ia32_Normal;
785 am->ls_mode = get_irn_mode(op2);
786 if (flags & match_mode_neutral)
787 am->ls_mode = mode_Iu;
789 if (addr->base == NULL)
790 addr->base = noreg_gp;
791 if (addr->index == NULL)
792 addr->index = noreg_gp;
793 if (addr->mem == NULL)
794 addr->mem = new_NoMem();
796 am->new_op1 = new_op1;
797 am->new_op2 = new_op2;
798 am->commutative = commutative;
801 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
806 if (am->mem_proj == NULL)
809 /* we have to create a mode_T so the old MemProj can attach to us */
810 mode = get_irn_mode(node);
811 load = get_Proj_pred(am->mem_proj);
813 mark_irn_visited(load);
814 be_set_transformed_node(load, node);
816 if (mode != mode_T) {
817 set_irn_mode(node, mode_T);
818 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
825 * Construct a standard binary operation, set AM and immediate if required.
827 * @param node The original node for which the binop is created
828 * @param op1 The first operand
829 * @param op2 The second operand
830 * @param func The node constructor function
831 * @return The constructed ia32 node.
833 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
834 construct_binop_func *func, match_flags_t flags)
837 ir_node *block, *new_block, *new_node;
838 ia32_address_mode_t am;
839 ia32_address_t *addr = &am.addr;
841 block = get_nodes_block(node);
842 match_arguments(&am, block, op1, op2, NULL, flags);
844 dbgi = get_irn_dbg_info(node);
845 new_block = be_transform_node(block);
846 new_node = func(dbgi, current_ir_graph, new_block,
847 addr->base, addr->index, addr->mem,
848 am.new_op1, am.new_op2);
849 set_am_attributes(new_node, &am);
850 /* we can't use source address mode anymore when using immediates */
851 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
852 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
853 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
855 new_node = fix_mem_proj(new_node, &am);
862 n_ia32_l_binop_right,
863 n_ia32_l_binop_eflags
865 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
866 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
867 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
868 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
869 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
870 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
873 * Construct a binary operation which also consumes the eflags.
875 * @param node The node to transform
876 * @param func The node constructor function
877 * @param flags The match flags
878 * @return The constructor ia32 node
880 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
883 ir_node *src_block = get_nodes_block(node);
884 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
885 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
887 ir_node *block, *new_node, *eflags, *new_eflags;
888 ia32_address_mode_t am;
889 ia32_address_t *addr = &am.addr;
891 match_arguments(&am, src_block, op1, op2, NULL, flags);
893 dbgi = get_irn_dbg_info(node);
894 block = be_transform_node(src_block);
895 eflags = get_irn_n(node, n_ia32_l_binop_eflags);
896 new_eflags = be_transform_node(eflags);
897 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
898 addr->mem, am.new_op1, am.new_op2, new_eflags);
899 set_am_attributes(new_node, &am);
900 /* we can't use source address mode anymore when using immediates */
901 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
902 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
903 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
905 new_node = fix_mem_proj(new_node, &am);
910 static ir_node *get_fpcw(void)
913 if (initial_fpcw != NULL)
916 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
917 &ia32_fp_cw_regs[REG_FPCW]);
918 initial_fpcw = be_transform_node(fpcw);
924 * Construct a standard binary operation, set AM and immediate if required.
926 * @param op1 The first operand
927 * @param op2 The second operand
928 * @param func The node constructor function
929 * @return The constructed ia32 node.
931 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
932 construct_binop_float_func *func,
935 ir_mode *mode = get_irn_mode(node);
937 ir_node *block, *new_block, *new_node;
938 ia32_address_mode_t am;
939 ia32_address_t *addr = &am.addr;
941 /* cannot use address mode with long double on x87 */
942 if (get_mode_size_bits(mode) > 64)
945 block = get_nodes_block(node);
946 match_arguments(&am, block, op1, op2, NULL, flags);
948 dbgi = get_irn_dbg_info(node);
949 new_block = be_transform_node(block);
950 new_node = func(dbgi, current_ir_graph, new_block,
951 addr->base, addr->index, addr->mem,
952 am.new_op1, am.new_op2, get_fpcw());
953 set_am_attributes(new_node, &am);
955 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
957 new_node = fix_mem_proj(new_node, &am);
963 * Construct a shift/rotate binary operation, sets AM and immediate if required.
965 * @param op1 The first operand
966 * @param op2 The second operand
967 * @param func The node constructor function
968 * @return The constructed ia32 node.
970 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
971 construct_shift_func *func,
975 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
977 assert(! mode_is_float(get_irn_mode(node)));
978 assert(flags & match_immediate);
979 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
981 if (flags & match_mode_neutral) {
982 op1 = ia32_skip_downconv(op1);
983 new_op1 = be_transform_node(op1);
984 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
985 new_op1 = create_upconv(op1, node);
987 new_op1 = be_transform_node(op1);
990 /* the shift amount can be any mode that is bigger than 5 bits, since all
991 * other bits are ignored anyway */
992 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
993 ir_node *const op = get_Conv_op(op2);
994 if (mode_is_float(get_irn_mode(op)))
997 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
999 new_op2 = create_immediate_or_transform(op2, 0);
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_op1, new_op2);
1005 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1007 /* lowered shift instruction may have a dependency operand, handle it here */
1008 if (get_irn_arity(node) == 3) {
1009 /* we have a dependency */
1010 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1011 add_irn_dep(new_node, new_dep);
1019 * Construct a standard unary operation, set AM and immediate if required.
1021 * @param op The operand
1022 * @param func The node constructor function
1023 * @return The constructed ia32 node.
1025 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1026 match_flags_t flags)
1029 ir_node *block, *new_block, *new_op, *new_node;
1031 assert(flags == 0 || flags == match_mode_neutral);
1032 if (flags & match_mode_neutral) {
1033 op = ia32_skip_downconv(op);
1036 new_op = be_transform_node(op);
1037 dbgi = get_irn_dbg_info(node);
1038 block = get_nodes_block(node);
1039 new_block = be_transform_node(block);
1040 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1042 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1047 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1048 ia32_address_t *addr)
1050 ir_node *base, *index, *res;
1054 base = ia32_new_NoReg_gp(env_cg);
1056 base = be_transform_node(base);
1059 index = addr->index;
1060 if (index == NULL) {
1061 index = ia32_new_NoReg_gp(env_cg);
1063 index = be_transform_node(index);
1066 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1067 set_address(res, addr);
1073 * Returns non-zero if a given address mode has a symbolic or
1074 * numerical offset != 0.
1076 static int am_has_immediates(const ia32_address_t *addr)
1078 return addr->offset != 0 || addr->symconst_ent != NULL
1079 || addr->frame_entity || addr->use_frame;
1083 * Creates an ia32 Add.
1085 * @return the created ia32 Add node
1087 static ir_node *gen_Add(ir_node *node) {
1088 ir_mode *mode = get_irn_mode(node);
1089 ir_node *op1 = get_Add_left(node);
1090 ir_node *op2 = get_Add_right(node);
1092 ir_node *block, *new_block, *new_node, *add_immediate_op;
1093 ia32_address_t addr;
1094 ia32_address_mode_t am;
1096 if (mode_is_float(mode)) {
1097 if (ia32_cg_config.use_sse2)
1098 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1099 match_commutative | match_am);
1101 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1102 match_commutative | match_am);
1105 ia32_mark_non_am(node);
1107 op2 = ia32_skip_downconv(op2);
1108 op1 = ia32_skip_downconv(op1);
1112 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1113 * 1. Add with immediate -> Lea
1114 * 2. Add with possible source address mode -> Add
1115 * 3. Otherwise -> Lea
1117 memset(&addr, 0, sizeof(addr));
1118 ia32_create_address_mode(&addr, node, /*force=*/1);
1119 add_immediate_op = NULL;
1121 dbgi = get_irn_dbg_info(node);
1122 block = get_nodes_block(node);
1123 new_block = be_transform_node(block);
1126 if(addr.base == NULL && addr.index == NULL) {
1127 ir_graph *irg = current_ir_graph;
1128 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1129 addr.symconst_sign, addr.offset);
1130 add_irn_dep(new_node, get_irg_frame(irg));
1131 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1134 /* add with immediate? */
1135 if(addr.index == NULL) {
1136 add_immediate_op = addr.base;
1137 } else if(addr.base == NULL && addr.scale == 0) {
1138 add_immediate_op = addr.index;
1141 if(add_immediate_op != NULL) {
1142 if(!am_has_immediates(&addr)) {
1143 #ifdef DEBUG_libfirm
1144 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1147 return be_transform_node(add_immediate_op);
1150 new_node = create_lea_from_address(dbgi, new_block, &addr);
1151 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1155 /* test if we can use source address mode */
1156 match_arguments(&am, block, op1, op2, NULL, match_commutative
1157 | match_mode_neutral | match_am | match_immediate | match_try_am);
1159 /* construct an Add with source address mode */
1160 if (am.op_type == ia32_AddrModeS) {
1161 ir_graph *irg = current_ir_graph;
1162 ia32_address_t *am_addr = &am.addr;
1163 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1164 am_addr->index, am_addr->mem, am.new_op1,
1166 set_am_attributes(new_node, &am);
1167 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1169 new_node = fix_mem_proj(new_node, &am);
1174 /* otherwise construct a lea */
1175 new_node = create_lea_from_address(dbgi, new_block, &addr);
1176 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1181 * Creates an ia32 Mul.
1183 * @return the created ia32 Mul node
1185 static ir_node *gen_Mul(ir_node *node) {
1186 ir_node *op1 = get_Mul_left(node);
1187 ir_node *op2 = get_Mul_right(node);
1188 ir_mode *mode = get_irn_mode(node);
1190 if (mode_is_float(mode)) {
1191 if (ia32_cg_config.use_sse2)
1192 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1193 match_commutative | match_am);
1195 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1196 match_commutative | match_am);
1198 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1199 match_commutative | match_am | match_mode_neutral |
1200 match_immediate | match_am_and_immediates);
1204 * Creates an ia32 Mulh.
1205 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1206 * this result while Mul returns the lower 32 bit.
1208 * @return the created ia32 Mulh node
1210 static ir_node *gen_Mulh(ir_node *node)
1212 ir_node *block = get_nodes_block(node);
1213 ir_node *new_block = be_transform_node(block);
1214 ir_graph *irg = current_ir_graph;
1215 dbg_info *dbgi = get_irn_dbg_info(node);
1216 ir_mode *mode = get_irn_mode(node);
1217 ir_node *op1 = get_Mulh_left(node);
1218 ir_node *op2 = get_Mulh_right(node);
1219 ir_node *proj_res_high;
1221 ia32_address_mode_t am;
1222 ia32_address_t *addr = &am.addr;
1224 assert(!mode_is_float(mode) && "Mulh with float not supported");
1225 assert(get_mode_size_bits(mode) == 32);
1227 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1229 if (mode_is_signed(mode)) {
1230 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1231 addr->index, addr->mem, am.new_op1,
1234 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1235 addr->index, addr->mem, am.new_op1,
1239 set_am_attributes(new_node, &am);
1240 /* we can't use source address mode anymore when using immediates */
1241 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1242 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1243 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1245 assert(get_irn_mode(new_node) == mode_T);
1247 fix_mem_proj(new_node, &am);
1249 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1250 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1251 mode_Iu, pn_ia32_IMul1OP_res_high);
1253 return proj_res_high;
1259 * Creates an ia32 And.
1261 * @return The created ia32 And node
1263 static ir_node *gen_And(ir_node *node) {
1264 ir_node *op1 = get_And_left(node);
1265 ir_node *op2 = get_And_right(node);
1266 assert(! mode_is_float(get_irn_mode(node)));
1268 /* is it a zero extension? */
1269 if (is_Const(op2)) {
1270 tarval *tv = get_Const_tarval(op2);
1271 long v = get_tarval_long(tv);
1273 if (v == 0xFF || v == 0xFFFF) {
1274 dbg_info *dbgi = get_irn_dbg_info(node);
1275 ir_node *block = get_nodes_block(node);
1282 assert(v == 0xFFFF);
1285 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1290 return gen_binop(node, op1, op2, new_rd_ia32_And,
1291 match_commutative | match_mode_neutral | match_am
1298 * Creates an ia32 Or.
1300 * @return The created ia32 Or node
1302 static ir_node *gen_Or(ir_node *node) {
1303 ir_node *op1 = get_Or_left(node);
1304 ir_node *op2 = get_Or_right(node);
1306 assert (! mode_is_float(get_irn_mode(node)));
1307 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1308 | match_mode_neutral | match_am | match_immediate);
1314 * Creates an ia32 Eor.
1316 * @return The created ia32 Eor node
1318 static ir_node *gen_Eor(ir_node *node) {
1319 ir_node *op1 = get_Eor_left(node);
1320 ir_node *op2 = get_Eor_right(node);
1322 assert(! mode_is_float(get_irn_mode(node)));
1323 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1324 | match_mode_neutral | match_am | match_immediate);
1329 * Creates an ia32 Sub.
1331 * @return The created ia32 Sub node
1333 static ir_node *gen_Sub(ir_node *node) {
1334 ir_node *op1 = get_Sub_left(node);
1335 ir_node *op2 = get_Sub_right(node);
1336 ir_mode *mode = get_irn_mode(node);
1338 if (mode_is_float(mode)) {
1339 if (ia32_cg_config.use_sse2)
1340 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1342 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1346 if (is_Const(op2)) {
1347 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1351 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1352 | match_am | match_immediate);
1355 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1356 ir_node *const src_val,
1357 ir_node *const src_mem,
1358 ir_node *const am_mem)
1360 if (is_NoMem(am_mem)) {
1361 return be_transform_node(src_mem);
1362 } else if (is_Proj(src_val) &&
1364 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1365 /* avoid memory loop */
1367 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1368 ir_node *const ptr_pred = get_Proj_pred(src_val);
1369 int const arity = get_Sync_n_preds(src_mem);
1374 NEW_ARR_A(ir_node*, ins, arity + 1);
1376 for (i = arity - 1; i >= 0; --i) {
1377 ir_node *const pred = get_Sync_pred(src_mem, i);
1379 /* avoid memory loop */
1380 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1383 ins[n++] = be_transform_node(pred);
1388 return new_r_Sync(irg, block, n, ins);
1392 ins[0] = be_transform_node(src_mem);
1394 return new_r_Sync(irg, block, 2, ins);
1399 * Generates an ia32 DivMod with additional infrastructure for the
1400 * register allocator if needed.
1402 static ir_node *create_Div(ir_node *node)
1404 ir_graph *irg = current_ir_graph;
1405 dbg_info *dbgi = get_irn_dbg_info(node);
1406 ir_node *block = get_nodes_block(node);
1407 ir_node *new_block = be_transform_node(block);
1414 ir_node *sign_extension;
1415 ia32_address_mode_t am;
1416 ia32_address_t *addr = &am.addr;
1418 /* the upper bits have random contents for smaller modes */
1419 switch (get_irn_opcode(node)) {
1421 op1 = get_Div_left(node);
1422 op2 = get_Div_right(node);
1423 mem = get_Div_mem(node);
1424 mode = get_Div_resmode(node);
1427 op1 = get_Mod_left(node);
1428 op2 = get_Mod_right(node);
1429 mem = get_Mod_mem(node);
1430 mode = get_Mod_resmode(node);
1433 op1 = get_DivMod_left(node);
1434 op2 = get_DivMod_right(node);
1435 mem = get_DivMod_mem(node);
1436 mode = get_DivMod_resmode(node);
1439 panic("invalid divmod node %+F", node);
1442 match_arguments(&am, block, op1, op2, NULL, match_am);
1444 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1445 is the memory of the consumed address. We can have only the second op as address
1446 in Div nodes, so check only op2. */
1447 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1449 if (mode_is_signed(mode)) {
1450 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1451 add_irn_dep(produceval, get_irg_frame(irg));
1452 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1455 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1456 addr->index, new_mem, am.new_op2,
1457 am.new_op1, sign_extension);
1459 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1460 add_irn_dep(sign_extension, get_irg_frame(irg));
1462 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1463 addr->index, new_mem, am.new_op2,
1464 am.new_op1, sign_extension);
1467 set_irn_pinned(new_node, get_irn_pinned(node));
1469 set_am_attributes(new_node, &am);
1470 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1472 new_node = fix_mem_proj(new_node, &am);
1478 static ir_node *gen_Mod(ir_node *node) {
1479 return create_Div(node);
1482 static ir_node *gen_Div(ir_node *node) {
1483 return create_Div(node);
1486 static ir_node *gen_DivMod(ir_node *node) {
1487 return create_Div(node);
1493 * Creates an ia32 floating Div.
1495 * @return The created ia32 xDiv node
1497 static ir_node *gen_Quot(ir_node *node)
1499 ir_node *op1 = get_Quot_left(node);
1500 ir_node *op2 = get_Quot_right(node);
1502 if (ia32_cg_config.use_sse2) {
1503 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1505 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1511 * Creates an ia32 Shl.
1513 * @return The created ia32 Shl node
1515 static ir_node *gen_Shl(ir_node *node) {
1516 ir_node *left = get_Shl_left(node);
1517 ir_node *right = get_Shl_right(node);
1519 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1520 match_mode_neutral | match_immediate);
1524 * Creates an ia32 Shr.
1526 * @return The created ia32 Shr node
1528 static ir_node *gen_Shr(ir_node *node) {
1529 ir_node *left = get_Shr_left(node);
1530 ir_node *right = get_Shr_right(node);
1532 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1538 * Creates an ia32 Sar.
1540 * @return The created ia32 Shrs node
1542 static ir_node *gen_Shrs(ir_node *node) {
1543 ir_node *left = get_Shrs_left(node);
1544 ir_node *right = get_Shrs_right(node);
1545 ir_mode *mode = get_irn_mode(node);
1547 if(is_Const(right) && mode == mode_Is) {
1548 tarval *tv = get_Const_tarval(right);
1549 long val = get_tarval_long(tv);
1551 /* this is a sign extension */
1552 ir_graph *irg = current_ir_graph;
1553 dbg_info *dbgi = get_irn_dbg_info(node);
1554 ir_node *block = be_transform_node(get_nodes_block(node));
1556 ir_node *new_op = be_transform_node(op);
1557 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1558 add_irn_dep(pval, get_irg_frame(irg));
1560 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1564 /* 8 or 16 bit sign extension? */
1565 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1566 ir_node *shl_left = get_Shl_left(left);
1567 ir_node *shl_right = get_Shl_right(left);
1568 if(is_Const(shl_right)) {
1569 tarval *tv1 = get_Const_tarval(right);
1570 tarval *tv2 = get_Const_tarval(shl_right);
1571 if(tv1 == tv2 && tarval_is_long(tv1)) {
1572 long val = get_tarval_long(tv1);
1573 if(val == 16 || val == 24) {
1574 dbg_info *dbgi = get_irn_dbg_info(node);
1575 ir_node *block = get_nodes_block(node);
1585 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1594 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1600 * Creates an ia32 Rol.
1602 * @param op1 The first operator
1603 * @param op2 The second operator
1604 * @return The created ia32 RotL node
1606 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1607 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1613 * Creates an ia32 Ror.
1614 * NOTE: There is no RotR with immediate because this would always be a RotL
1615 * "imm-mode_size_bits" which can be pre-calculated.
1617 * @param op1 The first operator
1618 * @param op2 The second operator
1619 * @return The created ia32 RotR node
1621 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1622 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1628 * Creates an ia32 RotR or RotL (depending on the found pattern).
1630 * @return The created ia32 RotL or RotR node
1632 static ir_node *gen_Rotl(ir_node *node) {
1633 ir_node *rotate = NULL;
1634 ir_node *op1 = get_Rotl_left(node);
1635 ir_node *op2 = get_Rotl_right(node);
1637 /* Firm has only RotL, so we are looking for a right (op2)
1638 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1639 that means we can create a RotR instead of an Add and a RotL */
1643 ir_node *left = get_Add_left(add);
1644 ir_node *right = get_Add_right(add);
1645 if (is_Const(right)) {
1646 tarval *tv = get_Const_tarval(right);
1647 ir_mode *mode = get_irn_mode(node);
1648 long bits = get_mode_size_bits(mode);
1650 if (is_Minus(left) &&
1651 tarval_is_long(tv) &&
1652 get_tarval_long(tv) == bits &&
1655 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1656 rotate = gen_Ror(node, op1, get_Minus_op(left));
1661 if (rotate == NULL) {
1662 rotate = gen_Rol(node, op1, op2);
1671 * Transforms a Minus node.
1673 * @return The created ia32 Minus node
1675 static ir_node *gen_Minus(ir_node *node)
1677 ir_node *op = get_Minus_op(node);
1678 ir_node *block = be_transform_node(get_nodes_block(node));
1679 ir_graph *irg = current_ir_graph;
1680 dbg_info *dbgi = get_irn_dbg_info(node);
1681 ir_mode *mode = get_irn_mode(node);
1686 if (mode_is_float(mode)) {
1687 ir_node *new_op = be_transform_node(op);
1688 if (ia32_cg_config.use_sse2) {
1689 /* TODO: non-optimal... if we have many xXors, then we should
1690 * rather create a load for the const and use that instead of
1691 * several AM nodes... */
1692 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1693 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1694 ir_node *nomem = new_rd_NoMem(irg);
1696 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1697 nomem, new_op, noreg_xmm);
1699 size = get_mode_size_bits(mode);
1700 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1702 set_ia32_am_sc(new_node, ent);
1703 set_ia32_op_type(new_node, ia32_AddrModeS);
1704 set_ia32_ls_mode(new_node, mode);
1706 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1709 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1712 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1718 * Transforms a Not node.
1720 * @return The created ia32 Not node
1722 static ir_node *gen_Not(ir_node *node) {
1723 ir_node *op = get_Not_op(node);
1725 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1726 assert (! mode_is_float(get_irn_mode(node)));
1728 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1734 * Transforms an Abs node.
1736 * @return The created ia32 Abs node
1738 static ir_node *gen_Abs(ir_node *node)
1740 ir_node *block = get_nodes_block(node);
1741 ir_node *new_block = be_transform_node(block);
1742 ir_node *op = get_Abs_op(node);
1743 ir_graph *irg = current_ir_graph;
1744 dbg_info *dbgi = get_irn_dbg_info(node);
1745 ir_mode *mode = get_irn_mode(node);
1746 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1747 ir_node *nomem = new_NoMem();
1753 if (mode_is_float(mode)) {
1754 new_op = be_transform_node(op);
1756 if (ia32_cg_config.use_sse2) {
1757 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1758 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1759 nomem, new_op, noreg_fp);
1761 size = get_mode_size_bits(mode);
1762 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1764 set_ia32_am_sc(new_node, ent);
1766 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1768 set_ia32_op_type(new_node, ia32_AddrModeS);
1769 set_ia32_ls_mode(new_node, mode);
1771 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1772 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1775 ir_node *xor, *pval, *sign_extension;
1777 if (get_mode_size_bits(mode) == 32) {
1778 new_op = be_transform_node(op);
1780 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1783 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1784 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1787 add_irn_dep(pval, get_irg_frame(irg));
1788 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1790 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1791 nomem, new_op, sign_extension);
1792 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1794 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1795 nomem, xor, sign_extension);
1796 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1803 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1805 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1806 dbg_info *dbgi = get_irn_dbg_info(cmp);
1807 ir_node *block = get_nodes_block(cmp);
1808 ir_node *new_block = be_transform_node(block);
1809 ir_node *op1 = be_transform_node(x);
1810 ir_node *op2 = be_transform_node(n);
1812 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1816 * Transform a node returning a "flag" result.
1818 * @param node the node to transform
1819 * @param pnc_out the compare mode to use
1821 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1830 /* we have a Cmp as input */
1831 if (is_Proj(node)) {
1832 ir_node *pred = get_Proj_pred(node);
1834 pn_Cmp pnc = get_Proj_proj(node);
1835 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1836 ir_node *l = get_Cmp_left(pred);
1837 ir_node *r = get_Cmp_right(pred);
1839 ir_node *la = get_And_left(l);
1840 ir_node *ra = get_And_right(l);
1842 ir_node *c = get_Shl_left(la);
1843 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1844 /* (1 << n) & ra) */
1845 ir_node *n = get_Shl_right(la);
1846 flags = gen_bt(pred, ra, n);
1847 /* we must generate a Jc/Jnc jump */
1848 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1851 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1856 ir_node *c = get_Shl_left(ra);
1857 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1858 /* la & (1 << n)) */
1859 ir_node *n = get_Shl_right(ra);
1860 flags = gen_bt(pred, la, n);
1861 /* we must generate a Jc/Jnc jump */
1862 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1865 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1871 flags = be_transform_node(pred);
1877 /* a mode_b value, we have to compare it against 0 */
1878 dbgi = get_irn_dbg_info(node);
1879 new_block = be_transform_node(get_nodes_block(node));
1880 new_op = be_transform_node(node);
1881 noreg = ia32_new_NoReg_gp(env_cg);
1882 nomem = new_NoMem();
1883 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1884 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1885 *pnc_out = pn_Cmp_Lg;
1890 * Transforms a Load.
1892 * @return the created ia32 Load node
1894 static ir_node *gen_Load(ir_node *node) {
1895 ir_node *old_block = get_nodes_block(node);
1896 ir_node *block = be_transform_node(old_block);
1897 ir_node *ptr = get_Load_ptr(node);
1898 ir_node *mem = get_Load_mem(node);
1899 ir_node *new_mem = be_transform_node(mem);
1902 ir_graph *irg = current_ir_graph;
1903 dbg_info *dbgi = get_irn_dbg_info(node);
1904 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1905 ir_mode *mode = get_Load_mode(node);
1908 ia32_address_t addr;
1910 /* construct load address */
1911 memset(&addr, 0, sizeof(addr));
1912 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1919 base = be_transform_node(base);
1925 index = be_transform_node(index);
1928 if (mode_is_float(mode)) {
1929 if (ia32_cg_config.use_sse2) {
1930 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1932 res_mode = mode_xmm;
1934 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1936 res_mode = mode_vfp;
1939 assert(mode != mode_b);
1941 /* create a conv node with address mode for smaller modes */
1942 if(get_mode_size_bits(mode) < 32) {
1943 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1944 new_mem, noreg, mode);
1946 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1951 set_irn_pinned(new_node, get_irn_pinned(node));
1952 set_ia32_op_type(new_node, ia32_AddrModeS);
1953 set_ia32_ls_mode(new_node, mode);
1954 set_address(new_node, &addr);
1956 if(get_irn_pinned(node) == op_pin_state_floats) {
1957 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1960 /* make sure we are scheduled behind the initial IncSP/Barrier
1961 * to avoid spills being placed before it
1963 if (block == get_irg_start_block(irg)) {
1964 add_irn_dep(new_node, get_irg_frame(irg));
1967 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1972 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1973 ir_node *ptr, ir_node *other)
1980 /* we only use address mode if we're the only user of the load */
1981 if(get_irn_n_edges(node) > 1)
1984 load = get_Proj_pred(node);
1987 if(get_nodes_block(load) != block)
1990 /* Store should be attached to the load */
1991 if(!is_Proj(mem) || get_Proj_pred(mem) != load)
1993 /* store should have the same pointer as the load */
1994 if(get_Load_ptr(load) != ptr)
1997 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1998 if(other != NULL && get_nodes_block(other) == block
1999 && heights_reachable_in_block(heights, other, load))
2005 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
2007 mark_irn_visited(old_node);
2008 be_set_transformed_node(old_node, new_node);
2011 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2012 ir_node *mem, ir_node *ptr, ir_mode *mode,
2013 construct_binop_dest_func *func,
2014 construct_binop_dest_func *func8bit,
2015 match_flags_t flags)
2017 ir_node *src_block = get_nodes_block(node);
2019 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2020 ir_graph *irg = current_ir_graph;
2026 ia32_address_mode_t am;
2027 ia32_address_t *addr = &am.addr;
2028 memset(&am, 0, sizeof(am));
2030 assert(flags & match_dest_am);
2031 assert(flags & match_immediate); /* there is no destam node without... */
2032 commutative = (flags & match_commutative) != 0;
2034 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2035 build_address(&am, op1);
2036 new_op = create_immediate_or_transform(op2, 0);
2037 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2038 build_address(&am, op2);
2039 new_op = create_immediate_or_transform(op1, 0);
2044 if(addr->base == NULL)
2045 addr->base = noreg_gp;
2046 if(addr->index == NULL)
2047 addr->index = noreg_gp;
2048 if(addr->mem == NULL)
2049 addr->mem = new_NoMem();
2051 dbgi = get_irn_dbg_info(node);
2052 block = be_transform_node(src_block);
2053 if(get_mode_size_bits(mode) == 8) {
2054 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2057 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
2060 set_address(new_node, addr);
2061 set_ia32_op_type(new_node, ia32_AddrModeD);
2062 set_ia32_ls_mode(new_node, mode);
2063 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2065 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2066 mem_proj = be_transform_node(am.mem_proj);
2067 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2072 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2073 ir_node *ptr, ir_mode *mode,
2074 construct_unop_dest_func *func)
2076 ir_graph *irg = current_ir_graph;
2077 ir_node *src_block = get_nodes_block(node);
2082 ia32_address_mode_t am;
2083 ia32_address_t *addr = &am.addr;
2084 memset(&am, 0, sizeof(am));
2086 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2089 build_address(&am, op);
2091 dbgi = get_irn_dbg_info(node);
2092 block = be_transform_node(src_block);
2093 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2094 set_address(new_node, addr);
2095 set_ia32_op_type(new_node, ia32_AddrModeD);
2096 set_ia32_ls_mode(new_node, mode);
2097 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2099 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2100 mem_proj = be_transform_node(am.mem_proj);
2101 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2106 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2107 ir_mode *mode = get_irn_mode(node);
2108 ir_node *mux_true = get_Mux_true(node);
2109 ir_node *mux_false = get_Mux_false(node);
2120 ia32_address_t addr;
2122 if(get_mode_size_bits(mode) != 8)
2125 if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2127 } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2133 build_address_ptr(&addr, ptr, mem);
2135 irg = current_ir_graph;
2136 dbgi = get_irn_dbg_info(node);
2137 block = get_nodes_block(node);
2138 new_block = be_transform_node(block);
2139 cond = get_Mux_sel(node);
2140 flags = get_flags_node(cond, &pnc);
2141 new_mem = be_transform_node(mem);
2142 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2143 addr.index, addr.mem, flags, pnc, negated);
2144 set_address(new_node, &addr);
2145 set_ia32_op_type(new_node, ia32_AddrModeD);
2146 set_ia32_ls_mode(new_node, mode);
2147 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2152 static ir_node *try_create_dest_am(ir_node *node) {
2153 ir_node *val = get_Store_value(node);
2154 ir_node *mem = get_Store_mem(node);
2155 ir_node *ptr = get_Store_ptr(node);
2156 ir_mode *mode = get_irn_mode(val);
2157 unsigned bits = get_mode_size_bits(mode);
2162 /* handle only GP modes for now... */
2163 if(!ia32_mode_needs_gp_reg(mode))
2167 /* store must be the only user of the val node */
2168 if(get_irn_n_edges(val) > 1)
2170 /* skip pointless convs */
2172 ir_node *conv_op = get_Conv_op(val);
2173 ir_mode *pred_mode = get_irn_mode(conv_op);
2174 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2182 /* value must be in the same block */
2183 if(get_nodes_block(node) != get_nodes_block(val))
2186 switch (get_irn_opcode(val)) {
2188 op1 = get_Add_left(val);
2189 op2 = get_Add_right(val);
2190 if(is_Const_1(op2)) {
2191 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2192 new_rd_ia32_IncMem);
2194 } else if(is_Const_Minus_1(op2)) {
2195 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2196 new_rd_ia32_DecMem);
2199 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2200 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2201 match_dest_am | match_commutative |
2205 op1 = get_Sub_left(val);
2206 op2 = get_Sub_right(val);
2208 ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2211 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2212 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2213 match_dest_am | match_immediate |
2217 op1 = get_And_left(val);
2218 op2 = get_And_right(val);
2219 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2220 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2221 match_dest_am | match_commutative |
2225 op1 = get_Or_left(val);
2226 op2 = get_Or_right(val);
2227 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2228 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2229 match_dest_am | match_commutative |
2233 op1 = get_Eor_left(val);
2234 op2 = get_Eor_right(val);
2235 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2236 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2237 match_dest_am | match_commutative |
2241 op1 = get_Shl_left(val);
2242 op2 = get_Shl_right(val);
2243 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2244 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2245 match_dest_am | match_immediate);
2248 op1 = get_Shr_left(val);
2249 op2 = get_Shr_right(val);
2250 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2251 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2252 match_dest_am | match_immediate);
2255 op1 = get_Shrs_left(val);
2256 op2 = get_Shrs_right(val);
2257 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2258 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2259 match_dest_am | match_immediate);
2262 op1 = get_Rotl_left(val);
2263 op2 = get_Rotl_right(val);
2264 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2265 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2266 match_dest_am | match_immediate);
2268 /* TODO: match ROR patterns... */
2270 new_node = try_create_SetMem(val, ptr, mem);
2273 op1 = get_Minus_op(val);
2274 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2277 /* should be lowered already */
2278 assert(mode != mode_b);
2279 op1 = get_Not_op(val);
2280 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2286 if(new_node != NULL) {
2287 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2288 get_irn_pinned(node) == op_pin_state_pinned) {
2289 set_irn_pinned(new_node, op_pin_state_pinned);
2296 static int is_float_to_int32_conv(const ir_node *node)
2298 ir_mode *mode = get_irn_mode(node);
2302 if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode))
2304 /* don't report unsigned as conv to 32bit, because we really need to do
2305 * a vfist with 64bit signed in this case */
2306 if(!mode_is_signed(mode))
2311 conv_op = get_Conv_op(node);
2312 conv_mode = get_irn_mode(conv_op);
2314 if(!mode_is_float(conv_mode))
2321 * Transform a Store(floatConst).
2323 * @return the created ia32 Store node
2325 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2326 ir_mode *mode = get_irn_mode(cns);
2327 int size = get_mode_size_bits(mode);
2328 tarval *tv = get_Const_tarval(cns);
2329 ir_node *block = get_nodes_block(node);
2330 ir_node *new_block = be_transform_node(block);
2331 ir_node *ptr = get_Store_ptr(node);
2332 ir_node *mem = get_Store_mem(node);
2333 ir_graph *irg = current_ir_graph;
2334 dbg_info *dbgi = get_irn_dbg_info(node);
2335 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2338 ia32_address_t addr;
2340 unsigned val = get_tarval_sub_bits(tv, 0) |
2341 (get_tarval_sub_bits(tv, 1) << 8) |
2342 (get_tarval_sub_bits(tv, 2) << 16) |
2343 (get_tarval_sub_bits(tv, 3) << 24);
2344 ir_node *imm = create_Immediate(NULL, 0, val);
2346 /* construct store address */
2347 memset(&addr, 0, sizeof(addr));
2348 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2350 if (addr.base == NULL) {
2353 addr.base = be_transform_node(addr.base);
2356 if (addr.index == NULL) {
2359 addr.index = be_transform_node(addr.index);
2361 addr.mem = be_transform_node(mem);
2363 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2364 addr.index, addr.mem, imm);
2366 set_irn_pinned(new_node, get_irn_pinned(node));
2367 set_ia32_op_type(new_node, ia32_AddrModeD);
2368 set_ia32_ls_mode(new_node, mode_Iu);
2370 set_address(new_node, &addr);
2372 /** add more stores if needed */
2374 unsigned val = get_tarval_sub_bits(tv, ofs) |
2375 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2376 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2377 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2378 ir_node *imm = create_Immediate(NULL, 0, val);
2381 addr.mem = new_node;
2383 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2384 addr.index, addr.mem, imm);
2386 set_irn_pinned(new_node, get_irn_pinned(node));
2387 set_ia32_op_type(new_node, ia32_AddrModeD);
2388 set_ia32_ls_mode(new_node, mode_Iu);
2390 set_address(new_node, &addr);
2395 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2400 * Generate a vfist or vfisttp instruction.
2402 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2403 ir_node *mem, ir_node *val, ir_node **fist)
2407 if (ia32_cg_config.use_fisttp) {
2408 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2409 if other users exists */
2410 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2411 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2412 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2413 be_new_Keep(reg_class, irg, block, 1, &value);
2415 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2418 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2421 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2427 * Transforms a normal Store.
2429 * @return the created ia32 Store node
2431 static ir_node *gen_normal_Store(ir_node *node)
2433 ir_node *val = get_Store_value(node);
2434 ir_mode *mode = get_irn_mode(val);
2435 ir_node *block = get_nodes_block(node);
2436 ir_node *new_block = be_transform_node(block);
2437 ir_node *ptr = get_Store_ptr(node);
2438 ir_node *mem = get_Store_mem(node);
2439 ir_graph *irg = current_ir_graph;
2440 dbg_info *dbgi = get_irn_dbg_info(node);
2441 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2442 ir_node *new_val, *new_node, *store;
2443 ia32_address_t addr;
2445 /* check for destination address mode */
2446 new_node = try_create_dest_am(node);
2447 if (new_node != NULL)
2450 /* construct store address */
2451 memset(&addr, 0, sizeof(addr));
2452 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2454 if (addr.base == NULL) {
2457 addr.base = be_transform_node(addr.base);
2460 if (addr.index == NULL) {
2463 addr.index = be_transform_node(addr.index);
2465 addr.mem = be_transform_node(mem);
2467 if (mode_is_float(mode)) {
2468 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2470 while (is_Conv(val) && mode == get_irn_mode(val)) {
2471 ir_node *op = get_Conv_op(val);
2472 if (!mode_is_float(get_irn_mode(op)))
2476 new_val = be_transform_node(val);
2477 if (ia32_cg_config.use_sse2) {
2478 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2479 addr.index, addr.mem, new_val);
2481 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2482 addr.index, addr.mem, new_val, mode);
2485 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2486 val = get_Conv_op(val);
2488 /* TODO: is this optimisation still necessary at all (middleend)? */
2489 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2490 while (is_Conv(val)) {
2491 ir_node *op = get_Conv_op(val);
2492 if (!mode_is_float(get_irn_mode(op)))
2494 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2498 new_val = be_transform_node(val);
2499 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2501 new_val = create_immediate_or_transform(val, 0);
2502 assert(mode != mode_b);
2504 if (get_mode_size_bits(mode) == 8) {
2505 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2506 addr.index, addr.mem, new_val);
2508 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2509 addr.index, addr.mem, new_val);
2514 set_irn_pinned(store, get_irn_pinned(node));
2515 set_ia32_op_type(store, ia32_AddrModeD);
2516 set_ia32_ls_mode(store, mode);
2518 set_address(store, &addr);
2519 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2525 * Transforms a Store.
2527 * @return the created ia32 Store node
2529 static ir_node *gen_Store(ir_node *node)
2531 ir_node *val = get_Store_value(node);
2532 ir_mode *mode = get_irn_mode(val);
2534 if (mode_is_float(mode) && is_Const(val)) {
2537 /* we are storing a floating point constant */
2538 if (ia32_cg_config.use_sse2) {
2539 transform = !is_simple_sse_Const(val);
2541 transform = !is_simple_x87_Const(val);
2544 return gen_float_const_Store(node, val);
2546 return gen_normal_Store(node);
2550 * Transforms a Switch.
2552 * @return the created ia32 SwitchJmp node
2554 static ir_node *create_Switch(ir_node *node)
2556 ir_graph *irg = current_ir_graph;
2557 dbg_info *dbgi = get_irn_dbg_info(node);
2558 ir_node *block = be_transform_node(get_nodes_block(node));
2559 ir_node *sel = get_Cond_selector(node);
2560 ir_node *new_sel = be_transform_node(sel);
2561 int switch_min = INT_MAX;
2562 int switch_max = INT_MIN;
2563 long default_pn = get_Cond_defaultProj(node);
2565 const ir_edge_t *edge;
2567 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2569 /* determine the smallest switch case value */
2570 foreach_out_edge(node, edge) {
2571 ir_node *proj = get_edge_src_irn(edge);
2572 long pn = get_Proj_proj(proj);
2573 if(pn == default_pn)
2582 if((unsigned) (switch_max - switch_min) > 256000) {
2583 panic("Size of switch %+F bigger than 256000", node);
2586 if (switch_min != 0) {
2587 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2589 /* if smallest switch case is not 0 we need an additional sub */
2590 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2591 add_ia32_am_offs_int(new_sel, -switch_min);
2592 set_ia32_op_type(new_sel, ia32_AddrModeS);
2594 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2597 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2598 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2604 * Transform a Cond node.
2606 static ir_node *gen_Cond(ir_node *node) {
2607 ir_node *block = get_nodes_block(node);
2608 ir_node *new_block = be_transform_node(block);
2609 ir_graph *irg = current_ir_graph;
2610 dbg_info *dbgi = get_irn_dbg_info(node);
2611 ir_node *sel = get_Cond_selector(node);
2612 ir_mode *sel_mode = get_irn_mode(sel);
2613 ir_node *flags = NULL;
2617 if (sel_mode != mode_b) {
2618 return create_Switch(node);
2621 /* we get flags from a Cmp */
2622 flags = get_flags_node(sel, &pnc);
2624 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2625 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2631 * Transforms a CopyB node.
2633 * @return The transformed node.
2635 static ir_node *gen_CopyB(ir_node *node) {
2636 ir_node *block = be_transform_node(get_nodes_block(node));
2637 ir_node *src = get_CopyB_src(node);
2638 ir_node *new_src = be_transform_node(src);
2639 ir_node *dst = get_CopyB_dst(node);
2640 ir_node *new_dst = be_transform_node(dst);
2641 ir_node *mem = get_CopyB_mem(node);
2642 ir_node *new_mem = be_transform_node(mem);
2643 ir_node *res = NULL;
2644 ir_graph *irg = current_ir_graph;
2645 dbg_info *dbgi = get_irn_dbg_info(node);
2646 int size = get_type_size_bytes(get_CopyB_type(node));
2649 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2650 /* then we need the size explicitly in ECX. */
2651 if (size >= 32 * 4) {
2652 rem = size & 0x3; /* size % 4 */
2655 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2656 add_irn_dep(res, get_irg_frame(irg));
2658 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2661 ir_fprintf(stderr, "Optimization warning copyb %+F with size <4\n",
2664 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2667 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2672 static ir_node *gen_be_Copy(ir_node *node)
2674 ir_node *new_node = be_duplicate_node(node);
2675 ir_mode *mode = get_irn_mode(new_node);
2677 if (ia32_mode_needs_gp_reg(mode)) {
2678 set_irn_mode(new_node, mode_Iu);
2684 static ir_node *create_Fucom(ir_node *node)
2686 ir_graph *irg = current_ir_graph;
2687 dbg_info *dbgi = get_irn_dbg_info(node);
2688 ir_node *block = get_nodes_block(node);
2689 ir_node *new_block = be_transform_node(block);
2690 ir_node *left = get_Cmp_left(node);
2691 ir_node *new_left = be_transform_node(left);
2692 ir_node *right = get_Cmp_right(node);
2696 if(ia32_cg_config.use_fucomi) {
2697 new_right = be_transform_node(right);
2698 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2700 set_ia32_commutative(new_node);
2701 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2703 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2704 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2707 new_right = be_transform_node(right);
2708 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2712 set_ia32_commutative(new_node);
2714 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2716 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2717 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2723 static ir_node *create_Ucomi(ir_node *node)
2725 ir_graph *irg = current_ir_graph;
2726 dbg_info *dbgi = get_irn_dbg_info(node);
2727 ir_node *src_block = get_nodes_block(node);
2728 ir_node *new_block = be_transform_node(src_block);
2729 ir_node *left = get_Cmp_left(node);
2730 ir_node *right = get_Cmp_right(node);
2732 ia32_address_mode_t am;
2733 ia32_address_t *addr = &am.addr;
2735 match_arguments(&am, src_block, left, right, NULL,
2736 match_commutative | match_am);
2738 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2739 addr->mem, am.new_op1, am.new_op2,
2741 set_am_attributes(new_node, &am);
2743 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2745 new_node = fix_mem_proj(new_node, &am);
2751 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2752 * to fold an and into a test node
2754 static int can_fold_test_and(ir_node *node)
2756 const ir_edge_t *edge;
2758 /** we can only have eq and lg projs */
2759 foreach_out_edge(node, edge) {
2760 ir_node *proj = get_edge_src_irn(edge);
2761 pn_Cmp pnc = get_Proj_proj(proj);
2762 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2770 * Generate code for a Cmp.
2772 static ir_node *gen_Cmp(ir_node *node)
2774 ir_graph *irg = current_ir_graph;
2775 dbg_info *dbgi = get_irn_dbg_info(node);
2776 ir_node *block = get_nodes_block(node);
2777 ir_node *new_block = be_transform_node(block);
2778 ir_node *left = get_Cmp_left(node);
2779 ir_node *right = get_Cmp_right(node);
2780 ir_mode *cmp_mode = get_irn_mode(left);
2782 ia32_address_mode_t am;
2783 ia32_address_t *addr = &am.addr;
2786 if(mode_is_float(cmp_mode)) {
2787 if (ia32_cg_config.use_sse2) {
2788 return create_Ucomi(node);
2790 return create_Fucom(node);
2794 assert(ia32_mode_needs_gp_reg(cmp_mode));
2796 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2797 cmp_unsigned = !mode_is_signed(cmp_mode);
2798 if (is_Const_0(right) &&
2800 get_irn_n_edges(left) == 1 &&
2801 can_fold_test_and(node)) {
2802 /* Test(and_left, and_right) */
2803 ir_node *and_left = get_And_left(left);
2804 ir_node *and_right = get_And_right(left);
2805 ir_mode *mode = get_irn_mode(and_left);
2807 match_arguments(&am, block, and_left, and_right, NULL,
2809 match_am | match_8bit_am | match_16bit_am |
2810 match_am_and_immediates | match_immediate |
2811 match_8bit | match_16bit);
2812 if (get_mode_size_bits(mode) == 8) {
2813 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2814 addr->index, addr->mem, am.new_op1,
2815 am.new_op2, am.ins_permuted,
2818 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2819 addr->index, addr->mem, am.new_op1,
2820 am.new_op2, am.ins_permuted, cmp_unsigned);
2823 /* Cmp(left, right) */
2824 match_arguments(&am, block, left, right, NULL,
2825 match_commutative | match_am | match_8bit_am |
2826 match_16bit_am | match_am_and_immediates |
2827 match_immediate | match_8bit | match_16bit);
2828 if (get_mode_size_bits(cmp_mode) == 8) {
2829 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2830 addr->index, addr->mem, am.new_op1,
2831 am.new_op2, am.ins_permuted,
2834 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2835 addr->index, addr->mem, am.new_op1,
2836 am.new_op2, am.ins_permuted, cmp_unsigned);
2839 set_am_attributes(new_node, &am);
2840 set_ia32_ls_mode(new_node, cmp_mode);
2842 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2844 new_node = fix_mem_proj(new_node, &am);
2849 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2852 ir_graph *irg = current_ir_graph;
2853 dbg_info *dbgi = get_irn_dbg_info(node);
2854 ir_node *block = get_nodes_block(node);
2855 ir_node *new_block = be_transform_node(block);
2856 ir_node *val_true = get_Mux_true(node);
2857 ir_node *val_false = get_Mux_false(node);
2859 match_flags_t match_flags;
2860 ia32_address_mode_t am;
2861 ia32_address_t *addr;
2863 assert(ia32_cg_config.use_cmov);
2864 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2868 match_flags = match_commutative | match_am | match_16bit_am |
2871 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2873 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2874 addr->mem, am.new_op1, am.new_op2, new_flags,
2875 am.ins_permuted, pnc);
2876 set_am_attributes(new_node, &am);
2878 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2880 new_node = fix_mem_proj(new_node, &am);
2886 * Creates a ia32 Setcc instruction.
2888 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2889 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2892 ir_graph *irg = current_ir_graph;
2893 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2894 ir_node *nomem = new_NoMem();
2895 ir_mode *mode = get_irn_mode(orig_node);
2898 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2899 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2901 /* we might need to conv the result up */
2902 if (get_mode_size_bits(mode) > 8) {
2903 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2904 nomem, new_node, mode_Bu);
2905 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2912 * Create instruction for an unsigned Difference or Zero.
2914 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2915 ir_graph *irg = current_ir_graph;
2916 ir_mode *mode = get_irn_mode(psi);
2917 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2920 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2921 match_mode_neutral | match_am | match_immediate | match_two_users);
2923 block = get_nodes_block(new_node);
2925 if (is_Proj(new_node)) {
2926 sub = get_Proj_pred(new_node);
2927 assert(is_ia32_Sub(sub));
2930 set_irn_mode(sub, mode_T);
2931 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2933 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2935 dbgi = get_irn_dbg_info(psi);
2936 noreg = ia32_new_NoReg_gp(env_cg);
2937 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2938 nomem = new_NoMem();
2939 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2941 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2942 set_ia32_commutative(new_node);
2947 * Transforms a Mux node into CMov.
2949 * @return The transformed node.
2951 static ir_node *gen_Mux(ir_node *node)
2953 dbg_info *dbgi = get_irn_dbg_info(node);
2954 ir_node *block = get_nodes_block(node);
2955 ir_node *new_block = be_transform_node(block);
2956 ir_node *mux_true = get_Mux_true(node);
2957 ir_node *mux_false = get_Mux_false(node);
2958 ir_node *cond = get_Mux_sel(node);
2959 ir_mode *mode = get_irn_mode(node);
2962 assert(get_irn_mode(cond) == mode_b);
2964 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2965 if (mode_is_float(mode)) {
2966 ir_node *cmp = get_Proj_pred(cond);
2967 ir_node *cmp_left = get_Cmp_left(cmp);
2968 ir_node *cmp_right = get_Cmp_right(cmp);
2969 pn_Cmp pnc = get_Proj_proj(cond);
2971 if (ia32_cg_config.use_sse2) {
2972 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2973 if (cmp_left == mux_true && cmp_right == mux_false) {
2974 /* Mux(a <= b, a, b) => MIN */
2975 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2976 match_commutative | match_am | match_two_users);
2977 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2978 /* Mux(a <= b, b, a) => MAX */
2979 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2980 match_commutative | match_am | match_two_users);
2982 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2983 if (cmp_left == mux_true && cmp_right == mux_false) {
2984 /* Mux(a >= b, a, b) => MAX */
2985 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2986 match_commutative | match_am | match_two_users);
2987 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2988 /* Mux(a >= b, b, a) => MIN */
2989 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2990 match_commutative | match_am | match_two_users);
2994 panic("cannot transform floating point Mux");
3000 assert(ia32_mode_needs_gp_reg(mode));
3002 if (is_Proj(cond)) {
3003 ir_node *cmp = get_Proj_pred(cond);
3005 ir_node *cmp_left = get_Cmp_left(cmp);
3006 ir_node *cmp_right = get_Cmp_right(cmp);
3007 pn_Cmp pnc = get_Proj_proj(cond);
3009 /* check for unsigned Doz first */
3010 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3011 is_Const_0(mux_false) && is_Sub(mux_true) &&
3012 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3013 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3014 return create_Doz(node, cmp_left, cmp_right);
3015 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3016 is_Const_0(mux_true) && is_Sub(mux_false) &&
3017 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3018 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3019 return create_Doz(node, cmp_left, cmp_right);
3024 flags = get_flags_node(cond, &pnc);
3026 if (is_Const(mux_true) && is_Const(mux_false)) {
3027 /* both are const, good */
3028 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3029 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3030 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3031 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3033 /* Not that simple. */
3038 new_node = create_CMov(node, cond, flags, pnc);
3046 * Create a conversion from x87 state register to general purpose.
3048 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3049 ir_node *block = be_transform_node(get_nodes_block(node));
3050 ir_node *op = get_Conv_op(node);
3051 ir_node *new_op = be_transform_node(op);
3052 ia32_code_gen_t *cg = env_cg;
3053 ir_graph *irg = current_ir_graph;
3054 dbg_info *dbgi = get_irn_dbg_info(node);
3055 ir_node *noreg = ia32_new_NoReg_gp(cg);
3056 ir_mode *mode = get_irn_mode(node);
3057 ir_node *fist, *load, *mem;
3059 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3060 set_irn_pinned(fist, op_pin_state_floats);
3061 set_ia32_use_frame(fist);
3062 set_ia32_op_type(fist, ia32_AddrModeD);
3064 assert(get_mode_size_bits(mode) <= 32);
3065 /* exception we can only store signed 32 bit integers, so for unsigned
3066 we store a 64bit (signed) integer and load the lower bits */
3067 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3068 set_ia32_ls_mode(fist, mode_Ls);
3070 set_ia32_ls_mode(fist, mode_Is);
3072 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3075 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3077 set_irn_pinned(load, op_pin_state_floats);
3078 set_ia32_use_frame(load);
3079 set_ia32_op_type(load, ia32_AddrModeS);
3080 set_ia32_ls_mode(load, mode_Is);
3081 if(get_ia32_ls_mode(fist) == mode_Ls) {
3082 ia32_attr_t *attr = get_ia32_attr(load);
3083 attr->data.need_64bit_stackent = 1;
3085 ia32_attr_t *attr = get_ia32_attr(load);
3086 attr->data.need_32bit_stackent = 1;
3088 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3090 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3094 * Creates a x87 strict Conv by placing a Store and a Load
3096 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3098 ir_node *block = get_nodes_block(node);
3099 ir_graph *irg = current_ir_graph;
3100 dbg_info *dbgi = get_irn_dbg_info(node);
3101 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3102 ir_node *nomem = new_NoMem();
3103 ir_node *frame = get_irg_frame(irg);
3104 ir_node *store, *load;
3107 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3109 set_ia32_use_frame(store);
3110 set_ia32_op_type(store, ia32_AddrModeD);
3111 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3113 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3115 set_ia32_use_frame(load);
3116 set_ia32_op_type(load, ia32_AddrModeS);
3117 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3119 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3124 * Create a conversion from general purpose to x87 register
3126 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3127 ir_node *src_block = get_nodes_block(node);
3128 ir_node *block = be_transform_node(src_block);
3129 ir_graph *irg = current_ir_graph;
3130 dbg_info *dbgi = get_irn_dbg_info(node);
3131 ir_node *op = get_Conv_op(node);
3132 ir_node *new_op = NULL;
3136 ir_mode *store_mode;
3142 /* fild can use source AM if the operand is a signed 32bit integer */
3143 if (src_mode == mode_Is) {
3144 ia32_address_mode_t am;
3146 match_arguments(&am, src_block, NULL, op, NULL,
3147 match_am | match_try_am);
3148 if (am.op_type == ia32_AddrModeS) {
3149 ia32_address_t *addr = &am.addr;
3151 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3152 addr->index, addr->mem);
3153 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3156 set_am_attributes(fild, &am);
3157 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3159 fix_mem_proj(fild, &am);
3164 if(new_op == NULL) {
3165 new_op = be_transform_node(op);
3168 noreg = ia32_new_NoReg_gp(env_cg);
3169 nomem = new_NoMem();
3170 mode = get_irn_mode(op);
3172 /* first convert to 32 bit signed if necessary */
3173 src_bits = get_mode_size_bits(src_mode);
3174 if (src_bits == 8) {
3175 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3177 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3179 } else if (src_bits < 32) {
3180 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3182 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3186 assert(get_mode_size_bits(mode) == 32);
3189 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3192 set_ia32_use_frame(store);
3193 set_ia32_op_type(store, ia32_AddrModeD);
3194 set_ia32_ls_mode(store, mode_Iu);
3196 /* exception for 32bit unsigned, do a 64bit spill+load */
3197 if(!mode_is_signed(mode)) {
3200 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3202 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3203 get_irg_frame(irg), noreg, nomem,
3206 set_ia32_use_frame(zero_store);
3207 set_ia32_op_type(zero_store, ia32_AddrModeD);
3208 add_ia32_am_offs_int(zero_store, 4);
3209 set_ia32_ls_mode(zero_store, mode_Iu);
3214 store = new_rd_Sync(dbgi, irg, block, 2, in);
3215 store_mode = mode_Ls;
3217 store_mode = mode_Is;
3221 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3223 set_ia32_use_frame(fild);
3224 set_ia32_op_type(fild, ia32_AddrModeS);
3225 set_ia32_ls_mode(fild, store_mode);
3227 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3233 * Create a conversion from one integer mode into another one
3235 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3236 dbg_info *dbgi, ir_node *block, ir_node *op,
3239 ir_graph *irg = current_ir_graph;
3240 int src_bits = get_mode_size_bits(src_mode);
3241 int tgt_bits = get_mode_size_bits(tgt_mode);
3242 ir_node *new_block = be_transform_node(block);
3244 ir_mode *smaller_mode;
3246 ia32_address_mode_t am;
3247 ia32_address_t *addr = &am.addr;
3250 if (src_bits < tgt_bits) {
3251 smaller_mode = src_mode;
3252 smaller_bits = src_bits;
3254 smaller_mode = tgt_mode;
3255 smaller_bits = tgt_bits;
3258 #ifdef DEBUG_libfirm
3260 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3265 match_arguments(&am, block, NULL, op, NULL,
3266 match_8bit | match_16bit |
3267 match_am | match_8bit_am | match_16bit_am);
3268 if (smaller_bits == 8) {
3269 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3270 addr->index, addr->mem, am.new_op2,
3273 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3274 addr->index, addr->mem, am.new_op2,
3277 set_am_attributes(new_node, &am);
3278 /* match_arguments assume that out-mode = in-mode, this isn't true here
3280 set_ia32_ls_mode(new_node, smaller_mode);
3281 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3282 new_node = fix_mem_proj(new_node, &am);
3287 * Transforms a Conv node.
3289 * @return The created ia32 Conv node
3291 static ir_node *gen_Conv(ir_node *node) {
3292 ir_node *block = get_nodes_block(node);
3293 ir_node *new_block = be_transform_node(block);
3294 ir_node *op = get_Conv_op(node);
3295 ir_node *new_op = NULL;
3296 ir_graph *irg = current_ir_graph;
3297 dbg_info *dbgi = get_irn_dbg_info(node);
3298 ir_mode *src_mode = get_irn_mode(op);
3299 ir_mode *tgt_mode = get_irn_mode(node);
3300 int src_bits = get_mode_size_bits(src_mode);
3301 int tgt_bits = get_mode_size_bits(tgt_mode);
3302 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3303 ir_node *nomem = new_rd_NoMem(irg);
3304 ir_node *res = NULL;
3306 if (src_mode == mode_b) {
3307 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3308 /* nothing to do, we already model bools as 0/1 ints */
3309 return be_transform_node(op);
3312 if (src_mode == tgt_mode) {
3313 if (get_Conv_strict(node)) {
3314 if (ia32_cg_config.use_sse2) {
3315 /* when we are in SSE mode, we can kill all strict no-op conversion */
3316 return be_transform_node(op);
3319 /* this should be optimized already, but who knows... */
3320 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3321 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3322 return be_transform_node(op);
3326 if (mode_is_float(src_mode)) {
3327 new_op = be_transform_node(op);
3328 /* we convert from float ... */
3329 if (mode_is_float(tgt_mode)) {
3330 if(src_mode == mode_E && tgt_mode == mode_D
3331 && !get_Conv_strict(node)) {
3332 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3337 if (ia32_cg_config.use_sse2) {
3338 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3339 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3341 set_ia32_ls_mode(res, tgt_mode);
3343 if(get_Conv_strict(node)) {
3344 res = gen_x87_strict_conv(tgt_mode, new_op);
3345 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3348 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3353 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3354 if (ia32_cg_config.use_sse2) {
3355 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3357 set_ia32_ls_mode(res, src_mode);
3359 return gen_x87_fp_to_gp(node);
3363 /* we convert from int ... */
3364 if (mode_is_float(tgt_mode)) {
3366 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3367 if (ia32_cg_config.use_sse2) {
3368 new_op = be_transform_node(op);
3369 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3371 set_ia32_ls_mode(res, tgt_mode);
3373 res = gen_x87_gp_to_fp(node, src_mode);
3374 if(get_Conv_strict(node)) {
3375 /* The strict-Conv is only necessary, if the int mode has more bits
3376 * than the float mantissa */
3377 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3378 size_t float_mantissa;
3379 /* FIXME There is no way to get the mantissa size of a mode */
3380 switch (get_mode_size_bits(tgt_mode)) {
3381 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3382 case 64: float_mantissa = 52 + 1; break;
3383 case 80: float_mantissa = 64 + 1; break;
3384 default: float_mantissa = 0; break;
3386 if (float_mantissa < int_mantissa) {
3387 res = gen_x87_strict_conv(tgt_mode, res);
3388 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3393 } else if(tgt_mode == mode_b) {
3394 /* mode_b lowering already took care that we only have 0/1 values */
3395 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3396 src_mode, tgt_mode));
3397 return be_transform_node(op);
3400 if (src_bits == tgt_bits) {
3401 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3402 src_mode, tgt_mode));
3403 return be_transform_node(op);
3406 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3414 static ir_node *create_immediate_or_transform(ir_node *node,
3415 char immediate_constraint_type)
3417 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3418 if (new_node == NULL) {
3419 new_node = be_transform_node(node);
3425 * Transforms a FrameAddr into an ia32 Add.
3427 static ir_node *gen_be_FrameAddr(ir_node *node) {
3428 ir_node *block = be_transform_node(get_nodes_block(node));
3429 ir_node *op = be_get_FrameAddr_frame(node);
3430 ir_node *new_op = be_transform_node(op);
3431 ir_graph *irg = current_ir_graph;
3432 dbg_info *dbgi = get_irn_dbg_info(node);
3433 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3436 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3437 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3438 set_ia32_use_frame(new_node);
3440 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3446 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3448 static ir_node *gen_be_Return(ir_node *node) {
3449 ir_graph *irg = current_ir_graph;
3450 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3451 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3452 ir_entity *ent = get_irg_entity(irg);
3453 ir_type *tp = get_entity_type(ent);
3458 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3459 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3462 int pn_ret_val, pn_ret_mem, arity, i;
3464 assert(ret_val != NULL);
3465 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3466 return be_duplicate_node(node);
3469 res_type = get_method_res_type(tp, 0);
3471 if (! is_Primitive_type(res_type)) {
3472 return be_duplicate_node(node);
3475 mode = get_type_mode(res_type);
3476 if (! mode_is_float(mode)) {
3477 return be_duplicate_node(node);
3480 assert(get_method_n_ress(tp) == 1);
3482 pn_ret_val = get_Proj_proj(ret_val);
3483 pn_ret_mem = get_Proj_proj(ret_mem);
3485 /* get the Barrier */
3486 barrier = get_Proj_pred(ret_val);
3488 /* get result input of the Barrier */
3489 ret_val = get_irn_n(barrier, pn_ret_val);
3490 new_ret_val = be_transform_node(ret_val);
3492 /* get memory input of the Barrier */
3493 ret_mem = get_irn_n(barrier, pn_ret_mem);
3494 new_ret_mem = be_transform_node(ret_mem);
3496 frame = get_irg_frame(irg);
3498 dbgi = get_irn_dbg_info(barrier);
3499 block = be_transform_node(get_nodes_block(barrier));
3501 noreg = ia32_new_NoReg_gp(env_cg);
3503 /* store xmm0 onto stack */
3504 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3505 new_ret_mem, new_ret_val);
3506 set_ia32_ls_mode(sse_store, mode);
3507 set_ia32_op_type(sse_store, ia32_AddrModeD);
3508 set_ia32_use_frame(sse_store);
3510 /* load into x87 register */
3511 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3512 set_ia32_op_type(fld, ia32_AddrModeS);
3513 set_ia32_use_frame(fld);
3515 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3516 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3518 /* create a new barrier */
3519 arity = get_irn_arity(barrier);
3520 in = alloca(arity * sizeof(in[0]));
3521 for (i = 0; i < arity; ++i) {
3524 if (i == pn_ret_val) {
3526 } else if (i == pn_ret_mem) {
3529 ir_node *in = get_irn_n(barrier, i);
3530 new_in = be_transform_node(in);
3535 new_barrier = new_ir_node(dbgi, irg, block,
3536 get_irn_op(barrier), get_irn_mode(barrier),
3538 copy_node_attr(barrier, new_barrier);
3539 be_duplicate_deps(barrier, new_barrier);
3540 be_set_transformed_node(barrier, new_barrier);
3541 mark_irn_visited(barrier);
3543 /* transform normally */
3544 return be_duplicate_node(node);
3548 * Transform a be_AddSP into an ia32_SubSP.
3550 static ir_node *gen_be_AddSP(ir_node *node)
3552 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3553 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3555 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
3559 * Transform a be_SubSP into an ia32_AddSP
3561 static ir_node *gen_be_SubSP(ir_node *node)
3563 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3564 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3566 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
3570 * Change some phi modes
3572 static ir_node *gen_Phi(ir_node *node) {
3573 ir_node *block = be_transform_node(get_nodes_block(node));
3574 ir_graph *irg = current_ir_graph;
3575 dbg_info *dbgi = get_irn_dbg_info(node);
3576 ir_mode *mode = get_irn_mode(node);
3579 if(ia32_mode_needs_gp_reg(mode)) {
3580 /* we shouldn't have any 64bit stuff around anymore */
3581 assert(get_mode_size_bits(mode) <= 32);
3582 /* all integer operations are on 32bit registers now */
3584 } else if(mode_is_float(mode)) {
3585 if (ia32_cg_config.use_sse2) {
3592 /* phi nodes allow loops, so we use the old arguments for now
3593 * and fix this later */
3594 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3595 get_irn_in(node) + 1);
3596 copy_node_attr(node, phi);
3597 be_duplicate_deps(node, phi);
3599 be_set_transformed_node(node, phi);
3600 be_enqueue_preds(node);
3608 static ir_node *gen_IJmp(ir_node *node)
3610 ir_node *block = get_nodes_block(node);
3611 ir_node *new_block = be_transform_node(block);
3612 dbg_info *dbgi = get_irn_dbg_info(node);
3613 ir_node *op = get_IJmp_target(node);
3615 ia32_address_mode_t am;
3616 ia32_address_t *addr = &am.addr;
3618 assert(get_irn_mode(op) == mode_P);
3620 match_arguments(&am, block, NULL, op, NULL,
3621 match_am | match_8bit_am | match_16bit_am |
3622 match_immediate | match_8bit | match_16bit);
3624 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3625 addr->base, addr->index, addr->mem,
3627 set_am_attributes(new_node, &am);
3628 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3630 new_node = fix_mem_proj(new_node, &am);
3636 * Transform a Bound node.
3638 static ir_node *gen_Bound(ir_node *node)
3641 ir_node *lower = get_Bound_lower(node);
3642 dbg_info *dbgi = get_irn_dbg_info(node);
3644 if (is_Const_0(lower)) {
3645 /* typical case for Java */
3646 ir_node *sub, *res, *flags, *block;
3647 ir_graph *irg = current_ir_graph;
3649 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3650 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3652 block = get_nodes_block(res);
3653 if (! is_Proj(res)) {
3655 set_irn_mode(sub, mode_T);
3656 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3658 sub = get_Proj_pred(res);
3660 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3661 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3662 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3664 panic("generic Bound not supported in ia32 Backend");
3670 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3673 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3674 ir_node *val, ir_node *mem);
3677 * Transforms a lowered Load into a "real" one.
3679 static ir_node *gen_lowered_Load(ir_node *node, construct_load_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 *mem = get_irn_n(node, 1);
3685 ir_node *new_mem = be_transform_node(mem);
3686 ir_graph *irg = current_ir_graph;
3687 dbg_info *dbgi = get_irn_dbg_info(node);
3688 ir_mode *mode = get_ia32_ls_mode(node);
3689 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3692 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
3694 set_ia32_op_type(new_op, ia32_AddrModeS);
3695 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
3696 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
3697 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
3698 if (is_ia32_am_sc_sign(node))
3699 set_ia32_am_sc_sign(new_op);
3700 set_ia32_ls_mode(new_op, mode);
3701 if (is_ia32_use_frame(node)) {
3702 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3703 set_ia32_use_frame(new_op);
3706 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3712 * Transforms a lowered Store into a "real" one.
3714 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
3716 ir_node *block = be_transform_node(get_nodes_block(node));
3717 ir_node *ptr = get_irn_n(node, 0);
3718 ir_node *new_ptr = be_transform_node(ptr);
3719 ir_node *val = get_irn_n(node, 1);
3720 ir_node *new_val = be_transform_node(val);
3721 ir_node *mem = get_irn_n(node, 2);
3722 ir_node *new_mem = be_transform_node(mem);
3723 ir_graph *irg = current_ir_graph;
3724 dbg_info *dbgi = get_irn_dbg_info(node);
3725 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3726 ir_mode *mode = get_ia32_ls_mode(node);
3730 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
3732 am_offs = get_ia32_am_offs_int(node);
3733 add_ia32_am_offs_int(new_op, am_offs);
3735 set_ia32_op_type(new_op, ia32_AddrModeD);
3736 set_ia32_ls_mode(new_op, mode);
3737 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3738 set_ia32_use_frame(new_op);
3740 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3745 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3747 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3748 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3750 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3751 match_immediate | match_mode_neutral);
3754 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3756 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3757 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3758 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3762 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3764 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3765 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3766 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3770 static ir_node *gen_ia32_l_Add(ir_node *node) {
3771 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3772 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3773 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3774 match_commutative | match_am | match_immediate |
3775 match_mode_neutral);
3777 if(is_Proj(lowered)) {
3778 lowered = get_Proj_pred(lowered);
3780 assert(is_ia32_Add(lowered));
3781 set_irn_mode(lowered, mode_T);
3787 static ir_node *gen_ia32_l_Adc(ir_node *node)
3789 return gen_binop_flags(node, new_rd_ia32_Adc,
3790 match_commutative | match_am | match_immediate |
3791 match_mode_neutral);
3795 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
3797 * @param node The node to transform
3798 * @return the created ia32 vfild node
3800 static ir_node *gen_ia32_l_vfild(ir_node *node) {
3801 return gen_lowered_Load(node, new_rd_ia32_vfild);
3805 * Transforms an ia32_l_Load into a "real" ia32_Load node
3807 * @param node The node to transform
3808 * @return the created ia32 Load node
3810 static ir_node *gen_ia32_l_Load(ir_node *node) {
3811 return gen_lowered_Load(node, new_rd_ia32_Load);
3815 * Transforms an ia32_l_Store into a "real" ia32_Store node
3817 * @param node The node to transform
3818 * @return the created ia32 Store node
3820 static ir_node *gen_ia32_l_Store(ir_node *node) {
3821 return gen_lowered_Store(node, new_rd_ia32_Store);
3825 * Transforms a l_vfist into a "real" vfist node.
3827 * @param node The node to transform
3828 * @return the created ia32 vfist node
3830 static ir_node *gen_ia32_l_vfist(ir_node *node) {
3831 ir_node *block = be_transform_node(get_nodes_block(node));
3832 ir_node *ptr = get_irn_n(node, 0);
3833 ir_node *new_ptr = be_transform_node(ptr);
3834 ir_node *val = get_irn_n(node, 1);
3835 ir_node *new_val = be_transform_node(val);
3836 ir_node *mem = get_irn_n(node, 2);
3837 ir_node *new_mem = be_transform_node(mem);
3838 ir_graph *irg = current_ir_graph;
3839 dbg_info *dbgi = get_irn_dbg_info(node);
3840 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3841 ir_mode *mode = get_ia32_ls_mode(node);
3842 ir_node *memres, *fist;
3845 memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
3846 am_offs = get_ia32_am_offs_int(node);
3847 add_ia32_am_offs_int(fist, am_offs);
3849 set_ia32_op_type(fist, ia32_AddrModeD);
3850 set_ia32_ls_mode(fist, mode);
3851 set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
3852 set_ia32_use_frame(fist);
3854 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3860 * Transforms a l_MulS into a "real" MulS node.
3862 * @return the created ia32 Mul node
3864 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3865 ir_node *left = get_binop_left(node);
3866 ir_node *right = get_binop_right(node);
3868 return gen_binop(node, left, right, new_rd_ia32_Mul,
3869 match_commutative | match_am | match_mode_neutral);
3873 * Transforms a l_IMulS into a "real" IMul1OPS node.
3875 * @return the created ia32 IMul1OP node
3877 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3878 ir_node *left = get_binop_left(node);
3879 ir_node *right = get_binop_right(node);
3881 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3882 match_commutative | match_am | match_mode_neutral);
3885 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3886 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3887 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3888 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3889 match_am | match_immediate | match_mode_neutral);
3891 if(is_Proj(lowered)) {
3892 lowered = get_Proj_pred(lowered);
3894 assert(is_ia32_Sub(lowered));
3895 set_irn_mode(lowered, mode_T);
3901 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3902 return gen_binop_flags(node, new_rd_ia32_Sbb,
3903 match_am | match_immediate | match_mode_neutral);
3907 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3908 * op1 - target to be shifted
3909 * op2 - contains bits to be shifted into target
3911 * Only op3 can be an immediate.
3913 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3914 ir_node *low, ir_node *count)
3916 ir_node *block = get_nodes_block(node);
3917 ir_node *new_block = be_transform_node(block);
3918 ir_graph *irg = current_ir_graph;
3919 dbg_info *dbgi = get_irn_dbg_info(node);
3920 ir_node *new_high = be_transform_node(high);
3921 ir_node *new_low = be_transform_node(low);
3925 /* the shift amount can be any mode that is bigger than 5 bits, since all
3926 * other bits are ignored anyway */
3927 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
3928 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3929 count = get_Conv_op(count);
3931 new_count = create_immediate_or_transform(count, 0);
3933 if (is_ia32_l_ShlD(node)) {
3934 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3937 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3940 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3945 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3947 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3948 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3949 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3950 return gen_lowered_64bit_shifts(node, high, low, count);
3953 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3955 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3956 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3957 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3958 return gen_lowered_64bit_shifts(node, high, low, count);
3961 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3962 ir_node *src_block = get_nodes_block(node);
3963 ir_node *block = be_transform_node(src_block);
3964 ir_graph *irg = current_ir_graph;
3965 dbg_info *dbgi = get_irn_dbg_info(node);
3966 ir_node *frame = get_irg_frame(irg);
3967 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3968 ir_node *nomem = new_NoMem();
3969 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3970 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3971 ir_node *new_val_low = be_transform_node(val_low);
3972 ir_node *new_val_high = be_transform_node(val_high);
3977 ir_node *store_high;
3979 if(!mode_is_signed(get_irn_mode(val_high))) {
3980 panic("unsigned long long -> float not supported yet (%+F)", node);
3984 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3986 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3988 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3989 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3991 set_ia32_use_frame(store_low);
3992 set_ia32_use_frame(store_high);
3993 set_ia32_op_type(store_low, ia32_AddrModeD);
3994 set_ia32_op_type(store_high, ia32_AddrModeD);
3995 set_ia32_ls_mode(store_low, mode_Iu);
3996 set_ia32_ls_mode(store_high, mode_Is);
3997 add_ia32_am_offs_int(store_high, 4);
4001 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4004 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4006 set_ia32_use_frame(fild);
4007 set_ia32_op_type(fild, ia32_AddrModeS);
4008 set_ia32_ls_mode(fild, mode_Ls);
4010 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4012 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4015 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4016 ir_node *src_block = get_nodes_block(node);
4017 ir_node *block = be_transform_node(src_block);
4018 ir_graph *irg = current_ir_graph;
4019 dbg_info *dbgi = get_irn_dbg_info(node);
4020 ir_node *frame = get_irg_frame(irg);
4021 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4022 ir_node *nomem = new_NoMem();
4023 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4024 ir_node *new_val = be_transform_node(val);
4025 ir_node *fist, *mem;
4027 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4028 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4029 set_ia32_use_frame(fist);
4030 set_ia32_op_type(fist, ia32_AddrModeD);
4031 set_ia32_ls_mode(fist, mode_Ls);
4037 * the BAD transformer.
4039 static ir_node *bad_transform(ir_node *node) {
4040 panic("No transform function for %+F available.\n", node);
4044 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4045 ir_graph *irg = current_ir_graph;
4046 ir_node *block = be_transform_node(get_nodes_block(node));
4047 ir_node *pred = get_Proj_pred(node);
4048 ir_node *new_pred = be_transform_node(pred);
4049 ir_node *frame = get_irg_frame(irg);
4050 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4051 dbg_info *dbgi = get_irn_dbg_info(node);
4052 long pn = get_Proj_proj(node);
4057 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4058 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4059 set_ia32_use_frame(load);
4060 set_ia32_op_type(load, ia32_AddrModeS);
4061 set_ia32_ls_mode(load, mode_Iu);
4062 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4063 * 32 bit from it with this particular load */
4064 attr = get_ia32_attr(load);
4065 attr->data.need_64bit_stackent = 1;
4067 if (pn == pn_ia32_l_FloattoLL_res_high) {
4068 add_ia32_am_offs_int(load, 4);
4070 assert(pn == pn_ia32_l_FloattoLL_res_low);
4073 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4079 * Transform the Projs of an AddSP.
4081 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4082 ir_node *block = be_transform_node(get_nodes_block(node));
4083 ir_node *pred = get_Proj_pred(node);
4084 ir_node *new_pred = be_transform_node(pred);
4085 ir_graph *irg = current_ir_graph;
4086 dbg_info *dbgi = get_irn_dbg_info(node);
4087 long proj = get_Proj_proj(node);
4089 if (proj == pn_be_AddSP_sp) {
4090 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4091 pn_ia32_SubSP_stack);
4092 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4094 } else if(proj == pn_be_AddSP_res) {
4095 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4096 pn_ia32_SubSP_addr);
4097 } else if (proj == pn_be_AddSP_M) {
4098 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4102 return new_rd_Unknown(irg, get_irn_mode(node));
4106 * Transform the Projs of a SubSP.
4108 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4109 ir_node *block = be_transform_node(get_nodes_block(node));
4110 ir_node *pred = get_Proj_pred(node);
4111 ir_node *new_pred = be_transform_node(pred);
4112 ir_graph *irg = current_ir_graph;
4113 dbg_info *dbgi = get_irn_dbg_info(node);
4114 long proj = get_Proj_proj(node);
4116 if (proj == pn_be_SubSP_sp) {
4117 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4118 pn_ia32_AddSP_stack);
4119 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4121 } else if (proj == pn_be_SubSP_M) {
4122 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4126 return new_rd_Unknown(irg, get_irn_mode(node));
4130 * Transform and renumber the Projs from a Load.
4132 static ir_node *gen_Proj_Load(ir_node *node) {
4134 ir_node *block = be_transform_node(get_nodes_block(node));
4135 ir_node *pred = get_Proj_pred(node);
4136 ir_graph *irg = current_ir_graph;
4137 dbg_info *dbgi = get_irn_dbg_info(node);
4138 long proj = get_Proj_proj(node);
4140 /* loads might be part of source address mode matches, so we don't
4141 * transform the ProjMs yet (with the exception of loads whose result is
4144 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4147 /* this is needed, because sometimes we have loops that are only
4148 reachable through the ProjM */
4149 be_enqueue_preds(node);
4150 /* do it in 2 steps, to silence firm verifier */
4151 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4152 set_Proj_proj(res, pn_ia32_mem);
4156 /* renumber the proj */
4157 new_pred = be_transform_node(pred);
4158 if (is_ia32_Load(new_pred)) {
4161 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4163 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4164 case pn_Load_X_regular:
4165 return new_rd_Jmp(dbgi, irg, block);
4166 case pn_Load_X_except:
4167 /* This Load might raise an exception. Mark it. */
4168 set_ia32_exc_label(new_pred, 1);
4169 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4173 } else if (is_ia32_Conv_I2I(new_pred) ||
4174 is_ia32_Conv_I2I8Bit(new_pred)) {
4175 set_irn_mode(new_pred, mode_T);
4176 if (proj == pn_Load_res) {
4177 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4178 } else if (proj == pn_Load_M) {
4179 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4181 } else if (is_ia32_xLoad(new_pred)) {
4184 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4186 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4187 case pn_Load_X_regular:
4188 return new_rd_Jmp(dbgi, irg, block);
4189 case pn_Load_X_except:
4190 /* This Load might raise an exception. Mark it. */
4191 set_ia32_exc_label(new_pred, 1);
4192 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4196 } else if (is_ia32_vfld(new_pred)) {
4199 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4201 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4202 case pn_Load_X_regular:
4203 return new_rd_Jmp(dbgi, irg, block);
4204 case pn_Load_X_except:
4205 /* This Load might raise an exception. Mark it. */
4206 set_ia32_exc_label(new_pred, 1);
4207 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4212 /* can happen for ProJMs when source address mode happened for the
4215 /* however it should not be the result proj, as that would mean the
4216 load had multiple users and should not have been used for
4218 if (proj != pn_Load_M) {
4219 panic("internal error: transformed node not a Load");
4221 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4225 return new_rd_Unknown(irg, get_irn_mode(node));
4229 * Transform and renumber the Projs from a DivMod like instruction.
4231 static ir_node *gen_Proj_DivMod(ir_node *node) {
4232 ir_node *block = be_transform_node(get_nodes_block(node));
4233 ir_node *pred = get_Proj_pred(node);
4234 ir_node *new_pred = be_transform_node(pred);
4235 ir_graph *irg = current_ir_graph;
4236 dbg_info *dbgi = get_irn_dbg_info(node);
4237 ir_mode *mode = get_irn_mode(node);
4238 long proj = get_Proj_proj(node);
4240 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4242 switch (get_irn_opcode(pred)) {
4246 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4248 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4249 case pn_Div_X_regular:
4250 return new_rd_Jmp(dbgi, irg, block);
4251 case pn_Div_X_except:
4252 set_ia32_exc_label(new_pred, 1);
4253 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4261 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4263 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4264 case pn_Mod_X_except:
4265 set_ia32_exc_label(new_pred, 1);
4266 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4274 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4275 case pn_DivMod_res_div:
4276 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4277 case pn_DivMod_res_mod:
4278 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4279 case pn_DivMod_X_regular:
4280 return new_rd_Jmp(dbgi, irg, block);
4281 case pn_DivMod_X_except:
4282 set_ia32_exc_label(new_pred, 1);
4283 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4293 return new_rd_Unknown(irg, mode);
4297 * Transform and renumber the Projs from a CopyB.
4299 static ir_node *gen_Proj_CopyB(ir_node *node) {
4300 ir_node *block = be_transform_node(get_nodes_block(node));
4301 ir_node *pred = get_Proj_pred(node);
4302 ir_node *new_pred = be_transform_node(pred);
4303 ir_graph *irg = current_ir_graph;
4304 dbg_info *dbgi = get_irn_dbg_info(node);
4305 ir_mode *mode = get_irn_mode(node);
4306 long proj = get_Proj_proj(node);
4309 case pn_CopyB_M_regular:
4310 if (is_ia32_CopyB_i(new_pred)) {
4311 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4312 } else if (is_ia32_CopyB(new_pred)) {
4313 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4321 return new_rd_Unknown(irg, mode);
4325 * Transform and renumber the Projs from a Quot.
4327 static ir_node *gen_Proj_Quot(ir_node *node) {
4328 ir_node *block = be_transform_node(get_nodes_block(node));
4329 ir_node *pred = get_Proj_pred(node);
4330 ir_node *new_pred = be_transform_node(pred);
4331 ir_graph *irg = current_ir_graph;
4332 dbg_info *dbgi = get_irn_dbg_info(node);
4333 ir_mode *mode = get_irn_mode(node);
4334 long proj = get_Proj_proj(node);
4338 if (is_ia32_xDiv(new_pred)) {
4339 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4340 } else if (is_ia32_vfdiv(new_pred)) {
4341 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4345 if (is_ia32_xDiv(new_pred)) {
4346 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4347 } else if (is_ia32_vfdiv(new_pred)) {
4348 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4351 case pn_Quot_X_regular:
4352 case pn_Quot_X_except:
4358 return new_rd_Unknown(irg, mode);
4362 * Transform the Thread Local Storage Proj.
4364 static ir_node *gen_Proj_tls(ir_node *node) {
4365 ir_node *block = be_transform_node(get_nodes_block(node));
4366 ir_graph *irg = current_ir_graph;
4367 dbg_info *dbgi = NULL;
4368 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4373 static ir_node *gen_be_Call(ir_node *node) {
4374 ir_node *res = be_duplicate_node(node);
4375 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4380 static ir_node *gen_be_IncSP(ir_node *node) {
4381 ir_node *res = be_duplicate_node(node);
4382 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4388 * Transform the Projs from a be_Call.
4390 static ir_node *gen_Proj_be_Call(ir_node *node) {
4391 ir_node *block = be_transform_node(get_nodes_block(node));
4392 ir_node *call = get_Proj_pred(node);
4393 ir_node *new_call = be_transform_node(call);
4394 ir_graph *irg = current_ir_graph;
4395 dbg_info *dbgi = get_irn_dbg_info(node);
4396 ir_type *method_type = be_Call_get_type(call);
4397 int n_res = get_method_n_ress(method_type);
4398 long proj = get_Proj_proj(node);
4399 ir_mode *mode = get_irn_mode(node);
4401 const arch_register_class_t *cls;
4403 /* The following is kinda tricky: If we're using SSE, then we have to
4404 * move the result value of the call in floating point registers to an
4405 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4406 * after the call, we have to make sure to correctly make the
4407 * MemProj and the result Proj use these 2 nodes
4409 if (proj == pn_be_Call_M_regular) {
4410 // get new node for result, are we doing the sse load/store hack?
4411 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4412 ir_node *call_res_new;
4413 ir_node *call_res_pred = NULL;
4415 if (call_res != NULL) {
4416 call_res_new = be_transform_node(call_res);
4417 call_res_pred = get_Proj_pred(call_res_new);
4420 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4421 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4422 pn_be_Call_M_regular);
4424 assert(is_ia32_xLoad(call_res_pred));
4425 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4429 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4430 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4432 ir_node *frame = get_irg_frame(irg);
4433 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4435 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4438 /* in case there is no memory output: create one to serialize the copy
4440 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4441 pn_be_Call_M_regular);
4442 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4443 pn_be_Call_first_res);
4445 /* store st(0) onto stack */
4446 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4448 set_ia32_op_type(fstp, ia32_AddrModeD);
4449 set_ia32_use_frame(fstp);
4451 /* load into SSE register */
4452 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4454 set_ia32_op_type(sse_load, ia32_AddrModeS);
4455 set_ia32_use_frame(sse_load);
4457 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4463 /* transform call modes */
4464 if (mode_is_data(mode)) {
4465 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4469 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4473 * Transform the Projs from a Cmp.
4475 static ir_node *gen_Proj_Cmp(ir_node *node)
4477 /* this probably means not all mode_b nodes were lowered... */
4478 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4483 * Transform the Projs from a Bound.
4485 static ir_node *gen_Proj_Bound(ir_node *node)
4487 ir_node *new_node, *block;
4488 ir_node *pred = get_Proj_pred(node);
4490 switch (get_Proj_proj(node)) {
4492 return be_transform_node(get_Bound_mem(pred));
4493 case pn_Bound_X_regular:
4494 new_node = be_transform_node(pred);
4495 block = get_nodes_block(new_node);
4496 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4497 case pn_Bound_X_except:
4498 new_node = be_transform_node(pred);
4499 block = get_nodes_block(new_node);
4500 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4502 return be_transform_node(get_Bound_index(pred));
4504 panic("unsupported Proj from Bound");
4508 static ir_node *gen_Proj_ASM(ir_node *node)
4514 if (get_irn_mode(node) != mode_M)
4515 return be_duplicate_node(node);
4517 pred = get_Proj_pred(node);
4518 new_pred = be_transform_node(pred);
4519 block = get_nodes_block(new_pred);
4520 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4521 get_ia32_n_res(new_pred) + 1);
4525 * Transform and potentially renumber Proj nodes.
4527 static ir_node *gen_Proj(ir_node *node) {
4528 ir_node *pred = get_Proj_pred(node);
4531 switch (get_irn_opcode(pred)) {
4533 proj = get_Proj_proj(node);
4534 if (proj == pn_Store_M) {
4535 return be_transform_node(pred);
4538 return new_r_Bad(current_ir_graph);
4541 return gen_Proj_Load(node);
4543 return gen_Proj_ASM(node);
4547 return gen_Proj_DivMod(node);
4549 return gen_Proj_CopyB(node);
4551 return gen_Proj_Quot(node);
4553 return gen_Proj_be_SubSP(node);
4555 return gen_Proj_be_AddSP(node);
4557 return gen_Proj_be_Call(node);
4559 return gen_Proj_Cmp(node);
4561 return gen_Proj_Bound(node);
4563 proj = get_Proj_proj(node);
4564 if (proj == pn_Start_X_initial_exec) {
4565 ir_node *block = get_nodes_block(pred);
4566 dbg_info *dbgi = get_irn_dbg_info(node);
4569 /* we exchange the ProjX with a jump */
4570 block = be_transform_node(block);
4571 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
4574 if (node == be_get_old_anchor(anchor_tls)) {
4575 return gen_Proj_tls(node);
4580 if (is_ia32_l_FloattoLL(pred)) {
4581 return gen_Proj_l_FloattoLL(node);
4583 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4587 ir_mode *mode = get_irn_mode(node);
4588 if (ia32_mode_needs_gp_reg(mode)) {
4589 ir_node *new_pred = be_transform_node(pred);
4590 ir_node *block = be_transform_node(get_nodes_block(node));
4591 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4592 mode_Iu, get_Proj_proj(node));
4593 #ifdef DEBUG_libfirm
4594 new_proj->node_nr = node->node_nr;
4600 return be_duplicate_node(node);
4604 * Enters all transform functions into the generic pointer
4606 static void register_transformers(void)
4610 /* first clear the generic function pointer for all ops */
4611 clear_irp_opcodes_generic_func();
4613 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4614 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4652 /* transform ops from intrinsic lowering */
4668 GEN(ia32_l_LLtoFloat);
4669 GEN(ia32_l_FloattoLL);
4675 /* we should never see these nodes */
4690 /* handle generic backend nodes */
4699 op_Mulh = get_op_Mulh();
4708 * Pre-transform all unknown and noreg nodes.
4710 static void ia32_pretransform_node(void *arch_cg) {
4711 ia32_code_gen_t *cg = arch_cg;
4713 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4714 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4715 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4716 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4717 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4718 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4723 * Walker, checks if all ia32 nodes producing more than one result have
4724 * its Projs, otherwise creates new Projs and keep them using a be_Keep node.
4726 static void add_missing_keep_walker(ir_node *node, void *data)
4729 unsigned found_projs = 0;
4730 const ir_edge_t *edge;
4731 ir_mode *mode = get_irn_mode(node);
4736 if(!is_ia32_irn(node))
4739 n_outs = get_ia32_n_res(node);
4742 if(is_ia32_SwitchJmp(node))
4745 assert(n_outs < (int) sizeof(unsigned) * 8);
4746 foreach_out_edge(node, edge) {
4747 ir_node *proj = get_edge_src_irn(edge);
4748 int pn = get_Proj_proj(proj);
4750 if (get_irn_mode(proj) == mode_M)
4753 assert(pn < n_outs);
4754 found_projs |= 1 << pn;
4758 /* are keeps missing? */
4760 for(i = 0; i < n_outs; ++i) {
4763 const arch_register_req_t *req;
4764 const arch_register_class_t *cls;
4766 if(found_projs & (1 << i)) {
4770 req = get_ia32_out_req(node, i);
4775 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4779 block = get_nodes_block(node);
4780 in[0] = new_r_Proj(current_ir_graph, block, node,
4781 arch_register_class_mode(cls), i);
4782 if(last_keep != NULL) {
4783 be_Keep_add_node(last_keep, cls, in[0]);
4785 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4786 if(sched_is_scheduled(node)) {
4787 sched_add_after(node, last_keep);
4794 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4797 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4799 ir_graph *irg = be_get_birg_irg(cg->birg);
4800 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4803 /* do the transformation */
4804 void ia32_transform_graph(ia32_code_gen_t *cg) {
4806 ir_graph *irg = cg->irg;
4808 register_transformers();
4810 initial_fpcw = NULL;
4812 BE_TIMER_PUSH(t_heights);
4813 heights = heights_new(irg);
4814 BE_TIMER_POP(t_heights);
4815 ia32_calculate_non_address_mode_nodes(cg->birg);
4817 /* the transform phase is not safe for CSE (yet) because several nodes get
4818 * attributes set after their creation */
4819 cse_last = get_opt_cse();
4822 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4824 set_opt_cse(cse_last);
4826 ia32_free_non_address_mode_nodes();
4827 heights_free(heights);
4831 void ia32_init_transform(void)
4833 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");