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
34 #include "irgraph_t.h"
39 #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"
79 #define ULL_BIAS "18446744073709551616"
81 #define TP_SFP_SIGN "ia32_sfp_sign"
82 #define TP_DFP_SIGN "ia32_dfp_sign"
83 #define TP_SFP_ABS "ia32_sfp_abs"
84 #define TP_DFP_ABS "ia32_dfp_abs"
85 #define TP_ULL_BIAS "ia32_ull_bias"
87 #define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
88 #define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
89 #define ENT_SFP_ABS ".LC_ia32_sfp_abs"
90 #define ENT_DFP_ABS ".LC_ia32_dfp_abs"
91 #define ENT_ULL_BIAS ".LC_ia32_ull_bias"
93 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
94 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
96 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
98 static ir_node *initial_fpcw = NULL;
100 extern ir_op *get_op_Mulh(void);
102 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
103 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
106 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
107 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
110 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
111 ir_node *op1, ir_node *op2);
113 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
114 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
116 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
117 ir_node *base, ir_node *index, ir_node *mem);
119 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
120 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
123 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
125 static ir_node *create_immediate_or_transform(ir_node *node,
126 char immediate_constraint_type);
128 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
129 dbg_info *dbgi, ir_node *block,
130 ir_node *op, ir_node *orig_node);
132 /** Return non-zero is a node represents the 0 constant. */
133 static bool 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 bool is_Const_1(ir_node *node)
141 return is_Const(node) && is_Const_one(node);
144 /** Return non-zero is a node represents the -1 constant. */
145 static bool is_Const_Minus_1(ir_node *node)
147 return is_Const(node) && is_Const_all_one(node);
151 * returns true if constant can be created with a simple float command
153 static bool is_simple_x87_Const(ir_node *node)
155 tarval *tv = get_Const_tarval(node);
156 if (tarval_is_null(tv) || tarval_is_one(tv))
159 /* TODO: match all the other float constants */
164 * returns true if constant can be created with a simple float command
166 static bool is_simple_sse_Const(ir_node *node)
168 tarval *tv = get_Const_tarval(node);
169 ir_mode *mode = get_tarval_mode(tv);
174 if (tarval_is_null(tv) || tarval_is_one(tv))
177 if (mode == mode_D) {
178 unsigned val = get_tarval_sub_bits(tv, 0) |
179 (get_tarval_sub_bits(tv, 1) << 8) |
180 (get_tarval_sub_bits(tv, 2) << 16) |
181 (get_tarval_sub_bits(tv, 3) << 24);
183 /* lower 32bit are zero, really a 32bit constant */
187 /* TODO: match all the other float constants */
192 * Transforms a Const.
194 static ir_node *gen_Const(ir_node *node)
196 ir_node *old_block = get_nodes_block(node);
197 ir_node *block = be_transform_node(old_block);
198 dbg_info *dbgi = get_irn_dbg_info(node);
199 ir_mode *mode = get_irn_mode(node);
201 assert(is_Const(node));
203 if (mode_is_float(mode)) {
205 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
206 ir_node *nomem = new_NoMem();
210 if (ia32_cg_config.use_sse2) {
211 tarval *tv = get_Const_tarval(node);
212 if (tarval_is_null(tv)) {
213 load = new_bd_ia32_xZero(dbgi, block);
214 set_ia32_ls_mode(load, mode);
216 } else if (tarval_is_one(tv)) {
217 int cnst = mode == mode_F ? 26 : 55;
218 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
219 ir_node *imm2 = create_Immediate(NULL, 0, 2);
220 ir_node *pslld, *psrld;
222 load = new_bd_ia32_xAllOnes(dbgi, block);
223 set_ia32_ls_mode(load, mode);
224 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
225 set_ia32_ls_mode(pslld, mode);
226 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
227 set_ia32_ls_mode(psrld, mode);
229 } else if (mode == mode_F) {
230 /* we can place any 32bit constant by using a movd gp, sse */
231 unsigned val = get_tarval_sub_bits(tv, 0) |
232 (get_tarval_sub_bits(tv, 1) << 8) |
233 (get_tarval_sub_bits(tv, 2) << 16) |
234 (get_tarval_sub_bits(tv, 3) << 24);
235 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
236 load = new_bd_ia32_xMovd(dbgi, block, cnst);
237 set_ia32_ls_mode(load, mode);
240 if (mode == mode_D) {
241 unsigned val = get_tarval_sub_bits(tv, 0) |
242 (get_tarval_sub_bits(tv, 1) << 8) |
243 (get_tarval_sub_bits(tv, 2) << 16) |
244 (get_tarval_sub_bits(tv, 3) << 24);
246 ir_node *imm32 = create_Immediate(NULL, 0, 32);
247 ir_node *cnst, *psllq;
249 /* fine, lower 32bit are zero, produce 32bit value */
250 val = get_tarval_sub_bits(tv, 4) |
251 (get_tarval_sub_bits(tv, 5) << 8) |
252 (get_tarval_sub_bits(tv, 6) << 16) |
253 (get_tarval_sub_bits(tv, 7) << 24);
254 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
255 load = new_bd_ia32_xMovd(dbgi, block, cnst);
256 set_ia32_ls_mode(load, mode);
257 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
258 set_ia32_ls_mode(psllq, mode);
263 floatent = create_float_const_entity(node);
265 load = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem,
267 set_ia32_op_type(load, ia32_AddrModeS);
268 set_ia32_am_sc(load, floatent);
269 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
270 res = new_r_Proj(current_ir_graph, block, load, mode_xmm, pn_ia32_xLoad_res);
273 if (is_Const_null(node)) {
274 load = new_bd_ia32_vfldz(dbgi, block);
276 set_ia32_ls_mode(load, mode);
277 } else if (is_Const_one(node)) {
278 load = new_bd_ia32_vfld1(dbgi, block);
280 set_ia32_ls_mode(load, mode);
282 floatent = create_float_const_entity(node);
284 load = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode);
285 set_ia32_op_type(load, ia32_AddrModeS);
286 set_ia32_am_sc(load, floatent);
287 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
288 res = new_r_Proj(current_ir_graph, block, load, mode_vfp, pn_ia32_vfld_res);
289 /* take the mode from the entity */
290 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
294 SET_IA32_ORIG_NODE(load, node);
296 be_dep_on_frame(load);
298 } else { /* non-float mode */
300 tarval *tv = get_Const_tarval(node);
303 tv = tarval_convert_to(tv, mode_Iu);
305 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
307 panic("couldn't convert constant tarval (%+F)", node);
309 val = get_tarval_long(tv);
311 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
312 SET_IA32_ORIG_NODE(cnst, node);
314 be_dep_on_frame(cnst);
320 * Transforms a SymConst.
322 static ir_node *gen_SymConst(ir_node *node)
324 ir_node *old_block = get_nodes_block(node);
325 ir_node *block = be_transform_node(old_block);
326 dbg_info *dbgi = get_irn_dbg_info(node);
327 ir_mode *mode = get_irn_mode(node);
330 if (mode_is_float(mode)) {
331 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
332 ir_node *nomem = new_NoMem();
334 if (ia32_cg_config.use_sse2)
335 cnst = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem, mode_E);
337 cnst = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode_E);
338 set_ia32_am_sc(cnst, get_SymConst_entity(node));
339 set_ia32_use_frame(cnst);
343 if (get_SymConst_kind(node) != symconst_addr_ent) {
344 panic("backend only support symconst_addr_ent (at %+F)", node);
346 entity = get_SymConst_entity(node);
347 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0);
350 SET_IA32_ORIG_NODE(cnst, node);
352 be_dep_on_frame(cnst);
356 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
357 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
359 static const struct {
361 const char *ent_name;
362 const char *cnst_str;
365 } names [ia32_known_const_max] = {
366 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
367 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
368 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
369 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
370 { TP_ULL_BIAS, ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
372 static ir_entity *ent_cache[ia32_known_const_max];
374 const char *tp_name, *ent_name, *cnst_str;
380 ent_name = names[kct].ent_name;
381 if (! ent_cache[kct]) {
382 tp_name = names[kct].tp_name;
383 cnst_str = names[kct].cnst_str;
385 switch (names[kct].mode) {
386 case 0: mode = mode_Iu; break;
387 case 1: mode = mode_Lu; break;
388 default: mode = mode_F; break;
390 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
391 tp = new_type_primitive(new_id_from_str(tp_name), mode);
392 /* set the specified alignment */
393 set_type_alignment_bytes(tp, names[kct].align);
395 if (kct == ia32_ULLBIAS) {
396 /* we are in the backend, construct a fixed type here */
397 unsigned size = get_type_size_bytes(tp);
398 tp = new_type_array(new_id_from_str(tp_name), 1, tp);
399 set_type_alignment_bytes(tp, names[kct].align);
400 set_type_size_bytes(tp, 2 * size);
401 set_type_state(tp, layout_fixed);
403 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
405 set_entity_ld_ident(ent, get_entity_ident(ent));
406 set_entity_visibility(ent, visibility_local);
407 set_entity_variability(ent, variability_constant);
408 set_entity_allocation(ent, allocation_static);
410 if (kct == ia32_ULLBIAS) {
411 ir_initializer_t *initializer = create_initializer_compound(2);
413 set_initializer_compound_value(initializer, 0,
414 create_initializer_tarval(get_tarval_null(mode)));
415 set_initializer_compound_value(initializer, 1,
416 create_initializer_tarval(tv));
418 set_entity_initializer(ent, initializer);
420 set_entity_initializer(ent, create_initializer_tarval(tv));
423 /* cache the entry */
424 ent_cache[kct] = ent;
427 return ent_cache[kct];
431 * return true if the node is a Proj(Load) and could be used in source address
432 * mode for another node. Will return only true if the @p other node is not
433 * dependent on the memory of the Load (for binary operations use the other
434 * input here, for unary operations use NULL).
436 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
437 ir_node *other, ir_node *other2, match_flags_t flags)
442 /* float constants are always available */
443 if (is_Const(node)) {
444 ir_mode *mode = get_irn_mode(node);
445 if (mode_is_float(mode)) {
446 if (ia32_cg_config.use_sse2) {
447 if (is_simple_sse_Const(node))
450 if (is_simple_x87_Const(node))
453 if (get_irn_n_edges(node) > 1)
461 load = get_Proj_pred(node);
462 pn = get_Proj_proj(node);
463 if (!is_Load(load) || pn != pn_Load_res)
465 if (get_nodes_block(load) != block)
467 /* we only use address mode if we're the only user of the load */
468 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
470 /* in some edge cases with address mode we might reach the load normally
471 * and through some AM sequence, if it is already materialized then we
472 * can't create an AM node from it */
473 if (be_is_transformed(node))
476 /* don't do AM if other node inputs depend on the load (via mem-proj) */
477 if (other != NULL && prevents_AM(block, load, other))
480 if (other2 != NULL && prevents_AM(block, load, other2))
486 typedef struct ia32_address_mode_t ia32_address_mode_t;
487 struct ia32_address_mode_t {
492 ia32_op_type_t op_type;
496 unsigned commutative : 1;
497 unsigned ins_permuted : 1;
500 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
504 /* construct load address */
505 memset(addr, 0, sizeof(addr[0]));
506 ia32_create_address_mode(addr, ptr, 0);
508 noreg_gp = ia32_new_NoReg_gp(env_cg);
509 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
510 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
511 addr->mem = be_transform_node(mem);
514 static void build_address(ia32_address_mode_t *am, ir_node *node,
515 ia32_create_am_flags_t flags)
517 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
518 ia32_address_t *addr = &am->addr;
524 if (is_Const(node)) {
525 ir_entity *entity = create_float_const_entity(node);
526 addr->base = noreg_gp;
527 addr->index = noreg_gp;
528 addr->mem = new_NoMem();
529 addr->symconst_ent = entity;
531 am->ls_mode = get_type_mode(get_entity_type(entity));
532 am->pinned = op_pin_state_floats;
536 load = get_Proj_pred(node);
537 ptr = get_Load_ptr(load);
538 mem = get_Load_mem(load);
539 new_mem = be_transform_node(mem);
540 am->pinned = get_irn_pinned(load);
541 am->ls_mode = get_Load_mode(load);
542 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
545 /* construct load address */
546 ia32_create_address_mode(addr, ptr, flags);
548 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
549 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
553 static void set_address(ir_node *node, const ia32_address_t *addr)
555 set_ia32_am_scale(node, addr->scale);
556 set_ia32_am_sc(node, addr->symconst_ent);
557 set_ia32_am_offs_int(node, addr->offset);
558 if (addr->symconst_sign)
559 set_ia32_am_sc_sign(node);
561 set_ia32_use_frame(node);
562 set_ia32_frame_ent(node, addr->frame_entity);
566 * Apply attributes of a given address mode to a node.
568 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
570 set_address(node, &am->addr);
572 set_ia32_op_type(node, am->op_type);
573 set_ia32_ls_mode(node, am->ls_mode);
574 if (am->pinned == op_pin_state_pinned) {
575 /* beware: some nodes are already pinned and did not allow to change the state */
576 if (get_irn_pinned(node) != op_pin_state_pinned)
577 set_irn_pinned(node, op_pin_state_pinned);
580 set_ia32_commutative(node);
584 * Check, if a given node is a Down-Conv, ie. a integer Conv
585 * from a mode with a mode with more bits to a mode with lesser bits.
586 * Moreover, we return only true if the node has not more than 1 user.
588 * @param node the node
589 * @return non-zero if node is a Down-Conv
591 static int is_downconv(const ir_node *node)
599 /* we only want to skip the conv when we're the only user
600 * (not optimal but for now...)
602 if (get_irn_n_edges(node) > 1)
605 src_mode = get_irn_mode(get_Conv_op(node));
606 dest_mode = get_irn_mode(node);
608 ia32_mode_needs_gp_reg(src_mode) &&
609 ia32_mode_needs_gp_reg(dest_mode) &&
610 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
613 /* Skip all Down-Conv's on a given node and return the resulting node. */
614 ir_node *ia32_skip_downconv(ir_node *node)
616 while (is_downconv(node))
617 node = get_Conv_op(node);
622 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
624 ir_mode *mode = get_irn_mode(node);
629 if (mode_is_signed(mode)) {
634 block = get_nodes_block(node);
635 dbgi = get_irn_dbg_info(node);
637 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
641 * matches operands of a node into ia32 addressing/operand modes. This covers
642 * usage of source address mode, immediates, operations with non 32-bit modes,
644 * The resulting data is filled into the @p am struct. block is the block
645 * of the node whose arguments are matched. op1, op2 are the first and second
646 * input that are matched (op1 may be NULL). other_op is another unrelated
647 * input that is not matched! but which is needed sometimes to check if AM
648 * for op1/op2 is legal.
649 * @p flags describes the supported modes of the operation in detail.
651 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
652 ir_node *op1, ir_node *op2, ir_node *other_op,
655 ia32_address_t *addr = &am->addr;
656 ir_mode *mode = get_irn_mode(op2);
657 int mode_bits = get_mode_size_bits(mode);
658 ir_node *noreg_gp, *new_op1, *new_op2;
660 unsigned commutative;
661 int use_am_and_immediates;
664 memset(am, 0, sizeof(am[0]));
666 commutative = (flags & match_commutative) != 0;
667 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
668 use_am = (flags & match_am) != 0;
669 use_immediate = (flags & match_immediate) != 0;
670 assert(!use_am_and_immediates || use_immediate);
673 assert(!commutative || op1 != NULL);
674 assert(use_am || !(flags & match_8bit_am));
675 assert(use_am || !(flags & match_16bit_am));
677 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
678 (mode_bits == 16 && !(flags & match_16bit_am))) {
682 /* we can simply skip downconvs for mode neutral nodes: the upper bits
683 * can be random for these operations */
684 if (flags & match_mode_neutral) {
685 op2 = ia32_skip_downconv(op2);
687 op1 = ia32_skip_downconv(op1);
691 /* match immediates. firm nodes are normalized: constants are always on the
694 if (!(flags & match_try_am) && use_immediate) {
695 new_op2 = try_create_Immediate(op2, 0);
698 noreg_gp = ia32_new_NoReg_gp(env_cg);
699 if (new_op2 == NULL &&
700 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
701 build_address(am, op2, 0);
702 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
703 if (mode_is_float(mode)) {
704 new_op2 = ia32_new_NoReg_vfp(env_cg);
708 am->op_type = ia32_AddrModeS;
709 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
711 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
713 build_address(am, op1, 0);
715 if (mode_is_float(mode)) {
716 noreg = ia32_new_NoReg_vfp(env_cg);
721 if (new_op2 != NULL) {
724 new_op1 = be_transform_node(op2);
726 am->ins_permuted = 1;
728 am->op_type = ia32_AddrModeS;
730 am->op_type = ia32_Normal;
732 if (flags & match_try_am) {
738 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
740 new_op2 = be_transform_node(op2);
742 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
744 if (addr->base == NULL)
745 addr->base = noreg_gp;
746 if (addr->index == NULL)
747 addr->index = noreg_gp;
748 if (addr->mem == NULL)
749 addr->mem = new_NoMem();
751 am->new_op1 = new_op1;
752 am->new_op2 = new_op2;
753 am->commutative = commutative;
756 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
761 if (am->mem_proj == NULL)
764 /* we have to create a mode_T so the old MemProj can attach to us */
765 mode = get_irn_mode(node);
766 load = get_Proj_pred(am->mem_proj);
768 be_set_transformed_node(load, node);
770 if (mode != mode_T) {
771 set_irn_mode(node, mode_T);
772 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
779 * Construct a standard binary operation, set AM and immediate if required.
781 * @param node The original node for which the binop is created
782 * @param op1 The first operand
783 * @param op2 The second operand
784 * @param func The node constructor function
785 * @return The constructed ia32 node.
787 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
788 construct_binop_func *func, match_flags_t flags)
791 ir_node *block, *new_block, *new_node;
792 ia32_address_mode_t am;
793 ia32_address_t *addr = &am.addr;
795 block = get_nodes_block(node);
796 match_arguments(&am, block, op1, op2, NULL, flags);
798 dbgi = get_irn_dbg_info(node);
799 new_block = be_transform_node(block);
800 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
801 am.new_op1, am.new_op2);
802 set_am_attributes(new_node, &am);
803 /* we can't use source address mode anymore when using immediates */
804 if (!(flags & match_am_and_immediates) &&
805 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
806 set_ia32_am_support(new_node, ia32_am_none);
807 SET_IA32_ORIG_NODE(new_node, node);
809 new_node = fix_mem_proj(new_node, &am);
816 n_ia32_l_binop_right,
817 n_ia32_l_binop_eflags
819 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
820 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
821 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
822 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
823 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
824 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
827 * Construct a binary operation which also consumes the eflags.
829 * @param node The node to transform
830 * @param func The node constructor function
831 * @param flags The match flags
832 * @return The constructor ia32 node
834 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
837 ir_node *src_block = get_nodes_block(node);
838 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
839 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
840 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
842 ir_node *block, *new_node, *new_eflags;
843 ia32_address_mode_t am;
844 ia32_address_t *addr = &am.addr;
846 match_arguments(&am, src_block, op1, op2, eflags, flags);
848 dbgi = get_irn_dbg_info(node);
849 block = be_transform_node(src_block);
850 new_eflags = be_transform_node(eflags);
851 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
852 am.new_op1, am.new_op2, new_eflags);
853 set_am_attributes(new_node, &am);
854 /* we can't use source address mode anymore when using immediates */
855 if (!(flags & match_am_and_immediates) &&
856 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
857 set_ia32_am_support(new_node, ia32_am_none);
858 SET_IA32_ORIG_NODE(new_node, node);
860 new_node = fix_mem_proj(new_node, &am);
865 static ir_node *get_fpcw(void)
868 if (initial_fpcw != NULL)
871 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
872 &ia32_fp_cw_regs[REG_FPCW]);
873 initial_fpcw = be_transform_node(fpcw);
879 * Construct a standard binary operation, set AM and immediate if required.
881 * @param op1 The first operand
882 * @param op2 The second operand
883 * @param func The node constructor function
884 * @return The constructed ia32 node.
886 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
887 construct_binop_float_func *func)
889 ir_mode *mode = get_irn_mode(node);
891 ir_node *block, *new_block, *new_node;
892 ia32_address_mode_t am;
893 ia32_address_t *addr = &am.addr;
894 ia32_x87_attr_t *attr;
895 /* All operations are considered commutative, because there are reverse
897 match_flags_t flags = match_commutative;
899 /* cannot use address mode with long double on x87 */
900 if (get_mode_size_bits(mode) <= 64)
903 block = get_nodes_block(node);
904 match_arguments(&am, block, op1, op2, NULL, flags);
906 dbgi = get_irn_dbg_info(node);
907 new_block = be_transform_node(block);
908 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
909 am.new_op1, am.new_op2, get_fpcw());
910 set_am_attributes(new_node, &am);
912 attr = get_ia32_x87_attr(new_node);
913 attr->attr.data.ins_permuted = am.ins_permuted;
915 SET_IA32_ORIG_NODE(new_node, node);
917 new_node = fix_mem_proj(new_node, &am);
923 * Construct a shift/rotate binary operation, sets AM and immediate if required.
925 * @param op1 The first operand
926 * @param op2 The second operand
927 * @param func The node constructor function
928 * @return The constructed ia32 node.
930 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
931 construct_shift_func *func,
935 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
937 assert(! mode_is_float(get_irn_mode(node)));
938 assert(flags & match_immediate);
939 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
941 if (flags & match_mode_neutral) {
942 op1 = ia32_skip_downconv(op1);
943 new_op1 = be_transform_node(op1);
944 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
945 new_op1 = create_upconv(op1, node);
947 new_op1 = be_transform_node(op1);
950 /* the shift amount can be any mode that is bigger than 5 bits, since all
951 * other bits are ignored anyway */
952 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
953 ir_node *const op = get_Conv_op(op2);
954 if (mode_is_float(get_irn_mode(op)))
957 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
959 new_op2 = create_immediate_or_transform(op2, 0);
961 dbgi = get_irn_dbg_info(node);
962 block = get_nodes_block(node);
963 new_block = be_transform_node(block);
964 new_node = func(dbgi, new_block, new_op1, new_op2);
965 SET_IA32_ORIG_NODE(new_node, node);
967 /* lowered shift instruction may have a dependency operand, handle it here */
968 if (get_irn_arity(node) == 3) {
969 /* we have a dependency */
970 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
971 add_irn_dep(new_node, new_dep);
979 * Construct a standard unary operation, set AM and immediate if required.
981 * @param op The operand
982 * @param func The node constructor function
983 * @return The constructed ia32 node.
985 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
989 ir_node *block, *new_block, *new_op, *new_node;
991 assert(flags == 0 || flags == match_mode_neutral);
992 if (flags & match_mode_neutral) {
993 op = ia32_skip_downconv(op);
996 new_op = be_transform_node(op);
997 dbgi = get_irn_dbg_info(node);
998 block = get_nodes_block(node);
999 new_block = be_transform_node(block);
1000 new_node = func(dbgi, new_block, new_op);
1002 SET_IA32_ORIG_NODE(new_node, node);
1007 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1008 ia32_address_t *addr)
1010 ir_node *base, *index, *res;
1014 base = ia32_new_NoReg_gp(env_cg);
1016 base = be_transform_node(base);
1019 index = addr->index;
1020 if (index == NULL) {
1021 index = ia32_new_NoReg_gp(env_cg);
1023 index = be_transform_node(index);
1026 res = new_bd_ia32_Lea(dbgi, block, base, index);
1027 set_address(res, addr);
1033 * Returns non-zero if a given address mode has a symbolic or
1034 * numerical offset != 0.
1036 static int am_has_immediates(const ia32_address_t *addr)
1038 return addr->offset != 0 || addr->symconst_ent != NULL
1039 || addr->frame_entity || addr->use_frame;
1043 * Creates an ia32 Add.
1045 * @return the created ia32 Add node
1047 static ir_node *gen_Add(ir_node *node)
1049 ir_mode *mode = get_irn_mode(node);
1050 ir_node *op1 = get_Add_left(node);
1051 ir_node *op2 = get_Add_right(node);
1053 ir_node *block, *new_block, *new_node, *add_immediate_op;
1054 ia32_address_t addr;
1055 ia32_address_mode_t am;
1057 if (mode_is_float(mode)) {
1058 if (ia32_cg_config.use_sse2)
1059 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1060 match_commutative | match_am);
1062 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1065 ia32_mark_non_am(node);
1067 op2 = ia32_skip_downconv(op2);
1068 op1 = ia32_skip_downconv(op1);
1072 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1073 * 1. Add with immediate -> Lea
1074 * 2. Add with possible source address mode -> Add
1075 * 3. Otherwise -> Lea
1077 memset(&addr, 0, sizeof(addr));
1078 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1079 add_immediate_op = NULL;
1081 dbgi = get_irn_dbg_info(node);
1082 block = get_nodes_block(node);
1083 new_block = be_transform_node(block);
1086 if (addr.base == NULL && addr.index == NULL) {
1087 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1088 addr.symconst_sign, addr.offset);
1089 be_dep_on_frame(new_node);
1090 SET_IA32_ORIG_NODE(new_node, node);
1093 /* add with immediate? */
1094 if (addr.index == NULL) {
1095 add_immediate_op = addr.base;
1096 } else if (addr.base == NULL && addr.scale == 0) {
1097 add_immediate_op = addr.index;
1100 if (add_immediate_op != NULL) {
1101 if (!am_has_immediates(&addr)) {
1102 #ifdef DEBUG_libfirm
1103 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1106 return be_transform_node(add_immediate_op);
1109 new_node = create_lea_from_address(dbgi, new_block, &addr);
1110 SET_IA32_ORIG_NODE(new_node, node);
1114 /* test if we can use source address mode */
1115 match_arguments(&am, block, op1, op2, NULL, match_commutative
1116 | match_mode_neutral | match_am | match_immediate | match_try_am);
1118 /* construct an Add with source address mode */
1119 if (am.op_type == ia32_AddrModeS) {
1120 ia32_address_t *am_addr = &am.addr;
1121 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1122 am_addr->index, am_addr->mem, am.new_op1,
1124 set_am_attributes(new_node, &am);
1125 SET_IA32_ORIG_NODE(new_node, node);
1127 new_node = fix_mem_proj(new_node, &am);
1132 /* otherwise construct a lea */
1133 new_node = create_lea_from_address(dbgi, new_block, &addr);
1134 SET_IA32_ORIG_NODE(new_node, node);
1139 * Creates an ia32 Mul.
1141 * @return the created ia32 Mul node
1143 static ir_node *gen_Mul(ir_node *node)
1145 ir_node *op1 = get_Mul_left(node);
1146 ir_node *op2 = get_Mul_right(node);
1147 ir_mode *mode = get_irn_mode(node);
1149 if (mode_is_float(mode)) {
1150 if (ia32_cg_config.use_sse2)
1151 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1152 match_commutative | match_am);
1154 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1156 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1157 match_commutative | match_am | match_mode_neutral |
1158 match_immediate | match_am_and_immediates);
1162 * Creates an ia32 Mulh.
1163 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1164 * this result while Mul returns the lower 32 bit.
1166 * @return the created ia32 Mulh node
1168 static ir_node *gen_Mulh(ir_node *node)
1170 ir_node *block = get_nodes_block(node);
1171 ir_node *new_block = be_transform_node(block);
1172 dbg_info *dbgi = get_irn_dbg_info(node);
1173 ir_node *op1 = get_Mulh_left(node);
1174 ir_node *op2 = get_Mulh_right(node);
1175 ir_mode *mode = get_irn_mode(node);
1177 ir_node *proj_res_high;
1179 if (mode_is_signed(mode)) {
1180 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1181 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1182 mode_Iu, pn_ia32_IMul1OP_res_high);
1184 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1185 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1186 mode_Iu, pn_ia32_Mul_res_high);
1188 return proj_res_high;
1192 * Creates an ia32 And.
1194 * @return The created ia32 And node
1196 static ir_node *gen_And(ir_node *node)
1198 ir_node *op1 = get_And_left(node);
1199 ir_node *op2 = get_And_right(node);
1200 assert(! mode_is_float(get_irn_mode(node)));
1202 /* is it a zero extension? */
1203 if (is_Const(op2)) {
1204 tarval *tv = get_Const_tarval(op2);
1205 long v = get_tarval_long(tv);
1207 if (v == 0xFF || v == 0xFFFF) {
1208 dbg_info *dbgi = get_irn_dbg_info(node);
1209 ir_node *block = get_nodes_block(node);
1216 assert(v == 0xFFFF);
1219 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1224 return gen_binop(node, op1, op2, new_bd_ia32_And,
1225 match_commutative | match_mode_neutral | match_am | match_immediate);
1231 * Creates an ia32 Or.
1233 * @return The created ia32 Or node
1235 static ir_node *gen_Or(ir_node *node)
1237 ir_node *op1 = get_Or_left(node);
1238 ir_node *op2 = get_Or_right(node);
1240 assert (! mode_is_float(get_irn_mode(node)));
1241 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1242 | match_mode_neutral | match_am | match_immediate);
1248 * Creates an ia32 Eor.
1250 * @return The created ia32 Eor node
1252 static ir_node *gen_Eor(ir_node *node)
1254 ir_node *op1 = get_Eor_left(node);
1255 ir_node *op2 = get_Eor_right(node);
1257 assert(! mode_is_float(get_irn_mode(node)));
1258 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1259 | match_mode_neutral | match_am | match_immediate);
1264 * Creates an ia32 Sub.
1266 * @return The created ia32 Sub node
1268 static ir_node *gen_Sub(ir_node *node)
1270 ir_node *op1 = get_Sub_left(node);
1271 ir_node *op2 = get_Sub_right(node);
1272 ir_mode *mode = get_irn_mode(node);
1274 if (mode_is_float(mode)) {
1275 if (ia32_cg_config.use_sse2)
1276 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1278 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1281 if (is_Const(op2)) {
1282 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1286 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1287 | match_am | match_immediate);
1290 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1291 ir_node *const src_val,
1292 ir_node *const src_mem,
1293 ir_node *const am_mem)
1295 if (is_NoMem(am_mem)) {
1296 return be_transform_node(src_mem);
1297 } else if (is_Proj(src_val) &&
1299 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1300 /* avoid memory loop */
1302 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1303 ir_node *const ptr_pred = get_Proj_pred(src_val);
1304 int const arity = get_Sync_n_preds(src_mem);
1309 NEW_ARR_A(ir_node*, ins, arity + 1);
1311 /* NOTE: This sometimes produces dead-code because the old sync in
1312 * src_mem might not be used anymore, we should detect this case
1313 * and kill the sync... */
1314 for (i = arity - 1; i >= 0; --i) {
1315 ir_node *const pred = get_Sync_pred(src_mem, i);
1317 /* avoid memory loop */
1318 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1321 ins[n++] = be_transform_node(pred);
1326 return new_r_Sync(irg, block, n, ins);
1330 ins[0] = be_transform_node(src_mem);
1332 return new_r_Sync(irg, block, 2, ins);
1336 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1337 ir_node *val, const ir_node *orig)
1342 if (ia32_cg_config.use_short_sex_eax) {
1343 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1344 be_dep_on_frame(pval);
1345 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1347 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1348 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1350 SET_IA32_ORIG_NODE(res, orig);
1355 * Generates an ia32 DivMod with additional infrastructure for the
1356 * register allocator if needed.
1358 static ir_node *create_Div(ir_node *node)
1360 dbg_info *dbgi = get_irn_dbg_info(node);
1361 ir_node *block = get_nodes_block(node);
1362 ir_node *new_block = be_transform_node(block);
1369 ir_node *sign_extension;
1370 ia32_address_mode_t am;
1371 ia32_address_t *addr = &am.addr;
1373 /* the upper bits have random contents for smaller modes */
1374 switch (get_irn_opcode(node)) {
1376 op1 = get_Div_left(node);
1377 op2 = get_Div_right(node);
1378 mem = get_Div_mem(node);
1379 mode = get_Div_resmode(node);
1382 op1 = get_Mod_left(node);
1383 op2 = get_Mod_right(node);
1384 mem = get_Mod_mem(node);
1385 mode = get_Mod_resmode(node);
1388 op1 = get_DivMod_left(node);
1389 op2 = get_DivMod_right(node);
1390 mem = get_DivMod_mem(node);
1391 mode = get_DivMod_resmode(node);
1394 panic("invalid divmod node %+F", node);
1397 match_arguments(&am, block, op1, op2, NULL, match_am);
1399 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1400 is the memory of the consumed address. We can have only the second op as address
1401 in Div nodes, so check only op2. */
1402 new_mem = transform_AM_mem(current_ir_graph, block, op2, mem, addr->mem);
1404 if (mode_is_signed(mode)) {
1405 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1406 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1407 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1409 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0);
1410 be_dep_on_frame(sign_extension);
1412 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1413 addr->index, new_mem, am.new_op2,
1414 am.new_op1, sign_extension);
1417 set_irn_pinned(new_node, get_irn_pinned(node));
1419 set_am_attributes(new_node, &am);
1420 SET_IA32_ORIG_NODE(new_node, node);
1422 new_node = fix_mem_proj(new_node, &am);
1428 static ir_node *gen_Mod(ir_node *node)
1430 return create_Div(node);
1433 static ir_node *gen_Div(ir_node *node)
1435 return create_Div(node);
1438 static ir_node *gen_DivMod(ir_node *node)
1440 return create_Div(node);
1446 * Creates an ia32 floating Div.
1448 * @return The created ia32 xDiv node
1450 static ir_node *gen_Quot(ir_node *node)
1452 ir_node *op1 = get_Quot_left(node);
1453 ir_node *op2 = get_Quot_right(node);
1455 if (ia32_cg_config.use_sse2) {
1456 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1458 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1464 * Creates an ia32 Shl.
1466 * @return The created ia32 Shl node
1468 static ir_node *gen_Shl(ir_node *node)
1470 ir_node *left = get_Shl_left(node);
1471 ir_node *right = get_Shl_right(node);
1473 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1474 match_mode_neutral | match_immediate);
1478 * Creates an ia32 Shr.
1480 * @return The created ia32 Shr node
1482 static ir_node *gen_Shr(ir_node *node)
1484 ir_node *left = get_Shr_left(node);
1485 ir_node *right = get_Shr_right(node);
1487 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1493 * Creates an ia32 Sar.
1495 * @return The created ia32 Shrs node
1497 static ir_node *gen_Shrs(ir_node *node)
1499 ir_node *left = get_Shrs_left(node);
1500 ir_node *right = get_Shrs_right(node);
1502 if (is_Const(right)) {
1503 tarval *tv = get_Const_tarval(right);
1504 long val = get_tarval_long(tv);
1506 /* this is a sign extension */
1507 dbg_info *dbgi = get_irn_dbg_info(node);
1508 ir_node *block = be_transform_node(get_nodes_block(node));
1509 ir_node *new_op = be_transform_node(left);
1511 return create_sex_32_64(dbgi, block, new_op, node);
1515 /* 8 or 16 bit sign extension? */
1516 if (is_Const(right) && is_Shl(left)) {
1517 ir_node *shl_left = get_Shl_left(left);
1518 ir_node *shl_right = get_Shl_right(left);
1519 if (is_Const(shl_right)) {
1520 tarval *tv1 = get_Const_tarval(right);
1521 tarval *tv2 = get_Const_tarval(shl_right);
1522 if (tv1 == tv2 && tarval_is_long(tv1)) {
1523 long val = get_tarval_long(tv1);
1524 if (val == 16 || val == 24) {
1525 dbg_info *dbgi = get_irn_dbg_info(node);
1526 ir_node *block = get_nodes_block(node);
1536 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1545 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1551 * Creates an ia32 Rol.
1553 * @param op1 The first operator
1554 * @param op2 The second operator
1555 * @return The created ia32 RotL node
1557 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1559 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1565 * Creates an ia32 Ror.
1566 * NOTE: There is no RotR with immediate because this would always be a RotL
1567 * "imm-mode_size_bits" which can be pre-calculated.
1569 * @param op1 The first operator
1570 * @param op2 The second operator
1571 * @return The created ia32 RotR node
1573 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1575 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1581 * Creates an ia32 RotR or RotL (depending on the found pattern).
1583 * @return The created ia32 RotL or RotR node
1585 static ir_node *gen_Rotl(ir_node *node)
1587 ir_node *rotate = NULL;
1588 ir_node *op1 = get_Rotl_left(node);
1589 ir_node *op2 = get_Rotl_right(node);
1591 /* Firm has only RotL, so we are looking for a right (op2)
1592 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1593 that means we can create a RotR instead of an Add and a RotL */
1597 ir_node *left = get_Add_left(add);
1598 ir_node *right = get_Add_right(add);
1599 if (is_Const(right)) {
1600 tarval *tv = get_Const_tarval(right);
1601 ir_mode *mode = get_irn_mode(node);
1602 long bits = get_mode_size_bits(mode);
1604 if (is_Minus(left) &&
1605 tarval_is_long(tv) &&
1606 get_tarval_long(tv) == bits &&
1609 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1610 rotate = gen_Ror(node, op1, get_Minus_op(left));
1615 if (rotate == NULL) {
1616 rotate = gen_Rol(node, op1, op2);
1625 * Transforms a Minus node.
1627 * @return The created ia32 Minus node
1629 static ir_node *gen_Minus(ir_node *node)
1631 ir_node *op = get_Minus_op(node);
1632 ir_node *block = be_transform_node(get_nodes_block(node));
1633 dbg_info *dbgi = get_irn_dbg_info(node);
1634 ir_mode *mode = get_irn_mode(node);
1639 if (mode_is_float(mode)) {
1640 ir_node *new_op = be_transform_node(op);
1641 if (ia32_cg_config.use_sse2) {
1642 /* TODO: non-optimal... if we have many xXors, then we should
1643 * rather create a load for the const and use that instead of
1644 * several AM nodes... */
1645 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1646 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1647 ir_node *nomem = new_NoMem();
1649 new_node = new_bd_ia32_xXor(dbgi, block, noreg_gp, noreg_gp,
1650 nomem, new_op, noreg_xmm);
1652 size = get_mode_size_bits(mode);
1653 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1655 set_ia32_am_sc(new_node, ent);
1656 set_ia32_op_type(new_node, ia32_AddrModeS);
1657 set_ia32_ls_mode(new_node, mode);
1659 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1662 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1665 SET_IA32_ORIG_NODE(new_node, node);
1671 * Transforms a Not node.
1673 * @return The created ia32 Not node
1675 static ir_node *gen_Not(ir_node *node)
1677 ir_node *op = get_Not_op(node);
1679 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1680 assert (! mode_is_float(get_irn_mode(node)));
1682 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1688 * Transforms an Abs node.
1690 * @return The created ia32 Abs node
1692 static ir_node *gen_Abs(ir_node *node)
1694 ir_node *block = get_nodes_block(node);
1695 ir_node *new_block = be_transform_node(block);
1696 ir_node *op = get_Abs_op(node);
1697 dbg_info *dbgi = get_irn_dbg_info(node);
1698 ir_mode *mode = get_irn_mode(node);
1699 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1700 ir_node *nomem = new_NoMem();
1706 if (mode_is_float(mode)) {
1707 new_op = be_transform_node(op);
1709 if (ia32_cg_config.use_sse2) {
1710 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1711 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_gp, noreg_gp,
1712 nomem, new_op, noreg_fp);
1714 size = get_mode_size_bits(mode);
1715 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1717 set_ia32_am_sc(new_node, ent);
1719 SET_IA32_ORIG_NODE(new_node, node);
1721 set_ia32_op_type(new_node, ia32_AddrModeS);
1722 set_ia32_ls_mode(new_node, mode);
1724 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1725 SET_IA32_ORIG_NODE(new_node, node);
1728 ir_node *xor, *sign_extension;
1730 if (get_mode_size_bits(mode) == 32) {
1731 new_op = be_transform_node(op);
1733 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1736 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1738 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_gp, noreg_gp,
1739 nomem, new_op, sign_extension);
1740 SET_IA32_ORIG_NODE(xor, node);
1742 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_gp, noreg_gp,
1743 nomem, xor, sign_extension);
1744 SET_IA32_ORIG_NODE(new_node, node);
1751 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1753 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1755 dbg_info *dbgi = get_irn_dbg_info(cmp);
1756 ir_node *block = get_nodes_block(cmp);
1757 ir_node *new_block = be_transform_node(block);
1758 ir_node *op1 = be_transform_node(x);
1759 ir_node *op2 = be_transform_node(n);
1761 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1765 * Transform a node returning a "flag" result.
1767 * @param node the node to transform
1768 * @param pnc_out the compare mode to use
1770 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1779 /* we have a Cmp as input */
1780 if (is_Proj(node)) {
1781 ir_node *pred = get_Proj_pred(node);
1783 pn_Cmp pnc = get_Proj_proj(node);
1784 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1785 ir_node *l = get_Cmp_left(pred);
1786 ir_node *r = get_Cmp_right(pred);
1788 ir_node *la = get_And_left(l);
1789 ir_node *ra = get_And_right(l);
1791 ir_node *c = get_Shl_left(la);
1792 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1793 /* (1 << n) & ra) */
1794 ir_node *n = get_Shl_right(la);
1795 flags = gen_bt(pred, ra, n);
1796 /* we must generate a Jc/Jnc jump */
1797 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1800 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1805 ir_node *c = get_Shl_left(ra);
1806 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1807 /* la & (1 << n)) */
1808 ir_node *n = get_Shl_right(ra);
1809 flags = gen_bt(pred, la, n);
1810 /* we must generate a Jc/Jnc jump */
1811 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1814 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1820 flags = be_transform_node(pred);
1826 /* a mode_b value, we have to compare it against 0 */
1827 dbgi = get_irn_dbg_info(node);
1828 new_block = be_transform_node(get_nodes_block(node));
1829 new_op = be_transform_node(node);
1830 noreg = ia32_new_NoReg_gp(env_cg);
1831 nomem = new_NoMem();
1832 flags = new_bd_ia32_Test(dbgi, new_block, noreg, noreg, nomem, new_op,
1833 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1834 *pnc_out = pn_Cmp_Lg;
1839 * Transforms a Load.
1841 * @return the created ia32 Load node
1843 static ir_node *gen_Load(ir_node *node)
1845 ir_node *old_block = get_nodes_block(node);
1846 ir_node *block = be_transform_node(old_block);
1847 ir_node *ptr = get_Load_ptr(node);
1848 ir_node *mem = get_Load_mem(node);
1849 ir_node *new_mem = be_transform_node(mem);
1852 dbg_info *dbgi = get_irn_dbg_info(node);
1853 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1854 ir_mode *mode = get_Load_mode(node);
1857 ia32_address_t addr;
1859 /* construct load address */
1860 memset(&addr, 0, sizeof(addr));
1861 ia32_create_address_mode(&addr, ptr, 0);
1868 base = be_transform_node(base);
1871 if (index == NULL) {
1874 index = be_transform_node(index);
1877 if (mode_is_float(mode)) {
1878 if (ia32_cg_config.use_sse2) {
1879 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1881 res_mode = mode_xmm;
1883 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1885 res_mode = mode_vfp;
1888 assert(mode != mode_b);
1890 /* create a conv node with address mode for smaller modes */
1891 if (get_mode_size_bits(mode) < 32) {
1892 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1893 new_mem, noreg, mode);
1895 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1900 set_irn_pinned(new_node, get_irn_pinned(node));
1901 set_ia32_op_type(new_node, ia32_AddrModeS);
1902 set_ia32_ls_mode(new_node, mode);
1903 set_address(new_node, &addr);
1905 if (get_irn_pinned(node) == op_pin_state_floats) {
1906 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1907 && pn_ia32_vfld_res == pn_ia32_Load_res
1908 && pn_ia32_Load_res == pn_ia32_res);
1909 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1912 SET_IA32_ORIG_NODE(new_node, node);
1914 be_dep_on_frame(new_node);
1918 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1919 ir_node *ptr, ir_node *other)
1926 /* we only use address mode if we're the only user of the load */
1927 if (get_irn_n_edges(node) > 1)
1930 load = get_Proj_pred(node);
1933 if (get_nodes_block(load) != block)
1936 /* store should have the same pointer as the load */
1937 if (get_Load_ptr(load) != ptr)
1940 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1941 if (other != NULL &&
1942 get_nodes_block(other) == block &&
1943 heights_reachable_in_block(heights, other, load)) {
1947 if (prevents_AM(block, load, mem))
1949 /* Store should be attached to the load via mem */
1950 assert(heights_reachable_in_block(heights, mem, load));
1955 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1956 ir_node *mem, ir_node *ptr, ir_mode *mode,
1957 construct_binop_dest_func *func,
1958 construct_binop_dest_func *func8bit,
1959 match_flags_t flags)
1961 ir_node *src_block = get_nodes_block(node);
1963 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1970 ia32_address_mode_t am;
1971 ia32_address_t *addr = &am.addr;
1972 memset(&am, 0, sizeof(am));
1974 assert(flags & match_immediate); /* there is no destam node without... */
1975 commutative = (flags & match_commutative) != 0;
1977 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1978 build_address(&am, op1, ia32_create_am_double_use);
1979 new_op = create_immediate_or_transform(op2, 0);
1980 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1981 build_address(&am, op2, ia32_create_am_double_use);
1982 new_op = create_immediate_or_transform(op1, 0);
1987 if (addr->base == NULL)
1988 addr->base = noreg_gp;
1989 if (addr->index == NULL)
1990 addr->index = noreg_gp;
1991 if (addr->mem == NULL)
1992 addr->mem = new_NoMem();
1994 dbgi = get_irn_dbg_info(node);
1995 block = be_transform_node(src_block);
1996 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
1998 if (get_mode_size_bits(mode) == 8) {
1999 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2001 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2003 set_address(new_node, addr);
2004 set_ia32_op_type(new_node, ia32_AddrModeD);
2005 set_ia32_ls_mode(new_node, mode);
2006 SET_IA32_ORIG_NODE(new_node, node);
2008 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2009 mem_proj = be_transform_node(am.mem_proj);
2010 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2015 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2016 ir_node *ptr, ir_mode *mode,
2017 construct_unop_dest_func *func)
2019 ir_node *src_block = get_nodes_block(node);
2025 ia32_address_mode_t am;
2026 ia32_address_t *addr = &am.addr;
2028 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2031 memset(&am, 0, sizeof(am));
2032 build_address(&am, op, ia32_create_am_double_use);
2034 dbgi = get_irn_dbg_info(node);
2035 block = be_transform_node(src_block);
2036 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2037 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2038 set_address(new_node, addr);
2039 set_ia32_op_type(new_node, ia32_AddrModeD);
2040 set_ia32_ls_mode(new_node, mode);
2041 SET_IA32_ORIG_NODE(new_node, node);
2043 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2044 mem_proj = be_transform_node(am.mem_proj);
2045 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2050 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2052 ir_mode *mode = get_irn_mode(node);
2053 ir_node *mux_true = get_Mux_true(node);
2054 ir_node *mux_false = get_Mux_false(node);
2064 ia32_address_t addr;
2066 if (get_mode_size_bits(mode) != 8)
2069 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2071 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2077 build_address_ptr(&addr, ptr, mem);
2079 dbgi = get_irn_dbg_info(node);
2080 block = get_nodes_block(node);
2081 new_block = be_transform_node(block);
2082 cond = get_Mux_sel(node);
2083 flags = get_flags_node(cond, &pnc);
2084 new_mem = be_transform_node(mem);
2085 new_node = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2086 addr.index, addr.mem, flags, pnc, negated);
2087 set_address(new_node, &addr);
2088 set_ia32_op_type(new_node, ia32_AddrModeD);
2089 set_ia32_ls_mode(new_node, mode);
2090 SET_IA32_ORIG_NODE(new_node, node);
2095 static ir_node *try_create_dest_am(ir_node *node)
2097 ir_node *val = get_Store_value(node);
2098 ir_node *mem = get_Store_mem(node);
2099 ir_node *ptr = get_Store_ptr(node);
2100 ir_mode *mode = get_irn_mode(val);
2101 unsigned bits = get_mode_size_bits(mode);
2106 /* handle only GP modes for now... */
2107 if (!ia32_mode_needs_gp_reg(mode))
2111 /* store must be the only user of the val node */
2112 if (get_irn_n_edges(val) > 1)
2114 /* skip pointless convs */
2116 ir_node *conv_op = get_Conv_op(val);
2117 ir_mode *pred_mode = get_irn_mode(conv_op);
2118 if (!ia32_mode_needs_gp_reg(pred_mode))
2120 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2128 /* value must be in the same block */
2129 if (get_nodes_block(node) != get_nodes_block(val))
2132 switch (get_irn_opcode(val)) {
2134 op1 = get_Add_left(val);
2135 op2 = get_Add_right(val);
2136 if (ia32_cg_config.use_incdec) {
2137 if (is_Const_1(op2)) {
2138 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2140 } else if (is_Const_Minus_1(op2)) {
2141 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2145 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2146 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2147 match_commutative | match_immediate);
2150 op1 = get_Sub_left(val);
2151 op2 = get_Sub_right(val);
2152 if (is_Const(op2)) {
2153 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2155 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2156 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2160 op1 = get_And_left(val);
2161 op2 = get_And_right(val);
2162 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2163 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2164 match_commutative | match_immediate);
2167 op1 = get_Or_left(val);
2168 op2 = get_Or_right(val);
2169 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2170 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2171 match_commutative | match_immediate);
2174 op1 = get_Eor_left(val);
2175 op2 = get_Eor_right(val);
2176 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2177 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2178 match_commutative | match_immediate);
2181 op1 = get_Shl_left(val);
2182 op2 = get_Shl_right(val);
2183 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2184 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2188 op1 = get_Shr_left(val);
2189 op2 = get_Shr_right(val);
2190 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2191 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2195 op1 = get_Shrs_left(val);
2196 op2 = get_Shrs_right(val);
2197 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2198 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2202 op1 = get_Rotl_left(val);
2203 op2 = get_Rotl_right(val);
2204 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2205 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2208 /* TODO: match ROR patterns... */
2210 new_node = try_create_SetMem(val, ptr, mem);
2213 op1 = get_Minus_op(val);
2214 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2217 /* should be lowered already */
2218 assert(mode != mode_b);
2219 op1 = get_Not_op(val);
2220 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2226 if (new_node != NULL) {
2227 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2228 get_irn_pinned(node) == op_pin_state_pinned) {
2229 set_irn_pinned(new_node, op_pin_state_pinned);
2236 static bool possible_int_mode_for_fp(ir_mode *mode)
2240 if (!mode_is_signed(mode))
2242 size = get_mode_size_bits(mode);
2243 if (size != 16 && size != 32)
2248 static int is_float_to_int_conv(const ir_node *node)
2250 ir_mode *mode = get_irn_mode(node);
2254 if (!possible_int_mode_for_fp(mode))
2259 conv_op = get_Conv_op(node);
2260 conv_mode = get_irn_mode(conv_op);
2262 if (!mode_is_float(conv_mode))
2269 * Transform a Store(floatConst) into a sequence of
2272 * @return the created ia32 Store node
2274 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2276 ir_mode *mode = get_irn_mode(cns);
2277 unsigned size = get_mode_size_bytes(mode);
2278 tarval *tv = get_Const_tarval(cns);
2279 ir_node *block = get_nodes_block(node);
2280 ir_node *new_block = be_transform_node(block);
2281 ir_node *ptr = get_Store_ptr(node);
2282 ir_node *mem = get_Store_mem(node);
2283 dbg_info *dbgi = get_irn_dbg_info(node);
2287 ia32_address_t addr;
2289 assert(size % 4 == 0);
2292 build_address_ptr(&addr, ptr, mem);
2296 get_tarval_sub_bits(tv, ofs) |
2297 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2298 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2299 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2300 ir_node *imm = create_Immediate(NULL, 0, val);
2302 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2303 addr.index, addr.mem, imm);
2305 set_irn_pinned(new_node, get_irn_pinned(node));
2306 set_ia32_op_type(new_node, ia32_AddrModeD);
2307 set_ia32_ls_mode(new_node, mode_Iu);
2308 set_address(new_node, &addr);
2309 SET_IA32_ORIG_NODE(new_node, node);
2312 ins[i++] = new_node;
2317 } while (size != 0);
2320 return new_rd_Sync(dbgi, current_ir_graph, new_block, i, ins);
2327 * Generate a vfist or vfisttp instruction.
2329 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2330 ir_node *mem, ir_node *val, ir_node **fist)
2334 if (ia32_cg_config.use_fisttp) {
2335 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2336 if other users exists */
2337 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2338 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2339 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2340 be_new_Keep(reg_class, irg, block, 1, &value);
2342 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2345 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2348 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2354 * Transforms a general (no special case) Store.
2356 * @return the created ia32 Store node
2358 static ir_node *gen_general_Store(ir_node *node)
2360 ir_node *val = get_Store_value(node);
2361 ir_mode *mode = get_irn_mode(val);
2362 ir_node *block = get_nodes_block(node);
2363 ir_node *new_block = be_transform_node(block);
2364 ir_node *ptr = get_Store_ptr(node);
2365 ir_node *mem = get_Store_mem(node);
2366 dbg_info *dbgi = get_irn_dbg_info(node);
2367 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2368 ir_node *new_val, *new_node, *store;
2369 ia32_address_t addr;
2371 /* check for destination address mode */
2372 new_node = try_create_dest_am(node);
2373 if (new_node != NULL)
2376 /* construct store address */
2377 memset(&addr, 0, sizeof(addr));
2378 ia32_create_address_mode(&addr, ptr, 0);
2380 if (addr.base == NULL) {
2383 addr.base = be_transform_node(addr.base);
2386 if (addr.index == NULL) {
2389 addr.index = be_transform_node(addr.index);
2391 addr.mem = be_transform_node(mem);
2393 if (mode_is_float(mode)) {
2394 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2396 while (is_Conv(val) && mode == get_irn_mode(val)) {
2397 ir_node *op = get_Conv_op(val);
2398 if (!mode_is_float(get_irn_mode(op)))
2402 new_val = be_transform_node(val);
2403 if (ia32_cg_config.use_sse2) {
2404 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2405 addr.index, addr.mem, new_val);
2407 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2408 addr.index, addr.mem, new_val, mode);
2411 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2412 val = get_Conv_op(val);
2414 /* TODO: is this optimisation still necessary at all (middleend)? */
2415 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2416 while (is_Conv(val)) {
2417 ir_node *op = get_Conv_op(val);
2418 if (!mode_is_float(get_irn_mode(op)))
2420 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2424 new_val = be_transform_node(val);
2425 new_node = gen_vfist(dbgi, current_ir_graph, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2427 new_val = create_immediate_or_transform(val, 0);
2428 assert(mode != mode_b);
2430 if (get_mode_size_bits(mode) == 8) {
2431 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2432 addr.index, addr.mem, new_val);
2434 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2435 addr.index, addr.mem, new_val);
2440 set_irn_pinned(store, get_irn_pinned(node));
2441 set_ia32_op_type(store, ia32_AddrModeD);
2442 set_ia32_ls_mode(store, mode);
2444 set_address(store, &addr);
2445 SET_IA32_ORIG_NODE(store, node);
2451 * Transforms a Store.
2453 * @return the created ia32 Store node
2455 static ir_node *gen_Store(ir_node *node)
2457 ir_node *val = get_Store_value(node);
2458 ir_mode *mode = get_irn_mode(val);
2460 if (mode_is_float(mode) && is_Const(val)) {
2461 /* We can transform every floating const store
2462 into a sequence of integer stores.
2463 If the constant is already in a register,
2464 it would be better to use it, but we don't
2465 have this information here. */
2466 return gen_float_const_Store(node, val);
2468 return gen_general_Store(node);
2472 * Transforms a Switch.
2474 * @return the created ia32 SwitchJmp node
2476 static ir_node *create_Switch(ir_node *node)
2478 dbg_info *dbgi = get_irn_dbg_info(node);
2479 ir_node *block = be_transform_node(get_nodes_block(node));
2480 ir_node *sel = get_Cond_selector(node);
2481 ir_node *new_sel = be_transform_node(sel);
2482 int switch_min = INT_MAX;
2483 int switch_max = INT_MIN;
2484 long default_pn = get_Cond_defaultProj(node);
2486 const ir_edge_t *edge;
2488 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2490 /* determine the smallest switch case value */
2491 foreach_out_edge(node, edge) {
2492 ir_node *proj = get_edge_src_irn(edge);
2493 long pn = get_Proj_proj(proj);
2494 if (pn == default_pn)
2497 if (pn < switch_min)
2499 if (pn > switch_max)
2503 if ((unsigned) (switch_max - switch_min) > 256000) {
2504 panic("Size of switch %+F bigger than 256000", node);
2507 if (switch_min != 0) {
2508 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2510 /* if smallest switch case is not 0 we need an additional sub */
2511 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg);
2512 add_ia32_am_offs_int(new_sel, -switch_min);
2513 set_ia32_op_type(new_sel, ia32_AddrModeS);
2515 SET_IA32_ORIG_NODE(new_sel, node);
2518 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2519 SET_IA32_ORIG_NODE(new_node, node);
2525 * Transform a Cond node.
2527 static ir_node *gen_Cond(ir_node *node)
2529 ir_node *block = get_nodes_block(node);
2530 ir_node *new_block = be_transform_node(block);
2531 dbg_info *dbgi = get_irn_dbg_info(node);
2532 ir_node *sel = get_Cond_selector(node);
2533 ir_mode *sel_mode = get_irn_mode(sel);
2534 ir_node *flags = NULL;
2538 if (sel_mode != mode_b) {
2539 return create_Switch(node);
2542 /* we get flags from a Cmp */
2543 flags = get_flags_node(sel, &pnc);
2545 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2546 SET_IA32_ORIG_NODE(new_node, node);
2551 static ir_node *gen_be_Copy(ir_node *node)
2553 ir_node *new_node = be_duplicate_node(node);
2554 ir_mode *mode = get_irn_mode(new_node);
2556 if (ia32_mode_needs_gp_reg(mode)) {
2557 set_irn_mode(new_node, mode_Iu);
2563 static ir_node *create_Fucom(ir_node *node)
2565 dbg_info *dbgi = get_irn_dbg_info(node);
2566 ir_node *block = get_nodes_block(node);
2567 ir_node *new_block = be_transform_node(block);
2568 ir_node *left = get_Cmp_left(node);
2569 ir_node *new_left = be_transform_node(left);
2570 ir_node *right = get_Cmp_right(node);
2574 if (ia32_cg_config.use_fucomi) {
2575 new_right = be_transform_node(right);
2576 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2578 set_ia32_commutative(new_node);
2579 SET_IA32_ORIG_NODE(new_node, node);
2581 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2582 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2584 new_right = be_transform_node(right);
2585 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2588 set_ia32_commutative(new_node);
2590 SET_IA32_ORIG_NODE(new_node, node);
2592 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2593 SET_IA32_ORIG_NODE(new_node, node);
2599 static ir_node *create_Ucomi(ir_node *node)
2601 dbg_info *dbgi = get_irn_dbg_info(node);
2602 ir_node *src_block = get_nodes_block(node);
2603 ir_node *new_block = be_transform_node(src_block);
2604 ir_node *left = get_Cmp_left(node);
2605 ir_node *right = get_Cmp_right(node);
2607 ia32_address_mode_t am;
2608 ia32_address_t *addr = &am.addr;
2610 match_arguments(&am, src_block, left, right, NULL,
2611 match_commutative | match_am);
2613 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2614 addr->mem, am.new_op1, am.new_op2,
2616 set_am_attributes(new_node, &am);
2618 SET_IA32_ORIG_NODE(new_node, node);
2620 new_node = fix_mem_proj(new_node, &am);
2626 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2627 * to fold an and into a test node
2629 static bool can_fold_test_and(ir_node *node)
2631 const ir_edge_t *edge;
2633 /** we can only have eq and lg projs */
2634 foreach_out_edge(node, edge) {
2635 ir_node *proj = get_edge_src_irn(edge);
2636 pn_Cmp pnc = get_Proj_proj(proj);
2637 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2645 * returns true if it is assured, that the upper bits of a node are "clean"
2646 * which means for a 16 or 8 bit value, that the upper bits in the register
2647 * are 0 for unsigned and a copy of the last significant bit for signed
2650 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2652 assert(ia32_mode_needs_gp_reg(mode));
2653 if (get_mode_size_bits(mode) >= 32)
2656 if (is_Proj(transformed_node))
2657 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2659 switch (get_ia32_irn_opcode(transformed_node)) {
2660 case iro_ia32_Conv_I2I:
2661 case iro_ia32_Conv_I2I8Bit: {
2662 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2663 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2665 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2672 if (mode_is_signed(mode)) {
2673 return false; /* TODO handle signed modes */
2675 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2676 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2677 const ia32_immediate_attr_t *attr
2678 = get_ia32_immediate_attr_const(right);
2679 if (attr->symconst == 0 &&
2680 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2684 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2688 /* TODO too conservative if shift amount is constant */
2689 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2692 if (!mode_is_signed(mode)) {
2694 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2695 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2697 /* TODO if one is known to be zero extended, then || is sufficient */
2702 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2703 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2705 case iro_ia32_Const:
2706 case iro_ia32_Immediate: {
2707 const ia32_immediate_attr_t *attr =
2708 get_ia32_immediate_attr_const(transformed_node);
2709 if (mode_is_signed(mode)) {
2710 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2711 return shifted == 0 || shifted == -1;
2713 unsigned long shifted = (unsigned long)attr->offset;
2714 shifted >>= get_mode_size_bits(mode);
2715 return shifted == 0;
2725 * Generate code for a Cmp.
2727 static ir_node *gen_Cmp(ir_node *node)
2729 dbg_info *dbgi = get_irn_dbg_info(node);
2730 ir_node *block = get_nodes_block(node);
2731 ir_node *new_block = be_transform_node(block);
2732 ir_node *left = get_Cmp_left(node);
2733 ir_node *right = get_Cmp_right(node);
2734 ir_mode *cmp_mode = get_irn_mode(left);
2736 ia32_address_mode_t am;
2737 ia32_address_t *addr = &am.addr;
2740 if (mode_is_float(cmp_mode)) {
2741 if (ia32_cg_config.use_sse2) {
2742 return create_Ucomi(node);
2744 return create_Fucom(node);
2748 assert(ia32_mode_needs_gp_reg(cmp_mode));
2750 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2751 cmp_unsigned = !mode_is_signed(cmp_mode);
2752 if (is_Const_0(right) &&
2754 get_irn_n_edges(left) == 1 &&
2755 can_fold_test_and(node)) {
2756 /* Test(and_left, and_right) */
2757 ir_node *and_left = get_And_left(left);
2758 ir_node *and_right = get_And_right(left);
2760 /* matze: code here used mode instead of cmd_mode, I think it is always
2761 * the same as cmp_mode, but I leave this here to see if this is really
2764 assert(get_irn_mode(and_left) == cmp_mode);
2766 match_arguments(&am, block, and_left, and_right, NULL,
2768 match_am | match_8bit_am | match_16bit_am |
2769 match_am_and_immediates | match_immediate);
2771 /* use 32bit compare mode if possible since the opcode is smaller */
2772 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2773 upper_bits_clean(am.new_op2, cmp_mode)) {
2774 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2777 if (get_mode_size_bits(cmp_mode) == 8) {
2778 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2779 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2782 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2783 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2786 /* Cmp(left, right) */
2787 match_arguments(&am, block, left, right, NULL,
2788 match_commutative | match_am | match_8bit_am |
2789 match_16bit_am | match_am_and_immediates |
2791 /* use 32bit compare mode if possible since the opcode is smaller */
2792 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2793 upper_bits_clean(am.new_op2, cmp_mode)) {
2794 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2797 if (get_mode_size_bits(cmp_mode) == 8) {
2798 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2799 addr->index, addr->mem, am.new_op1,
2800 am.new_op2, am.ins_permuted,
2803 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2804 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2807 set_am_attributes(new_node, &am);
2808 set_ia32_ls_mode(new_node, cmp_mode);
2810 SET_IA32_ORIG_NODE(new_node, node);
2812 new_node = fix_mem_proj(new_node, &am);
2817 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2820 dbg_info *dbgi = get_irn_dbg_info(node);
2821 ir_node *block = get_nodes_block(node);
2822 ir_node *new_block = be_transform_node(block);
2823 ir_node *val_true = get_Mux_true(node);
2824 ir_node *val_false = get_Mux_false(node);
2826 ia32_address_mode_t am;
2827 ia32_address_t *addr;
2829 assert(ia32_cg_config.use_cmov);
2830 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2834 match_arguments(&am, block, val_false, val_true, flags,
2835 match_commutative | match_am | match_16bit_am | match_mode_neutral);
2837 new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2838 addr->mem, am.new_op1, am.new_op2, new_flags,
2839 am.ins_permuted, pnc);
2840 set_am_attributes(new_node, &am);
2842 SET_IA32_ORIG_NODE(new_node, node);
2844 new_node = fix_mem_proj(new_node, &am);
2850 * Creates a ia32 Setcc instruction.
2852 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2853 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2856 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2857 ir_node *nomem = new_NoMem();
2858 ir_mode *mode = get_irn_mode(orig_node);
2861 new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2862 SET_IA32_ORIG_NODE(new_node, orig_node);
2864 /* we might need to conv the result up */
2865 if (get_mode_size_bits(mode) > 8) {
2866 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg, noreg,
2867 nomem, new_node, mode_Bu);
2868 SET_IA32_ORIG_NODE(new_node, orig_node);
2875 * Create instruction for an unsigned Difference or Zero.
2877 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2879 ir_graph *irg = current_ir_graph;
2880 ir_mode *mode = get_irn_mode(psi);
2881 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2884 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2885 match_mode_neutral | match_am | match_immediate | match_two_users);
2887 block = get_nodes_block(new_node);
2889 if (is_Proj(new_node)) {
2890 sub = get_Proj_pred(new_node);
2891 assert(is_ia32_Sub(sub));
2894 set_irn_mode(sub, mode_T);
2895 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2897 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2899 dbgi = get_irn_dbg_info(psi);
2900 noreg = ia32_new_NoReg_gp(env_cg);
2901 tmpreg = new_bd_ia32_ProduceVal(dbgi, block);
2902 nomem = new_NoMem();
2903 sbb = new_bd_ia32_Sbb(dbgi, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2905 new_node = new_bd_ia32_And(dbgi, block, noreg, noreg, nomem, new_node, sbb);
2906 set_ia32_commutative(new_node);
2911 * Transforms a Mux node into CMov.
2913 * @return The transformed node.
2915 static ir_node *gen_Mux(ir_node *node)
2917 dbg_info *dbgi = get_irn_dbg_info(node);
2918 ir_node *block = get_nodes_block(node);
2919 ir_node *new_block = be_transform_node(block);
2920 ir_node *mux_true = get_Mux_true(node);
2921 ir_node *mux_false = get_Mux_false(node);
2922 ir_node *cond = get_Mux_sel(node);
2923 ir_mode *mode = get_irn_mode(node);
2926 assert(get_irn_mode(cond) == mode_b);
2928 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2929 if (mode_is_float(mode)) {
2930 ir_node *cmp = get_Proj_pred(cond);
2931 ir_node *cmp_left = get_Cmp_left(cmp);
2932 ir_node *cmp_right = get_Cmp_right(cmp);
2933 pn_Cmp pnc = get_Proj_proj(cond);
2935 if (ia32_cg_config.use_sse2) {
2936 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2937 if (cmp_left == mux_true && cmp_right == mux_false) {
2938 /* Mux(a <= b, a, b) => MIN */
2939 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2940 match_commutative | match_am | match_two_users);
2941 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2942 /* Mux(a <= b, b, a) => MAX */
2943 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2944 match_commutative | match_am | match_two_users);
2946 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2947 if (cmp_left == mux_true && cmp_right == mux_false) {
2948 /* Mux(a >= b, a, b) => MAX */
2949 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2950 match_commutative | match_am | match_two_users);
2951 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2952 /* Mux(a >= b, b, a) => MIN */
2953 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2954 match_commutative | match_am | match_two_users);
2958 panic("cannot transform floating point Mux");
2964 assert(ia32_mode_needs_gp_reg(mode));
2966 if (is_Proj(cond)) {
2967 ir_node *cmp = get_Proj_pred(cond);
2969 ir_node *cmp_left = get_Cmp_left(cmp);
2970 ir_node *cmp_right = get_Cmp_right(cmp);
2971 pn_Cmp pnc = get_Proj_proj(cond);
2973 /* check for unsigned Doz first */
2974 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2975 is_Const_0(mux_false) && is_Sub(mux_true) &&
2976 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2977 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2978 return create_Doz(node, cmp_left, cmp_right);
2979 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2980 is_Const_0(mux_true) && is_Sub(mux_false) &&
2981 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2982 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2983 return create_Doz(node, cmp_left, cmp_right);
2988 flags = get_flags_node(cond, &pnc);
2990 if (is_Const(mux_true) && is_Const(mux_false)) {
2991 /* both are const, good */
2992 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2993 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2994 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2995 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2997 /* Not that simple. */
3002 new_node = create_CMov(node, cond, flags, pnc);
3010 * Create a conversion from x87 state register to general purpose.
3012 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3014 ir_node *block = be_transform_node(get_nodes_block(node));
3015 ir_node *op = get_Conv_op(node);
3016 ir_node *new_op = be_transform_node(op);
3017 ia32_code_gen_t *cg = env_cg;
3018 ir_graph *irg = current_ir_graph;
3019 dbg_info *dbgi = get_irn_dbg_info(node);
3020 ir_node *noreg = ia32_new_NoReg_gp(cg);
3021 ir_mode *mode = get_irn_mode(node);
3022 ir_node *fist, *load, *mem;
3024 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3025 set_irn_pinned(fist, op_pin_state_floats);
3026 set_ia32_use_frame(fist);
3027 set_ia32_op_type(fist, ia32_AddrModeD);
3029 assert(get_mode_size_bits(mode) <= 32);
3030 /* exception we can only store signed 32 bit integers, so for unsigned
3031 we store a 64bit (signed) integer and load the lower bits */
3032 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3033 set_ia32_ls_mode(fist, mode_Ls);
3035 set_ia32_ls_mode(fist, mode_Is);
3037 SET_IA32_ORIG_NODE(fist, node);
3040 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg, mem);
3042 set_irn_pinned(load, op_pin_state_floats);
3043 set_ia32_use_frame(load);
3044 set_ia32_op_type(load, ia32_AddrModeS);
3045 set_ia32_ls_mode(load, mode_Is);
3046 if (get_ia32_ls_mode(fist) == mode_Ls) {
3047 ia32_attr_t *attr = get_ia32_attr(load);
3048 attr->data.need_64bit_stackent = 1;
3050 ia32_attr_t *attr = get_ia32_attr(load);
3051 attr->data.need_32bit_stackent = 1;
3053 SET_IA32_ORIG_NODE(load, node);
3055 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3059 * Creates a x87 strict Conv by placing a Store and a Load
3061 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3063 ir_node *block = get_nodes_block(node);
3064 ir_graph *irg = current_ir_graph;
3065 dbg_info *dbgi = get_irn_dbg_info(node);
3066 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3067 ir_node *nomem = new_NoMem();
3068 ir_node *frame = get_irg_frame(irg);
3069 ir_node *store, *load;
3072 store = new_bd_ia32_vfst(dbgi, block, frame, noreg, nomem, node, tgt_mode);
3073 set_ia32_use_frame(store);
3074 set_ia32_op_type(store, ia32_AddrModeD);
3075 SET_IA32_ORIG_NODE(store, node);
3077 load = new_bd_ia32_vfld(dbgi, block, frame, noreg, store, tgt_mode);
3078 set_ia32_use_frame(load);
3079 set_ia32_op_type(load, ia32_AddrModeS);
3080 SET_IA32_ORIG_NODE(load, node);
3082 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3086 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3087 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3089 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3091 func = get_mode_size_bits(mode) == 8 ?
3092 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3093 return func(dbgi, block, base, index, mem, val, mode);
3097 * Create a conversion from general purpose to x87 register
3099 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3101 ir_node *src_block = get_nodes_block(node);
3102 ir_node *block = be_transform_node(src_block);
3103 ir_graph *irg = current_ir_graph;
3104 dbg_info *dbgi = get_irn_dbg_info(node);
3105 ir_node *op = get_Conv_op(node);
3106 ir_node *new_op = NULL;
3110 ir_mode *store_mode;
3115 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3116 if (possible_int_mode_for_fp(src_mode)) {
3117 ia32_address_mode_t am;
3119 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3120 if (am.op_type == ia32_AddrModeS) {
3121 ia32_address_t *addr = &am.addr;
3123 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index,
3125 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3128 set_am_attributes(fild, &am);
3129 SET_IA32_ORIG_NODE(fild, node);
3131 fix_mem_proj(fild, &am);
3136 if (new_op == NULL) {
3137 new_op = be_transform_node(op);
3140 noreg = ia32_new_NoReg_gp(env_cg);
3141 nomem = new_NoMem();
3142 mode = get_irn_mode(op);
3144 /* first convert to 32 bit signed if necessary */
3145 if (get_mode_size_bits(src_mode) < 32) {
3146 if (!upper_bits_clean(new_op, src_mode)) {
3147 new_op = create_Conv_I2I(dbgi, block, noreg, noreg, nomem, new_op, src_mode);
3148 SET_IA32_ORIG_NODE(new_op, node);
3153 assert(get_mode_size_bits(mode) == 32);
3156 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg, nomem,
3159 set_ia32_use_frame(store);
3160 set_ia32_op_type(store, ia32_AddrModeD);
3161 set_ia32_ls_mode(store, mode_Iu);
3163 /* exception for 32bit unsigned, do a 64bit spill+load */
3164 if (!mode_is_signed(mode)) {
3167 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3169 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3170 noreg, nomem, zero_const);
3172 set_ia32_use_frame(zero_store);
3173 set_ia32_op_type(zero_store, ia32_AddrModeD);
3174 add_ia32_am_offs_int(zero_store, 4);
3175 set_ia32_ls_mode(zero_store, mode_Iu);
3180 store = new_rd_Sync(dbgi, irg, block, 2, in);
3181 store_mode = mode_Ls;
3183 store_mode = mode_Is;
3187 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg, store);
3189 set_ia32_use_frame(fild);
3190 set_ia32_op_type(fild, ia32_AddrModeS);
3191 set_ia32_ls_mode(fild, store_mode);
3193 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3199 * Create a conversion from one integer mode into another one
3201 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3202 dbg_info *dbgi, ir_node *block, ir_node *op,
3205 ir_node *new_block = be_transform_node(block);
3207 ir_mode *smaller_mode;
3208 ia32_address_mode_t am;
3209 ia32_address_t *addr = &am.addr;
3212 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3213 smaller_mode = src_mode;
3215 smaller_mode = tgt_mode;
3218 #ifdef DEBUG_libfirm
3220 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3225 match_arguments(&am, block, NULL, op, NULL,
3226 match_am | match_8bit_am | match_16bit_am);
3228 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3229 /* unnecessary conv. in theory it shouldn't have been AM */
3230 assert(is_ia32_NoReg_GP(addr->base));
3231 assert(is_ia32_NoReg_GP(addr->index));
3232 assert(is_NoMem(addr->mem));
3233 assert(am.addr.offset == 0);
3234 assert(am.addr.symconst_ent == NULL);
3238 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3239 addr->mem, am.new_op2, smaller_mode);
3240 set_am_attributes(new_node, &am);
3241 /* match_arguments assume that out-mode = in-mode, this isn't true here
3243 set_ia32_ls_mode(new_node, smaller_mode);
3244 SET_IA32_ORIG_NODE(new_node, node);
3245 new_node = fix_mem_proj(new_node, &am);
3250 * Transforms a Conv node.
3252 * @return The created ia32 Conv node
3254 static ir_node *gen_Conv(ir_node *node)
3256 ir_node *block = get_nodes_block(node);
3257 ir_node *new_block = be_transform_node(block);
3258 ir_node *op = get_Conv_op(node);
3259 ir_node *new_op = NULL;
3260 dbg_info *dbgi = get_irn_dbg_info(node);
3261 ir_mode *src_mode = get_irn_mode(op);
3262 ir_mode *tgt_mode = get_irn_mode(node);
3263 int src_bits = get_mode_size_bits(src_mode);
3264 int tgt_bits = get_mode_size_bits(tgt_mode);
3265 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3266 ir_node *nomem = new_NoMem();
3267 ir_node *res = NULL;
3269 assert(!mode_is_int(src_mode) || src_bits <= 32);
3270 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3272 if (src_mode == mode_b) {
3273 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3274 /* nothing to do, we already model bools as 0/1 ints */
3275 return be_transform_node(op);
3278 if (src_mode == tgt_mode) {
3279 if (get_Conv_strict(node)) {
3280 if (ia32_cg_config.use_sse2) {
3281 /* when we are in SSE mode, we can kill all strict no-op conversion */
3282 return be_transform_node(op);
3285 /* this should be optimized already, but who knows... */
3286 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3287 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3288 return be_transform_node(op);
3292 if (mode_is_float(src_mode)) {
3293 new_op = be_transform_node(op);
3294 /* we convert from float ... */
3295 if (mode_is_float(tgt_mode)) {
3296 if (src_mode == mode_E && tgt_mode == mode_D
3297 && !get_Conv_strict(node)) {
3298 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3303 if (ia32_cg_config.use_sse2) {
3304 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3305 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg, noreg,
3307 set_ia32_ls_mode(res, tgt_mode);
3309 if (get_Conv_strict(node)) {
3310 res = gen_x87_strict_conv(tgt_mode, new_op);
3311 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3314 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3319 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3320 if (ia32_cg_config.use_sse2) {
3321 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg, noreg,
3323 set_ia32_ls_mode(res, src_mode);
3325 return gen_x87_fp_to_gp(node);
3329 /* we convert from int ... */
3330 if (mode_is_float(tgt_mode)) {
3332 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3333 if (ia32_cg_config.use_sse2) {
3334 new_op = be_transform_node(op);
3335 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg, noreg,
3337 set_ia32_ls_mode(res, tgt_mode);
3339 res = gen_x87_gp_to_fp(node, src_mode);
3340 if (get_Conv_strict(node)) {
3341 /* The strict-Conv is only necessary, if the int mode has more bits
3342 * than the float mantissa */
3343 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3344 size_t float_mantissa;
3345 /* FIXME There is no way to get the mantissa size of a mode */
3346 switch (get_mode_size_bits(tgt_mode)) {
3347 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3348 case 64: float_mantissa = 52 + 1; break;
3350 case 96: float_mantissa = 64; break;
3351 default: float_mantissa = 0; break;
3353 if (float_mantissa < int_mantissa) {
3354 res = gen_x87_strict_conv(tgt_mode, res);
3355 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3360 } else if (tgt_mode == mode_b) {
3361 /* mode_b lowering already took care that we only have 0/1 values */
3362 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3363 src_mode, tgt_mode));
3364 return be_transform_node(op);
3367 if (src_bits == tgt_bits) {
3368 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3369 src_mode, tgt_mode));
3370 return be_transform_node(op);
3373 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3381 static ir_node *create_immediate_or_transform(ir_node *node,
3382 char immediate_constraint_type)
3384 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3385 if (new_node == NULL) {
3386 new_node = be_transform_node(node);
3392 * Transforms a FrameAddr into an ia32 Add.
3394 static ir_node *gen_be_FrameAddr(ir_node *node)
3396 ir_node *block = be_transform_node(get_nodes_block(node));
3397 ir_node *op = be_get_FrameAddr_frame(node);
3398 ir_node *new_op = be_transform_node(op);
3399 dbg_info *dbgi = get_irn_dbg_info(node);
3400 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3403 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg);
3404 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3405 set_ia32_use_frame(new_node);
3407 SET_IA32_ORIG_NODE(new_node, node);
3413 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3415 static ir_node *gen_be_Return(ir_node *node)
3417 ir_graph *irg = current_ir_graph;
3418 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3419 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3420 ir_entity *ent = get_irg_entity(irg);
3421 ir_type *tp = get_entity_type(ent);
3426 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3427 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3430 int pn_ret_val, pn_ret_mem, arity, i;
3432 assert(ret_val != NULL);
3433 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3434 return be_duplicate_node(node);
3437 res_type = get_method_res_type(tp, 0);
3439 if (! is_Primitive_type(res_type)) {
3440 return be_duplicate_node(node);
3443 mode = get_type_mode(res_type);
3444 if (! mode_is_float(mode)) {
3445 return be_duplicate_node(node);
3448 assert(get_method_n_ress(tp) == 1);
3450 pn_ret_val = get_Proj_proj(ret_val);
3451 pn_ret_mem = get_Proj_proj(ret_mem);
3453 /* get the Barrier */
3454 barrier = get_Proj_pred(ret_val);
3456 /* get result input of the Barrier */
3457 ret_val = get_irn_n(barrier, pn_ret_val);
3458 new_ret_val = be_transform_node(ret_val);
3460 /* get memory input of the Barrier */
3461 ret_mem = get_irn_n(barrier, pn_ret_mem);
3462 new_ret_mem = be_transform_node(ret_mem);
3464 frame = get_irg_frame(irg);
3466 dbgi = get_irn_dbg_info(barrier);
3467 block = be_transform_node(get_nodes_block(barrier));
3469 noreg = ia32_new_NoReg_gp(env_cg);
3471 /* store xmm0 onto stack */
3472 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg,
3473 new_ret_mem, new_ret_val);
3474 set_ia32_ls_mode(sse_store, mode);
3475 set_ia32_op_type(sse_store, ia32_AddrModeD);
3476 set_ia32_use_frame(sse_store);
3478 /* load into x87 register */
3479 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg, sse_store, mode);
3480 set_ia32_op_type(fld, ia32_AddrModeS);
3481 set_ia32_use_frame(fld);
3483 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3484 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3486 /* create a new barrier */
3487 arity = get_irn_arity(barrier);
3488 in = ALLOCAN(ir_node*, arity);
3489 for (i = 0; i < arity; ++i) {
3492 if (i == pn_ret_val) {
3494 } else if (i == pn_ret_mem) {
3497 ir_node *in = get_irn_n(barrier, i);
3498 new_in = be_transform_node(in);
3503 new_barrier = new_ir_node(dbgi, irg, block,
3504 get_irn_op(barrier), get_irn_mode(barrier),
3506 copy_node_attr(barrier, new_barrier);
3507 be_duplicate_deps(barrier, new_barrier);
3508 be_set_transformed_node(barrier, new_barrier);
3510 /* transform normally */
3511 return be_duplicate_node(node);
3515 * Transform a be_AddSP into an ia32_SubSP.
3517 static ir_node *gen_be_AddSP(ir_node *node)
3519 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3520 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3522 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3523 match_am | match_immediate);
3527 * Transform a be_SubSP into an ia32_AddSP
3529 static ir_node *gen_be_SubSP(ir_node *node)
3531 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3532 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3534 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3535 match_am | match_immediate);
3539 * Change some phi modes
3541 static ir_node *gen_Phi(ir_node *node)
3543 ir_node *block = be_transform_node(get_nodes_block(node));
3544 ir_graph *irg = current_ir_graph;
3545 dbg_info *dbgi = get_irn_dbg_info(node);
3546 ir_mode *mode = get_irn_mode(node);
3549 if (ia32_mode_needs_gp_reg(mode)) {
3550 /* we shouldn't have any 64bit stuff around anymore */
3551 assert(get_mode_size_bits(mode) <= 32);
3552 /* all integer operations are on 32bit registers now */
3554 } else if (mode_is_float(mode)) {
3555 if (ia32_cg_config.use_sse2) {
3562 /* phi nodes allow loops, so we use the old arguments for now
3563 * and fix this later */
3564 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3565 get_irn_in(node) + 1);
3566 copy_node_attr(node, phi);
3567 be_duplicate_deps(node, phi);
3569 be_enqueue_preds(node);
3577 static ir_node *gen_IJmp(ir_node *node)
3579 ir_node *block = get_nodes_block(node);
3580 ir_node *new_block = be_transform_node(block);
3581 dbg_info *dbgi = get_irn_dbg_info(node);
3582 ir_node *op = get_IJmp_target(node);
3584 ia32_address_mode_t am;
3585 ia32_address_t *addr = &am.addr;
3587 assert(get_irn_mode(op) == mode_P);
3589 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3591 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3592 addr->mem, am.new_op2);
3593 set_am_attributes(new_node, &am);
3594 SET_IA32_ORIG_NODE(new_node, node);
3596 new_node = fix_mem_proj(new_node, &am);
3602 * Transform a Bound node.
3604 static ir_node *gen_Bound(ir_node *node)
3607 ir_node *lower = get_Bound_lower(node);
3608 dbg_info *dbgi = get_irn_dbg_info(node);
3610 if (is_Const_0(lower)) {
3611 /* typical case for Java */
3612 ir_node *sub, *res, *flags, *block;
3613 ir_graph *irg = current_ir_graph;
3615 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3616 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3618 block = get_nodes_block(res);
3619 if (! is_Proj(res)) {
3621 set_irn_mode(sub, mode_T);
3622 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3624 sub = get_Proj_pred(res);
3626 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3627 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3628 SET_IA32_ORIG_NODE(new_node, node);
3630 panic("generic Bound not supported in ia32 Backend");
3636 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3638 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3639 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3641 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3642 match_immediate | match_mode_neutral);
3645 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3647 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3648 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3649 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3653 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3655 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3656 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3657 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3661 static ir_node *gen_ia32_l_Add(ir_node *node)
3663 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3664 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3665 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3666 match_commutative | match_am | match_immediate |
3667 match_mode_neutral);
3669 if (is_Proj(lowered)) {
3670 lowered = get_Proj_pred(lowered);
3672 assert(is_ia32_Add(lowered));
3673 set_irn_mode(lowered, mode_T);
3679 static ir_node *gen_ia32_l_Adc(ir_node *node)
3681 return gen_binop_flags(node, new_bd_ia32_Adc,
3682 match_commutative | match_am | match_immediate |
3683 match_mode_neutral);
3687 * Transforms a l_MulS into a "real" MulS node.
3689 * @return the created ia32 Mul node
3691 static ir_node *gen_ia32_l_Mul(ir_node *node)
3693 ir_node *left = get_binop_left(node);
3694 ir_node *right = get_binop_right(node);
3696 return gen_binop(node, left, right, new_bd_ia32_Mul,
3697 match_commutative | match_am | match_mode_neutral);
3701 * Transforms a l_IMulS into a "real" IMul1OPS node.
3703 * @return the created ia32 IMul1OP node
3705 static ir_node *gen_ia32_l_IMul(ir_node *node)
3707 ir_node *left = get_binop_left(node);
3708 ir_node *right = get_binop_right(node);
3710 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3711 match_commutative | match_am | match_mode_neutral);
3714 static ir_node *gen_ia32_l_Sub(ir_node *node)
3716 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3717 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3718 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3719 match_am | match_immediate | match_mode_neutral);
3721 if (is_Proj(lowered)) {
3722 lowered = get_Proj_pred(lowered);
3724 assert(is_ia32_Sub(lowered));
3725 set_irn_mode(lowered, mode_T);
3731 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3733 return gen_binop_flags(node, new_bd_ia32_Sbb,
3734 match_am | match_immediate | match_mode_neutral);
3738 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3739 * op1 - target to be shifted
3740 * op2 - contains bits to be shifted into target
3742 * Only op3 can be an immediate.
3744 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3745 ir_node *low, ir_node *count)
3747 ir_node *block = get_nodes_block(node);
3748 ir_node *new_block = be_transform_node(block);
3749 dbg_info *dbgi = get_irn_dbg_info(node);
3750 ir_node *new_high = be_transform_node(high);
3751 ir_node *new_low = be_transform_node(low);
3755 /* the shift amount can be any mode that is bigger than 5 bits, since all
3756 * other bits are ignored anyway */
3757 while (is_Conv(count) &&
3758 get_irn_n_edges(count) == 1 &&
3759 mode_is_int(get_irn_mode(count))) {
3760 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3761 count = get_Conv_op(count);
3763 new_count = create_immediate_or_transform(count, 0);
3765 if (is_ia32_l_ShlD(node)) {
3766 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3769 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3772 SET_IA32_ORIG_NODE(new_node, node);
3777 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3779 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3780 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3781 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3782 return gen_lowered_64bit_shifts(node, high, low, count);
3785 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3787 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3788 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3789 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3790 return gen_lowered_64bit_shifts(node, high, low, count);
3793 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3795 ir_node *src_block = get_nodes_block(node);
3796 ir_node *block = be_transform_node(src_block);
3797 ir_graph *irg = current_ir_graph;
3798 dbg_info *dbgi = get_irn_dbg_info(node);
3799 ir_node *frame = get_irg_frame(irg);
3800 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3801 ir_node *nomem = new_NoMem();
3802 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3803 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3804 ir_node *new_val_low = be_transform_node(val_low);
3805 ir_node *new_val_high = be_transform_node(val_high);
3807 ir_node *sync, *fild, *res;
3808 ir_node *store_low, *store_high;
3810 if (ia32_cg_config.use_sse2) {
3811 panic("ia32_l_LLtoFloat not implemented for SSE2");
3815 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3817 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3819 SET_IA32_ORIG_NODE(store_low, node);
3820 SET_IA32_ORIG_NODE(store_high, node);
3822 set_ia32_use_frame(store_low);
3823 set_ia32_use_frame(store_high);
3824 set_ia32_op_type(store_low, ia32_AddrModeD);
3825 set_ia32_op_type(store_high, ia32_AddrModeD);
3826 set_ia32_ls_mode(store_low, mode_Iu);
3827 set_ia32_ls_mode(store_high, mode_Is);
3828 add_ia32_am_offs_int(store_high, 4);
3832 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3835 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg, sync);
3837 set_ia32_use_frame(fild);
3838 set_ia32_op_type(fild, ia32_AddrModeS);
3839 set_ia32_ls_mode(fild, mode_Ls);
3841 SET_IA32_ORIG_NODE(fild, node);
3843 res = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3845 if (! mode_is_signed(get_irn_mode(val_high))) {
3846 ia32_address_mode_t am;
3848 ir_node *count = create_Immediate(NULL, 0, 31);
3851 am.addr.base = ia32_new_NoReg_gp(env_cg);
3852 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
3853 am.addr.mem = nomem;
3856 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
3857 am.addr.use_frame = 0;
3858 am.addr.frame_entity = NULL;
3859 am.addr.symconst_sign = 0;
3860 am.ls_mode = mode_F;
3861 am.mem_proj = nomem;
3862 am.op_type = ia32_AddrModeS;
3864 am.new_op2 = ia32_new_NoReg_vfp(env_cg);
3865 am.pinned = op_pin_state_floats;
3867 am.ins_permuted = 0;
3869 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
3870 am.new_op1, am.new_op2, get_fpcw());
3871 set_am_attributes(fadd, &am);
3873 set_irn_mode(fadd, mode_T);
3874 res = new_rd_Proj(NULL, irg, block, fadd, mode_vfp, pn_ia32_res);
3879 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3881 ir_node *src_block = get_nodes_block(node);
3882 ir_node *block = be_transform_node(src_block);
3883 ir_graph *irg = current_ir_graph;
3884 dbg_info *dbgi = get_irn_dbg_info(node);
3885 ir_node *frame = get_irg_frame(irg);
3886 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3887 ir_node *nomem = new_NoMem();
3888 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3889 ir_node *new_val = be_transform_node(val);
3890 ir_node *fist, *mem;
3892 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3893 SET_IA32_ORIG_NODE(fist, node);
3894 set_ia32_use_frame(fist);
3895 set_ia32_op_type(fist, ia32_AddrModeD);
3896 set_ia32_ls_mode(fist, mode_Ls);
3902 * the BAD transformer.
3904 static ir_node *bad_transform(ir_node *node)
3906 panic("No transform function for %+F available.", node);
3910 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3912 ir_graph *irg = current_ir_graph;
3913 ir_node *block = be_transform_node(get_nodes_block(node));
3914 ir_node *pred = get_Proj_pred(node);
3915 ir_node *new_pred = be_transform_node(pred);
3916 ir_node *frame = get_irg_frame(irg);
3917 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3918 dbg_info *dbgi = get_irn_dbg_info(node);
3919 long pn = get_Proj_proj(node);
3924 load = new_bd_ia32_Load(dbgi, block, frame, noreg, new_pred);
3925 SET_IA32_ORIG_NODE(load, node);
3926 set_ia32_use_frame(load);
3927 set_ia32_op_type(load, ia32_AddrModeS);
3928 set_ia32_ls_mode(load, mode_Iu);
3929 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3930 * 32 bit from it with this particular load */
3931 attr = get_ia32_attr(load);
3932 attr->data.need_64bit_stackent = 1;
3934 if (pn == pn_ia32_l_FloattoLL_res_high) {
3935 add_ia32_am_offs_int(load, 4);
3937 assert(pn == pn_ia32_l_FloattoLL_res_low);
3940 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3946 * Transform the Projs of an AddSP.
3948 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3950 ir_node *block = be_transform_node(get_nodes_block(node));
3951 ir_node *pred = get_Proj_pred(node);
3952 ir_node *new_pred = be_transform_node(pred);
3953 ir_graph *irg = current_ir_graph;
3954 dbg_info *dbgi = get_irn_dbg_info(node);
3955 long proj = get_Proj_proj(node);
3957 if (proj == pn_be_AddSP_sp) {
3958 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3959 pn_ia32_SubSP_stack);
3960 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3962 } else if (proj == pn_be_AddSP_res) {
3963 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3964 pn_ia32_SubSP_addr);
3965 } else if (proj == pn_be_AddSP_M) {
3966 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3969 panic("No idea how to transform proj->AddSP");
3973 * Transform the Projs of a SubSP.
3975 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3977 ir_node *block = be_transform_node(get_nodes_block(node));
3978 ir_node *pred = get_Proj_pred(node);
3979 ir_node *new_pred = be_transform_node(pred);
3980 ir_graph *irg = current_ir_graph;
3981 dbg_info *dbgi = get_irn_dbg_info(node);
3982 long proj = get_Proj_proj(node);
3984 if (proj == pn_be_SubSP_sp) {
3985 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3986 pn_ia32_AddSP_stack);
3987 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3989 } else if (proj == pn_be_SubSP_M) {
3990 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3993 panic("No idea how to transform proj->SubSP");
3997 * Transform and renumber the Projs from a Load.
3999 static ir_node *gen_Proj_Load(ir_node *node)
4002 ir_node *block = be_transform_node(get_nodes_block(node));
4003 ir_node *pred = get_Proj_pred(node);
4004 ir_graph *irg = current_ir_graph;
4005 dbg_info *dbgi = get_irn_dbg_info(node);
4006 long proj = get_Proj_proj(node);
4008 /* loads might be part of source address mode matches, so we don't
4009 * transform the ProjMs yet (with the exception of loads whose result is
4012 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4015 /* this is needed, because sometimes we have loops that are only
4016 reachable through the ProjM */
4017 be_enqueue_preds(node);
4018 /* do it in 2 steps, to silence firm verifier */
4019 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4020 set_Proj_proj(res, pn_ia32_mem);
4024 /* renumber the proj */
4025 new_pred = be_transform_node(pred);
4026 if (is_ia32_Load(new_pred)) {
4029 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4031 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4032 case pn_Load_X_regular:
4033 return new_rd_Jmp(dbgi, irg, block);
4034 case pn_Load_X_except:
4035 /* This Load might raise an exception. Mark it. */
4036 set_ia32_exc_label(new_pred, 1);
4037 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4041 } else if (is_ia32_Conv_I2I(new_pred) ||
4042 is_ia32_Conv_I2I8Bit(new_pred)) {
4043 set_irn_mode(new_pred, mode_T);
4044 if (proj == pn_Load_res) {
4045 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4046 } else if (proj == pn_Load_M) {
4047 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4049 } else if (is_ia32_xLoad(new_pred)) {
4052 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4054 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4055 case pn_Load_X_regular:
4056 return new_rd_Jmp(dbgi, irg, block);
4057 case pn_Load_X_except:
4058 /* This Load might raise an exception. Mark it. */
4059 set_ia32_exc_label(new_pred, 1);
4060 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4064 } else if (is_ia32_vfld(new_pred)) {
4067 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4069 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4070 case pn_Load_X_regular:
4071 return new_rd_Jmp(dbgi, irg, block);
4072 case pn_Load_X_except:
4073 /* This Load might raise an exception. Mark it. */
4074 set_ia32_exc_label(new_pred, 1);
4075 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4080 /* can happen for ProJMs when source address mode happened for the
4083 /* however it should not be the result proj, as that would mean the
4084 load had multiple users and should not have been used for
4086 if (proj != pn_Load_M) {
4087 panic("internal error: transformed node not a Load");
4089 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4092 panic("No idea how to transform proj");
4096 * Transform and renumber the Projs from a DivMod like instruction.
4098 static ir_node *gen_Proj_DivMod(ir_node *node)
4100 ir_node *block = be_transform_node(get_nodes_block(node));
4101 ir_node *pred = get_Proj_pred(node);
4102 ir_node *new_pred = be_transform_node(pred);
4103 ir_graph *irg = current_ir_graph;
4104 dbg_info *dbgi = get_irn_dbg_info(node);
4105 long proj = get_Proj_proj(node);
4107 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4109 switch (get_irn_opcode(pred)) {
4113 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4115 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4116 case pn_Div_X_regular:
4117 return new_rd_Jmp(dbgi, irg, block);
4118 case pn_Div_X_except:
4119 set_ia32_exc_label(new_pred, 1);
4120 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4128 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4130 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4131 case pn_Mod_X_except:
4132 set_ia32_exc_label(new_pred, 1);
4133 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4141 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4142 case pn_DivMod_res_div:
4143 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4144 case pn_DivMod_res_mod:
4145 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4146 case pn_DivMod_X_regular:
4147 return new_rd_Jmp(dbgi, irg, block);
4148 case pn_DivMod_X_except:
4149 set_ia32_exc_label(new_pred, 1);
4150 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4159 panic("No idea how to transform proj->DivMod");
4163 * Transform and renumber the Projs from a CopyB.
4165 static ir_node *gen_Proj_CopyB(ir_node *node)
4167 ir_node *block = be_transform_node(get_nodes_block(node));
4168 ir_node *pred = get_Proj_pred(node);
4169 ir_node *new_pred = be_transform_node(pred);
4170 ir_graph *irg = current_ir_graph;
4171 dbg_info *dbgi = get_irn_dbg_info(node);
4172 long proj = get_Proj_proj(node);
4175 case pn_CopyB_M_regular:
4176 if (is_ia32_CopyB_i(new_pred)) {
4177 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4178 } else if (is_ia32_CopyB(new_pred)) {
4179 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4186 panic("No idea how to transform proj->CopyB");
4190 * Transform and renumber the Projs from a Quot.
4192 static ir_node *gen_Proj_Quot(ir_node *node)
4194 ir_node *block = be_transform_node(get_nodes_block(node));
4195 ir_node *pred = get_Proj_pred(node);
4196 ir_node *new_pred = be_transform_node(pred);
4197 ir_graph *irg = current_ir_graph;
4198 dbg_info *dbgi = get_irn_dbg_info(node);
4199 long proj = get_Proj_proj(node);
4203 if (is_ia32_xDiv(new_pred)) {
4204 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4205 } else if (is_ia32_vfdiv(new_pred)) {
4206 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4210 if (is_ia32_xDiv(new_pred)) {
4211 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4212 } else if (is_ia32_vfdiv(new_pred)) {
4213 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4216 case pn_Quot_X_regular:
4217 case pn_Quot_X_except:
4222 panic("No idea how to transform proj->Quot");
4225 static ir_node *gen_be_Call(ir_node *node)
4227 dbg_info *const dbgi = get_irn_dbg_info(node);
4228 ir_graph *const irg = current_ir_graph;
4229 ir_node *const src_block = get_nodes_block(node);
4230 ir_node *const block = be_transform_node(src_block);
4231 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4232 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4233 ir_node *const sp = be_transform_node(src_sp);
4234 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4235 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4236 ia32_address_mode_t am;
4237 ia32_address_t *const addr = &am.addr;
4242 ir_node * eax = noreg;
4243 ir_node * ecx = noreg;
4244 ir_node * edx = noreg;
4245 unsigned const pop = be_Call_get_pop(node);
4246 ir_type *const call_tp = be_Call_get_type(node);
4248 /* Run the x87 simulator if the call returns a float value */
4249 if (get_method_n_ress(call_tp) > 0) {
4250 ir_type *const res_type = get_method_res_type(call_tp, 0);
4251 ir_mode *const res_mode = get_type_mode(res_type);
4253 if (res_mode != NULL && mode_is_float(res_mode)) {
4254 env_cg->do_x87_sim = 1;
4258 /* We do not want be_Call direct calls */
4259 assert(be_Call_get_entity(node) == NULL);
4261 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4262 match_am | match_immediate);
4264 i = get_irn_arity(node) - 1;
4265 fpcw = be_transform_node(get_irn_n(node, i--));
4266 for (; i >= be_pos_Call_first_arg; --i) {
4267 arch_register_req_t const *const req = arch_get_register_req(node, i);
4268 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4270 assert(req->type == arch_register_req_type_limited);
4271 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4273 switch (*req->limited) {
4274 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4275 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4276 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4277 default: panic("Invalid GP register for register parameter");
4281 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4282 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4283 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4284 set_am_attributes(call, &am);
4285 call = fix_mem_proj(call, &am);
4287 if (get_irn_pinned(node) == op_pin_state_pinned)
4288 set_irn_pinned(call, op_pin_state_pinned);
4290 SET_IA32_ORIG_NODE(call, node);
4294 static ir_node *gen_be_IncSP(ir_node *node)
4296 ir_node *res = be_duplicate_node(node);
4297 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4303 * Transform the Projs from a be_Call.
4305 static ir_node *gen_Proj_be_Call(ir_node *node)
4307 ir_node *block = be_transform_node(get_nodes_block(node));
4308 ir_node *call = get_Proj_pred(node);
4309 ir_node *new_call = be_transform_node(call);
4310 ir_graph *irg = current_ir_graph;
4311 dbg_info *dbgi = get_irn_dbg_info(node);
4312 ir_type *method_type = be_Call_get_type(call);
4313 int n_res = get_method_n_ress(method_type);
4314 long proj = get_Proj_proj(node);
4315 ir_mode *mode = get_irn_mode(node);
4319 /* The following is kinda tricky: If we're using SSE, then we have to
4320 * move the result value of the call in floating point registers to an
4321 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4322 * after the call, we have to make sure to correctly make the
4323 * MemProj and the result Proj use these 2 nodes
4325 if (proj == pn_be_Call_M_regular) {
4326 // get new node for result, are we doing the sse load/store hack?
4327 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4328 ir_node *call_res_new;
4329 ir_node *call_res_pred = NULL;
4331 if (call_res != NULL) {
4332 call_res_new = be_transform_node(call_res);
4333 call_res_pred = get_Proj_pred(call_res_new);
4336 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4337 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4340 assert(is_ia32_xLoad(call_res_pred));
4341 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4345 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4346 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4348 ir_node *frame = get_irg_frame(irg);
4349 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4351 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4354 /* in case there is no memory output: create one to serialize the copy
4356 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4357 pn_be_Call_M_regular);
4358 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4359 pn_be_Call_first_res);
4361 /* store st(0) onto stack */
4362 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg, call_mem,
4364 set_ia32_op_type(fstp, ia32_AddrModeD);
4365 set_ia32_use_frame(fstp);
4367 /* load into SSE register */
4368 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg, fstp, mode);
4369 set_ia32_op_type(sse_load, ia32_AddrModeS);
4370 set_ia32_use_frame(sse_load);
4372 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4378 /* transform call modes */
4379 if (mode_is_data(mode)) {
4380 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4384 /* Map from be_Call to ia32_Call proj number */
4385 if (proj == pn_be_Call_sp) {
4386 proj = pn_ia32_Call_stack;
4387 } else if (proj == pn_be_Call_M_regular) {
4388 proj = pn_ia32_Call_M;
4390 arch_register_req_t const *const req = arch_get_register_req_out(node);
4391 int const n_outs = arch_irn_get_n_outs(new_call);
4394 assert(proj >= pn_be_Call_first_res);
4395 assert(req->type & arch_register_req_type_limited);
4397 for (i = 0; i < n_outs; ++i) {
4398 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4400 if (!(new_req->type & arch_register_req_type_limited) ||
4401 new_req->cls != req->cls ||
4402 *new_req->limited != *req->limited)
4411 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4413 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4415 case pn_ia32_Call_stack:
4416 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4419 case pn_ia32_Call_fpcw:
4420 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4428 * Transform the Projs from a Cmp.
4430 static ir_node *gen_Proj_Cmp(ir_node *node)
4432 /* this probably means not all mode_b nodes were lowered... */
4433 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4438 * Transform the Projs from a Bound.
4440 static ir_node *gen_Proj_Bound(ir_node *node)
4442 ir_node *new_node, *block;
4443 ir_node *pred = get_Proj_pred(node);
4445 switch (get_Proj_proj(node)) {
4447 return be_transform_node(get_Bound_mem(pred));
4448 case pn_Bound_X_regular:
4449 new_node = be_transform_node(pred);
4450 block = get_nodes_block(new_node);
4451 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4452 case pn_Bound_X_except:
4453 new_node = be_transform_node(pred);
4454 block = get_nodes_block(new_node);
4455 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4457 return be_transform_node(get_Bound_index(pred));
4459 panic("unsupported Proj from Bound");
4463 static ir_node *gen_Proj_ASM(ir_node *node)
4469 if (get_irn_mode(node) != mode_M)
4470 return be_duplicate_node(node);
4472 pred = get_Proj_pred(node);
4473 new_pred = be_transform_node(pred);
4474 block = get_nodes_block(new_pred);
4475 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4476 arch_irn_get_n_outs(new_pred) + 1);
4480 * Transform and potentially renumber Proj nodes.
4482 static ir_node *gen_Proj(ir_node *node)
4484 ir_node *pred = get_Proj_pred(node);
4487 switch (get_irn_opcode(pred)) {
4489 proj = get_Proj_proj(node);
4490 if (proj == pn_Store_M) {
4491 return be_transform_node(pred);
4493 panic("No idea how to transform proj->Store");
4496 return gen_Proj_Load(node);
4498 return gen_Proj_ASM(node);
4502 return gen_Proj_DivMod(node);
4504 return gen_Proj_CopyB(node);
4506 return gen_Proj_Quot(node);
4508 return gen_Proj_be_SubSP(node);
4510 return gen_Proj_be_AddSP(node);
4512 return gen_Proj_be_Call(node);
4514 return gen_Proj_Cmp(node);
4516 return gen_Proj_Bound(node);
4518 proj = get_Proj_proj(node);
4520 case pn_Start_X_initial_exec: {
4521 ir_node *block = get_nodes_block(pred);
4522 ir_node *new_block = be_transform_node(block);
4523 dbg_info *dbgi = get_irn_dbg_info(node);
4524 /* we exchange the ProjX with a jump */
4525 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4530 case pn_Start_P_tls:
4531 return gen_Proj_tls(node);
4536 if (is_ia32_l_FloattoLL(pred)) {
4537 return gen_Proj_l_FloattoLL(node);
4539 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4543 ir_mode *mode = get_irn_mode(node);
4544 if (ia32_mode_needs_gp_reg(mode)) {
4545 ir_node *new_pred = be_transform_node(pred);
4546 ir_node *block = be_transform_node(get_nodes_block(node));
4547 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4548 mode_Iu, get_Proj_proj(node));
4549 #ifdef DEBUG_libfirm
4550 new_proj->node_nr = node->node_nr;
4556 return be_duplicate_node(node);
4560 * Enters all transform functions into the generic pointer
4562 static void register_transformers(void)
4566 /* first clear the generic function pointer for all ops */
4567 clear_irp_opcodes_generic_func();
4569 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4570 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4608 /* transform ops from intrinsic lowering */
4620 GEN(ia32_l_LLtoFloat);
4621 GEN(ia32_l_FloattoLL);
4627 /* we should never see these nodes */
4642 /* handle generic backend nodes */
4651 op_Mulh = get_op_Mulh();
4660 * Pre-transform all unknown and noreg nodes.
4662 static void ia32_pretransform_node(void)
4664 ia32_code_gen_t *cg = env_cg;
4666 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4667 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4668 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4669 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4670 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4671 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4676 * Walker, checks if all ia32 nodes producing more than one result have their
4677 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4679 static void add_missing_keep_walker(ir_node *node, void *data)
4682 unsigned found_projs = 0;
4683 const ir_edge_t *edge;
4684 ir_mode *mode = get_irn_mode(node);
4689 if (!is_ia32_irn(node))
4692 n_outs = arch_irn_get_n_outs(node);
4695 if (is_ia32_SwitchJmp(node))
4698 assert(n_outs < (int) sizeof(unsigned) * 8);
4699 foreach_out_edge(node, edge) {
4700 ir_node *proj = get_edge_src_irn(edge);
4703 /* The node could be kept */
4707 if (get_irn_mode(proj) == mode_M)
4710 pn = get_Proj_proj(proj);
4711 assert(pn < n_outs);
4712 found_projs |= 1 << pn;
4716 /* are keeps missing? */
4718 for (i = 0; i < n_outs; ++i) {
4721 const arch_register_req_t *req;
4722 const arch_register_class_t *cls;
4724 if (found_projs & (1 << i)) {
4728 req = get_ia32_out_req(node, i);
4733 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4737 block = get_nodes_block(node);
4738 in[0] = new_r_Proj(current_ir_graph, block, node,
4739 arch_register_class_mode(cls), i);
4740 if (last_keep != NULL) {
4741 be_Keep_add_node(last_keep, cls, in[0]);
4743 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4744 if (sched_is_scheduled(node)) {
4745 sched_add_after(node, last_keep);
4752 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4755 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4757 ir_graph *irg = be_get_birg_irg(cg->birg);
4758 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4761 /* do the transformation */
4762 void ia32_transform_graph(ia32_code_gen_t *cg)
4766 register_transformers();
4768 initial_fpcw = NULL;
4770 BE_TIMER_PUSH(t_heights);
4771 heights = heights_new(cg->irg);
4772 BE_TIMER_POP(t_heights);
4773 ia32_calculate_non_address_mode_nodes(cg->birg);
4775 /* the transform phase is not safe for CSE (yet) because several nodes get
4776 * attributes set after their creation */
4777 cse_last = get_opt_cse();
4780 be_transform_graph(cg->birg, ia32_pretransform_node);
4782 set_opt_cse(cse_last);
4784 ia32_free_non_address_mode_nodes();
4785 heights_free(heights);
4789 void ia32_init_transform(void)
4791 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");