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);
1501 ir_mode *mode = get_irn_mode(node);
1503 if (is_Const(right) && mode == mode_Is) {
1504 tarval *tv = get_Const_tarval(right);
1505 long val = get_tarval_long(tv);
1507 /* this is a sign extension */
1508 dbg_info *dbgi = get_irn_dbg_info(node);
1509 ir_node *block = be_transform_node(get_nodes_block(node));
1510 ir_node *new_op = be_transform_node(left);
1512 return create_sex_32_64(dbgi, block, new_op, node);
1516 /* 8 or 16 bit sign extension? */
1517 if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1518 ir_node *shl_left = get_Shl_left(left);
1519 ir_node *shl_right = get_Shl_right(left);
1520 if (is_Const(shl_right)) {
1521 tarval *tv1 = get_Const_tarval(right);
1522 tarval *tv2 = get_Const_tarval(shl_right);
1523 if (tv1 == tv2 && tarval_is_long(tv1)) {
1524 long val = get_tarval_long(tv1);
1525 if (val == 16 || val == 24) {
1526 dbg_info *dbgi = get_irn_dbg_info(node);
1527 ir_node *block = get_nodes_block(node);
1537 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1546 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1552 * Creates an ia32 Rol.
1554 * @param op1 The first operator
1555 * @param op2 The second operator
1556 * @return The created ia32 RotL node
1558 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1560 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1566 * Creates an ia32 Ror.
1567 * NOTE: There is no RotR with immediate because this would always be a RotL
1568 * "imm-mode_size_bits" which can be pre-calculated.
1570 * @param op1 The first operator
1571 * @param op2 The second operator
1572 * @return The created ia32 RotR node
1574 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1576 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1582 * Creates an ia32 RotR or RotL (depending on the found pattern).
1584 * @return The created ia32 RotL or RotR node
1586 static ir_node *gen_Rotl(ir_node *node)
1588 ir_node *rotate = NULL;
1589 ir_node *op1 = get_Rotl_left(node);
1590 ir_node *op2 = get_Rotl_right(node);
1592 /* Firm has only RotL, so we are looking for a right (op2)
1593 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1594 that means we can create a RotR instead of an Add and a RotL */
1598 ir_node *left = get_Add_left(add);
1599 ir_node *right = get_Add_right(add);
1600 if (is_Const(right)) {
1601 tarval *tv = get_Const_tarval(right);
1602 ir_mode *mode = get_irn_mode(node);
1603 long bits = get_mode_size_bits(mode);
1605 if (is_Minus(left) &&
1606 tarval_is_long(tv) &&
1607 get_tarval_long(tv) == bits &&
1610 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1611 rotate = gen_Ror(node, op1, get_Minus_op(left));
1616 if (rotate == NULL) {
1617 rotate = gen_Rol(node, op1, op2);
1626 * Transforms a Minus node.
1628 * @return The created ia32 Minus node
1630 static ir_node *gen_Minus(ir_node *node)
1632 ir_node *op = get_Minus_op(node);
1633 ir_node *block = be_transform_node(get_nodes_block(node));
1634 dbg_info *dbgi = get_irn_dbg_info(node);
1635 ir_mode *mode = get_irn_mode(node);
1640 if (mode_is_float(mode)) {
1641 ir_node *new_op = be_transform_node(op);
1642 if (ia32_cg_config.use_sse2) {
1643 /* TODO: non-optimal... if we have many xXors, then we should
1644 * rather create a load for the const and use that instead of
1645 * several AM nodes... */
1646 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1647 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1648 ir_node *nomem = new_NoMem();
1650 new_node = new_bd_ia32_xXor(dbgi, block, noreg_gp, noreg_gp,
1651 nomem, new_op, noreg_xmm);
1653 size = get_mode_size_bits(mode);
1654 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1656 set_ia32_am_sc(new_node, ent);
1657 set_ia32_op_type(new_node, ia32_AddrModeS);
1658 set_ia32_ls_mode(new_node, mode);
1660 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1663 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1666 SET_IA32_ORIG_NODE(new_node, node);
1672 * Transforms a Not node.
1674 * @return The created ia32 Not node
1676 static ir_node *gen_Not(ir_node *node)
1678 ir_node *op = get_Not_op(node);
1680 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1681 assert (! mode_is_float(get_irn_mode(node)));
1683 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1689 * Transforms an Abs node.
1691 * @return The created ia32 Abs node
1693 static ir_node *gen_Abs(ir_node *node)
1695 ir_node *block = get_nodes_block(node);
1696 ir_node *new_block = be_transform_node(block);
1697 ir_node *op = get_Abs_op(node);
1698 dbg_info *dbgi = get_irn_dbg_info(node);
1699 ir_mode *mode = get_irn_mode(node);
1700 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1701 ir_node *nomem = new_NoMem();
1707 if (mode_is_float(mode)) {
1708 new_op = be_transform_node(op);
1710 if (ia32_cg_config.use_sse2) {
1711 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1712 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_gp, noreg_gp,
1713 nomem, new_op, noreg_fp);
1715 size = get_mode_size_bits(mode);
1716 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1718 set_ia32_am_sc(new_node, ent);
1720 SET_IA32_ORIG_NODE(new_node, node);
1722 set_ia32_op_type(new_node, ia32_AddrModeS);
1723 set_ia32_ls_mode(new_node, mode);
1725 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1726 SET_IA32_ORIG_NODE(new_node, node);
1729 ir_node *xor, *sign_extension;
1731 if (get_mode_size_bits(mode) == 32) {
1732 new_op = be_transform_node(op);
1734 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1737 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1739 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_gp, noreg_gp,
1740 nomem, new_op, sign_extension);
1741 SET_IA32_ORIG_NODE(xor, node);
1743 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_gp, noreg_gp,
1744 nomem, xor, sign_extension);
1745 SET_IA32_ORIG_NODE(new_node, node);
1752 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1754 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1756 dbg_info *dbgi = get_irn_dbg_info(cmp);
1757 ir_node *block = get_nodes_block(cmp);
1758 ir_node *new_block = be_transform_node(block);
1759 ir_node *op1 = be_transform_node(x);
1760 ir_node *op2 = be_transform_node(n);
1762 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1766 * Transform a node returning a "flag" result.
1768 * @param node the node to transform
1769 * @param pnc_out the compare mode to use
1771 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1780 /* we have a Cmp as input */
1781 if (is_Proj(node)) {
1782 ir_node *pred = get_Proj_pred(node);
1784 pn_Cmp pnc = get_Proj_proj(node);
1785 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1786 ir_node *l = get_Cmp_left(pred);
1787 ir_node *r = get_Cmp_right(pred);
1789 ir_node *la = get_And_left(l);
1790 ir_node *ra = get_And_right(l);
1792 ir_node *c = get_Shl_left(la);
1793 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1794 /* (1 << n) & ra) */
1795 ir_node *n = get_Shl_right(la);
1796 flags = gen_bt(pred, ra, n);
1797 /* we must generate a Jc/Jnc jump */
1798 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1801 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1806 ir_node *c = get_Shl_left(ra);
1807 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1808 /* la & (1 << n)) */
1809 ir_node *n = get_Shl_right(ra);
1810 flags = gen_bt(pred, la, n);
1811 /* we must generate a Jc/Jnc jump */
1812 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1815 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1821 flags = be_transform_node(pred);
1827 /* a mode_b value, we have to compare it against 0 */
1828 dbgi = get_irn_dbg_info(node);
1829 new_block = be_transform_node(get_nodes_block(node));
1830 new_op = be_transform_node(node);
1831 noreg = ia32_new_NoReg_gp(env_cg);
1832 nomem = new_NoMem();
1833 flags = new_bd_ia32_Test(dbgi, new_block, noreg, noreg, nomem, new_op,
1834 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1835 *pnc_out = pn_Cmp_Lg;
1840 * Transforms a Load.
1842 * @return the created ia32 Load node
1844 static ir_node *gen_Load(ir_node *node)
1846 ir_node *old_block = get_nodes_block(node);
1847 ir_node *block = be_transform_node(old_block);
1848 ir_node *ptr = get_Load_ptr(node);
1849 ir_node *mem = get_Load_mem(node);
1850 ir_node *new_mem = be_transform_node(mem);
1853 dbg_info *dbgi = get_irn_dbg_info(node);
1854 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1855 ir_mode *mode = get_Load_mode(node);
1858 ia32_address_t addr;
1860 /* construct load address */
1861 memset(&addr, 0, sizeof(addr));
1862 ia32_create_address_mode(&addr, ptr, 0);
1869 base = be_transform_node(base);
1872 if (index == NULL) {
1875 index = be_transform_node(index);
1878 if (mode_is_float(mode)) {
1879 if (ia32_cg_config.use_sse2) {
1880 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1882 res_mode = mode_xmm;
1884 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1886 res_mode = mode_vfp;
1889 assert(mode != mode_b);
1891 /* create a conv node with address mode for smaller modes */
1892 if (get_mode_size_bits(mode) < 32) {
1893 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1894 new_mem, noreg, mode);
1896 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1901 set_irn_pinned(new_node, get_irn_pinned(node));
1902 set_ia32_op_type(new_node, ia32_AddrModeS);
1903 set_ia32_ls_mode(new_node, mode);
1904 set_address(new_node, &addr);
1906 if (get_irn_pinned(node) == op_pin_state_floats) {
1907 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1908 && pn_ia32_vfld_res == pn_ia32_Load_res
1909 && pn_ia32_Load_res == pn_ia32_res);
1910 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1913 SET_IA32_ORIG_NODE(new_node, node);
1915 be_dep_on_frame(new_node);
1919 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1920 ir_node *ptr, ir_node *other)
1927 /* we only use address mode if we're the only user of the load */
1928 if (get_irn_n_edges(node) > 1)
1931 load = get_Proj_pred(node);
1934 if (get_nodes_block(load) != block)
1937 /* store should have the same pointer as the load */
1938 if (get_Load_ptr(load) != ptr)
1941 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1942 if (other != NULL &&
1943 get_nodes_block(other) == block &&
1944 heights_reachable_in_block(heights, other, load)) {
1948 if (prevents_AM(block, load, mem))
1950 /* Store should be attached to the load via mem */
1951 assert(heights_reachable_in_block(heights, mem, load));
1956 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1957 ir_node *mem, ir_node *ptr, ir_mode *mode,
1958 construct_binop_dest_func *func,
1959 construct_binop_dest_func *func8bit,
1960 match_flags_t flags)
1962 ir_node *src_block = get_nodes_block(node);
1964 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1971 ia32_address_mode_t am;
1972 ia32_address_t *addr = &am.addr;
1973 memset(&am, 0, sizeof(am));
1975 assert(flags & match_immediate); /* there is no destam node without... */
1976 commutative = (flags & match_commutative) != 0;
1978 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1979 build_address(&am, op1, ia32_create_am_double_use);
1980 new_op = create_immediate_or_transform(op2, 0);
1981 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1982 build_address(&am, op2, ia32_create_am_double_use);
1983 new_op = create_immediate_or_transform(op1, 0);
1988 if (addr->base == NULL)
1989 addr->base = noreg_gp;
1990 if (addr->index == NULL)
1991 addr->index = noreg_gp;
1992 if (addr->mem == NULL)
1993 addr->mem = new_NoMem();
1995 dbgi = get_irn_dbg_info(node);
1996 block = be_transform_node(src_block);
1997 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
1999 if (get_mode_size_bits(mode) == 8) {
2000 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2002 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2004 set_address(new_node, addr);
2005 set_ia32_op_type(new_node, ia32_AddrModeD);
2006 set_ia32_ls_mode(new_node, mode);
2007 SET_IA32_ORIG_NODE(new_node, node);
2009 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2010 mem_proj = be_transform_node(am.mem_proj);
2011 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2016 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2017 ir_node *ptr, ir_mode *mode,
2018 construct_unop_dest_func *func)
2020 ir_node *src_block = get_nodes_block(node);
2026 ia32_address_mode_t am;
2027 ia32_address_t *addr = &am.addr;
2029 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2032 memset(&am, 0, sizeof(am));
2033 build_address(&am, op, ia32_create_am_double_use);
2035 dbgi = get_irn_dbg_info(node);
2036 block = be_transform_node(src_block);
2037 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2038 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2039 set_address(new_node, addr);
2040 set_ia32_op_type(new_node, ia32_AddrModeD);
2041 set_ia32_ls_mode(new_node, mode);
2042 SET_IA32_ORIG_NODE(new_node, node);
2044 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2045 mem_proj = be_transform_node(am.mem_proj);
2046 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2051 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2053 ir_mode *mode = get_irn_mode(node);
2054 ir_node *mux_true = get_Mux_true(node);
2055 ir_node *mux_false = get_Mux_false(node);
2065 ia32_address_t addr;
2067 if (get_mode_size_bits(mode) != 8)
2070 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2072 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2078 build_address_ptr(&addr, ptr, mem);
2080 dbgi = get_irn_dbg_info(node);
2081 block = get_nodes_block(node);
2082 new_block = be_transform_node(block);
2083 cond = get_Mux_sel(node);
2084 flags = get_flags_node(cond, &pnc);
2085 new_mem = be_transform_node(mem);
2086 new_node = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2087 addr.index, addr.mem, flags, pnc, negated);
2088 set_address(new_node, &addr);
2089 set_ia32_op_type(new_node, ia32_AddrModeD);
2090 set_ia32_ls_mode(new_node, mode);
2091 SET_IA32_ORIG_NODE(new_node, node);
2096 static ir_node *try_create_dest_am(ir_node *node)
2098 ir_node *val = get_Store_value(node);
2099 ir_node *mem = get_Store_mem(node);
2100 ir_node *ptr = get_Store_ptr(node);
2101 ir_mode *mode = get_irn_mode(val);
2102 unsigned bits = get_mode_size_bits(mode);
2107 /* handle only GP modes for now... */
2108 if (!ia32_mode_needs_gp_reg(mode))
2112 /* store must be the only user of the val node */
2113 if (get_irn_n_edges(val) > 1)
2115 /* skip pointless convs */
2117 ir_node *conv_op = get_Conv_op(val);
2118 ir_mode *pred_mode = get_irn_mode(conv_op);
2119 if (!ia32_mode_needs_gp_reg(pred_mode))
2121 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2129 /* value must be in the same block */
2130 if (get_nodes_block(node) != get_nodes_block(val))
2133 switch (get_irn_opcode(val)) {
2135 op1 = get_Add_left(val);
2136 op2 = get_Add_right(val);
2137 if (ia32_cg_config.use_incdec) {
2138 if (is_Const_1(op2)) {
2139 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2141 } else if (is_Const_Minus_1(op2)) {
2142 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2146 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2147 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2148 match_commutative | match_immediate);
2151 op1 = get_Sub_left(val);
2152 op2 = get_Sub_right(val);
2153 if (is_Const(op2)) {
2154 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2156 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2157 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2161 op1 = get_And_left(val);
2162 op2 = get_And_right(val);
2163 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2164 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2165 match_commutative | match_immediate);
2168 op1 = get_Or_left(val);
2169 op2 = get_Or_right(val);
2170 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2171 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2172 match_commutative | match_immediate);
2175 op1 = get_Eor_left(val);
2176 op2 = get_Eor_right(val);
2177 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2178 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2179 match_commutative | match_immediate);
2182 op1 = get_Shl_left(val);
2183 op2 = get_Shl_right(val);
2184 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2185 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2189 op1 = get_Shr_left(val);
2190 op2 = get_Shr_right(val);
2191 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2192 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2196 op1 = get_Shrs_left(val);
2197 op2 = get_Shrs_right(val);
2198 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2199 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2203 op1 = get_Rotl_left(val);
2204 op2 = get_Rotl_right(val);
2205 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2206 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2209 /* TODO: match ROR patterns... */
2211 new_node = try_create_SetMem(val, ptr, mem);
2214 op1 = get_Minus_op(val);
2215 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2218 /* should be lowered already */
2219 assert(mode != mode_b);
2220 op1 = get_Not_op(val);
2221 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2227 if (new_node != NULL) {
2228 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2229 get_irn_pinned(node) == op_pin_state_pinned) {
2230 set_irn_pinned(new_node, op_pin_state_pinned);
2237 static bool possible_int_mode_for_fp(ir_mode *mode)
2241 if (!mode_is_signed(mode))
2243 size = get_mode_size_bits(mode);
2244 if (size != 16 && size != 32)
2249 static int is_float_to_int_conv(const ir_node *node)
2251 ir_mode *mode = get_irn_mode(node);
2255 if (!possible_int_mode_for_fp(mode))
2260 conv_op = get_Conv_op(node);
2261 conv_mode = get_irn_mode(conv_op);
2263 if (!mode_is_float(conv_mode))
2270 * Transform a Store(floatConst) into a sequence of
2273 * @return the created ia32 Store node
2275 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2277 ir_mode *mode = get_irn_mode(cns);
2278 unsigned size = get_mode_size_bytes(mode);
2279 tarval *tv = get_Const_tarval(cns);
2280 ir_node *block = get_nodes_block(node);
2281 ir_node *new_block = be_transform_node(block);
2282 ir_node *ptr = get_Store_ptr(node);
2283 ir_node *mem = get_Store_mem(node);
2284 dbg_info *dbgi = get_irn_dbg_info(node);
2288 ia32_address_t addr;
2290 assert(size % 4 == 0);
2293 build_address_ptr(&addr, ptr, mem);
2297 get_tarval_sub_bits(tv, ofs) |
2298 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2299 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2300 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2301 ir_node *imm = create_Immediate(NULL, 0, val);
2303 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2304 addr.index, addr.mem, imm);
2306 set_irn_pinned(new_node, get_irn_pinned(node));
2307 set_ia32_op_type(new_node, ia32_AddrModeD);
2308 set_ia32_ls_mode(new_node, mode_Iu);
2309 set_address(new_node, &addr);
2310 SET_IA32_ORIG_NODE(new_node, node);
2313 ins[i++] = new_node;
2318 } while (size != 0);
2321 return new_rd_Sync(dbgi, current_ir_graph, new_block, i, ins);
2328 * Generate a vfist or vfisttp instruction.
2330 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2331 ir_node *mem, ir_node *val, ir_node **fist)
2335 if (ia32_cg_config.use_fisttp) {
2336 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2337 if other users exists */
2338 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2339 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2340 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2341 be_new_Keep(reg_class, irg, block, 1, &value);
2343 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2346 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2349 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2355 * Transforms a general (no special case) Store.
2357 * @return the created ia32 Store node
2359 static ir_node *gen_general_Store(ir_node *node)
2361 ir_node *val = get_Store_value(node);
2362 ir_mode *mode = get_irn_mode(val);
2363 ir_node *block = get_nodes_block(node);
2364 ir_node *new_block = be_transform_node(block);
2365 ir_node *ptr = get_Store_ptr(node);
2366 ir_node *mem = get_Store_mem(node);
2367 dbg_info *dbgi = get_irn_dbg_info(node);
2368 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2369 ir_node *new_val, *new_node, *store;
2370 ia32_address_t addr;
2372 /* check for destination address mode */
2373 new_node = try_create_dest_am(node);
2374 if (new_node != NULL)
2377 /* construct store address */
2378 memset(&addr, 0, sizeof(addr));
2379 ia32_create_address_mode(&addr, ptr, 0);
2381 if (addr.base == NULL) {
2384 addr.base = be_transform_node(addr.base);
2387 if (addr.index == NULL) {
2390 addr.index = be_transform_node(addr.index);
2392 addr.mem = be_transform_node(mem);
2394 if (mode_is_float(mode)) {
2395 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2397 while (is_Conv(val) && mode == get_irn_mode(val)) {
2398 ir_node *op = get_Conv_op(val);
2399 if (!mode_is_float(get_irn_mode(op)))
2403 new_val = be_transform_node(val);
2404 if (ia32_cg_config.use_sse2) {
2405 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2406 addr.index, addr.mem, new_val);
2408 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2409 addr.index, addr.mem, new_val, mode);
2412 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2413 val = get_Conv_op(val);
2415 /* TODO: is this optimisation still necessary at all (middleend)? */
2416 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2417 while (is_Conv(val)) {
2418 ir_node *op = get_Conv_op(val);
2419 if (!mode_is_float(get_irn_mode(op)))
2421 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2425 new_val = be_transform_node(val);
2426 new_node = gen_vfist(dbgi, current_ir_graph, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2428 new_val = create_immediate_or_transform(val, 0);
2429 assert(mode != mode_b);
2431 if (get_mode_size_bits(mode) == 8) {
2432 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2433 addr.index, addr.mem, new_val);
2435 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2436 addr.index, addr.mem, new_val);
2441 set_irn_pinned(store, get_irn_pinned(node));
2442 set_ia32_op_type(store, ia32_AddrModeD);
2443 set_ia32_ls_mode(store, mode);
2445 set_address(store, &addr);
2446 SET_IA32_ORIG_NODE(store, node);
2452 * Transforms a Store.
2454 * @return the created ia32 Store node
2456 static ir_node *gen_Store(ir_node *node)
2458 ir_node *val = get_Store_value(node);
2459 ir_mode *mode = get_irn_mode(val);
2461 if (mode_is_float(mode) && is_Const(val)) {
2462 /* We can transform every floating const store
2463 into a sequence of integer stores.
2464 If the constant is already in a register,
2465 it would be better to use it, but we don't
2466 have this information here. */
2467 return gen_float_const_Store(node, val);
2469 return gen_general_Store(node);
2473 * Transforms a Switch.
2475 * @return the created ia32 SwitchJmp node
2477 static ir_node *create_Switch(ir_node *node)
2479 dbg_info *dbgi = get_irn_dbg_info(node);
2480 ir_node *block = be_transform_node(get_nodes_block(node));
2481 ir_node *sel = get_Cond_selector(node);
2482 ir_node *new_sel = be_transform_node(sel);
2483 int switch_min = INT_MAX;
2484 int switch_max = INT_MIN;
2485 long default_pn = get_Cond_defaultProj(node);
2487 const ir_edge_t *edge;
2489 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2491 /* determine the smallest switch case value */
2492 foreach_out_edge(node, edge) {
2493 ir_node *proj = get_edge_src_irn(edge);
2494 long pn = get_Proj_proj(proj);
2495 if (pn == default_pn)
2498 if (pn < switch_min)
2500 if (pn > switch_max)
2504 if ((unsigned) (switch_max - switch_min) > 256000) {
2505 panic("Size of switch %+F bigger than 256000", node);
2508 if (switch_min != 0) {
2509 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2511 /* if smallest switch case is not 0 we need an additional sub */
2512 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg);
2513 add_ia32_am_offs_int(new_sel, -switch_min);
2514 set_ia32_op_type(new_sel, ia32_AddrModeS);
2516 SET_IA32_ORIG_NODE(new_sel, node);
2519 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2520 SET_IA32_ORIG_NODE(new_node, node);
2526 * Transform a Cond node.
2528 static ir_node *gen_Cond(ir_node *node)
2530 ir_node *block = get_nodes_block(node);
2531 ir_node *new_block = be_transform_node(block);
2532 dbg_info *dbgi = get_irn_dbg_info(node);
2533 ir_node *sel = get_Cond_selector(node);
2534 ir_mode *sel_mode = get_irn_mode(sel);
2535 ir_node *flags = NULL;
2539 if (sel_mode != mode_b) {
2540 return create_Switch(node);
2543 /* we get flags from a Cmp */
2544 flags = get_flags_node(sel, &pnc);
2546 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2547 SET_IA32_ORIG_NODE(new_node, node);
2552 static ir_node *gen_be_Copy(ir_node *node)
2554 ir_node *new_node = be_duplicate_node(node);
2555 ir_mode *mode = get_irn_mode(new_node);
2557 if (ia32_mode_needs_gp_reg(mode)) {
2558 set_irn_mode(new_node, mode_Iu);
2564 static ir_node *create_Fucom(ir_node *node)
2566 dbg_info *dbgi = get_irn_dbg_info(node);
2567 ir_node *block = get_nodes_block(node);
2568 ir_node *new_block = be_transform_node(block);
2569 ir_node *left = get_Cmp_left(node);
2570 ir_node *new_left = be_transform_node(left);
2571 ir_node *right = get_Cmp_right(node);
2575 if (ia32_cg_config.use_fucomi) {
2576 new_right = be_transform_node(right);
2577 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2579 set_ia32_commutative(new_node);
2580 SET_IA32_ORIG_NODE(new_node, node);
2582 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2583 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2585 new_right = be_transform_node(right);
2586 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2589 set_ia32_commutative(new_node);
2591 SET_IA32_ORIG_NODE(new_node, node);
2593 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2594 SET_IA32_ORIG_NODE(new_node, node);
2600 static ir_node *create_Ucomi(ir_node *node)
2602 dbg_info *dbgi = get_irn_dbg_info(node);
2603 ir_node *src_block = get_nodes_block(node);
2604 ir_node *new_block = be_transform_node(src_block);
2605 ir_node *left = get_Cmp_left(node);
2606 ir_node *right = get_Cmp_right(node);
2608 ia32_address_mode_t am;
2609 ia32_address_t *addr = &am.addr;
2611 match_arguments(&am, src_block, left, right, NULL,
2612 match_commutative | match_am);
2614 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2615 addr->mem, am.new_op1, am.new_op2,
2617 set_am_attributes(new_node, &am);
2619 SET_IA32_ORIG_NODE(new_node, node);
2621 new_node = fix_mem_proj(new_node, &am);
2627 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2628 * to fold an and into a test node
2630 static bool can_fold_test_and(ir_node *node)
2632 const ir_edge_t *edge;
2634 /** we can only have eq and lg projs */
2635 foreach_out_edge(node, edge) {
2636 ir_node *proj = get_edge_src_irn(edge);
2637 pn_Cmp pnc = get_Proj_proj(proj);
2638 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2646 * returns true if it is assured, that the upper bits of a node are "clean"
2647 * which means for a 16 or 8 bit value, that the upper bits in the register
2648 * are 0 for unsigned and a copy of the last significant bit for signed
2651 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2653 assert(ia32_mode_needs_gp_reg(mode));
2654 if (get_mode_size_bits(mode) >= 32)
2657 if (is_Proj(transformed_node))
2658 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2660 switch (get_ia32_irn_opcode(transformed_node)) {
2661 case iro_ia32_Conv_I2I:
2662 case iro_ia32_Conv_I2I8Bit: {
2663 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2664 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2666 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2673 if (mode_is_signed(mode)) {
2674 return false; /* TODO handle signed modes */
2676 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2677 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2678 const ia32_immediate_attr_t *attr
2679 = get_ia32_immediate_attr_const(right);
2680 if (attr->symconst == 0 &&
2681 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2685 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2689 /* TODO too conservative if shift amount is constant */
2690 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2693 if (!mode_is_signed(mode)) {
2695 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2696 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2698 /* TODO if one is known to be zero extended, then || is sufficient */
2703 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2704 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2706 case iro_ia32_Const:
2707 case iro_ia32_Immediate: {
2708 const ia32_immediate_attr_t *attr =
2709 get_ia32_immediate_attr_const(transformed_node);
2710 if (mode_is_signed(mode)) {
2711 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2712 return shifted == 0 || shifted == -1;
2714 unsigned long shifted = (unsigned long)attr->offset;
2715 shifted >>= get_mode_size_bits(mode);
2716 return shifted == 0;
2726 * Generate code for a Cmp.
2728 static ir_node *gen_Cmp(ir_node *node)
2730 dbg_info *dbgi = get_irn_dbg_info(node);
2731 ir_node *block = get_nodes_block(node);
2732 ir_node *new_block = be_transform_node(block);
2733 ir_node *left = get_Cmp_left(node);
2734 ir_node *right = get_Cmp_right(node);
2735 ir_mode *cmp_mode = get_irn_mode(left);
2737 ia32_address_mode_t am;
2738 ia32_address_t *addr = &am.addr;
2741 if (mode_is_float(cmp_mode)) {
2742 if (ia32_cg_config.use_sse2) {
2743 return create_Ucomi(node);
2745 return create_Fucom(node);
2749 assert(ia32_mode_needs_gp_reg(cmp_mode));
2751 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2752 cmp_unsigned = !mode_is_signed(cmp_mode);
2753 if (is_Const_0(right) &&
2755 get_irn_n_edges(left) == 1 &&
2756 can_fold_test_and(node)) {
2757 /* Test(and_left, and_right) */
2758 ir_node *and_left = get_And_left(left);
2759 ir_node *and_right = get_And_right(left);
2761 /* matze: code here used mode instead of cmd_mode, I think it is always
2762 * the same as cmp_mode, but I leave this here to see if this is really
2765 assert(get_irn_mode(and_left) == cmp_mode);
2767 match_arguments(&am, block, and_left, and_right, NULL,
2769 match_am | match_8bit_am | match_16bit_am |
2770 match_am_and_immediates | match_immediate);
2772 /* use 32bit compare mode if possible since the opcode is smaller */
2773 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2774 upper_bits_clean(am.new_op2, cmp_mode)) {
2775 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2778 if (get_mode_size_bits(cmp_mode) == 8) {
2779 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2780 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2783 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2784 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2787 /* Cmp(left, right) */
2788 match_arguments(&am, block, left, right, NULL,
2789 match_commutative | match_am | match_8bit_am |
2790 match_16bit_am | match_am_and_immediates |
2792 /* use 32bit compare mode if possible since the opcode is smaller */
2793 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2794 upper_bits_clean(am.new_op2, cmp_mode)) {
2795 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2798 if (get_mode_size_bits(cmp_mode) == 8) {
2799 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2800 addr->index, addr->mem, am.new_op1,
2801 am.new_op2, am.ins_permuted,
2804 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2805 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2808 set_am_attributes(new_node, &am);
2809 set_ia32_ls_mode(new_node, cmp_mode);
2811 SET_IA32_ORIG_NODE(new_node, node);
2813 new_node = fix_mem_proj(new_node, &am);
2818 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2821 dbg_info *dbgi = get_irn_dbg_info(node);
2822 ir_node *block = get_nodes_block(node);
2823 ir_node *new_block = be_transform_node(block);
2824 ir_node *val_true = get_Mux_true(node);
2825 ir_node *val_false = get_Mux_false(node);
2827 ia32_address_mode_t am;
2828 ia32_address_t *addr;
2830 assert(ia32_cg_config.use_cmov);
2831 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2835 match_arguments(&am, block, val_false, val_true, flags,
2836 match_commutative | match_am | match_16bit_am | match_mode_neutral);
2838 new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2839 addr->mem, am.new_op1, am.new_op2, new_flags,
2840 am.ins_permuted, pnc);
2841 set_am_attributes(new_node, &am);
2843 SET_IA32_ORIG_NODE(new_node, node);
2845 new_node = fix_mem_proj(new_node, &am);
2851 * Creates a ia32 Setcc instruction.
2853 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2854 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2857 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2858 ir_node *nomem = new_NoMem();
2859 ir_mode *mode = get_irn_mode(orig_node);
2862 new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2863 SET_IA32_ORIG_NODE(new_node, orig_node);
2865 /* we might need to conv the result up */
2866 if (get_mode_size_bits(mode) > 8) {
2867 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg, noreg,
2868 nomem, new_node, mode_Bu);
2869 SET_IA32_ORIG_NODE(new_node, orig_node);
2876 * Create instruction for an unsigned Difference or Zero.
2878 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2880 ir_graph *irg = current_ir_graph;
2881 ir_mode *mode = get_irn_mode(psi);
2882 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2885 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2886 match_mode_neutral | match_am | match_immediate | match_two_users);
2888 block = get_nodes_block(new_node);
2890 if (is_Proj(new_node)) {
2891 sub = get_Proj_pred(new_node);
2892 assert(is_ia32_Sub(sub));
2895 set_irn_mode(sub, mode_T);
2896 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2898 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2900 dbgi = get_irn_dbg_info(psi);
2901 noreg = ia32_new_NoReg_gp(env_cg);
2902 tmpreg = new_bd_ia32_ProduceVal(dbgi, block);
2903 nomem = new_NoMem();
2904 sbb = new_bd_ia32_Sbb(dbgi, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2906 new_node = new_bd_ia32_And(dbgi, block, noreg, noreg, nomem, new_node, sbb);
2907 set_ia32_commutative(new_node);
2912 * Transforms a Mux node into CMov.
2914 * @return The transformed node.
2916 static ir_node *gen_Mux(ir_node *node)
2918 dbg_info *dbgi = get_irn_dbg_info(node);
2919 ir_node *block = get_nodes_block(node);
2920 ir_node *new_block = be_transform_node(block);
2921 ir_node *mux_true = get_Mux_true(node);
2922 ir_node *mux_false = get_Mux_false(node);
2923 ir_node *cond = get_Mux_sel(node);
2924 ir_mode *mode = get_irn_mode(node);
2927 assert(get_irn_mode(cond) == mode_b);
2929 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2930 if (mode_is_float(mode)) {
2931 ir_node *cmp = get_Proj_pred(cond);
2932 ir_node *cmp_left = get_Cmp_left(cmp);
2933 ir_node *cmp_right = get_Cmp_right(cmp);
2934 pn_Cmp pnc = get_Proj_proj(cond);
2936 if (ia32_cg_config.use_sse2) {
2937 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2938 if (cmp_left == mux_true && cmp_right == mux_false) {
2939 /* Mux(a <= b, a, b) => MIN */
2940 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2941 match_commutative | match_am | match_two_users);
2942 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2943 /* Mux(a <= b, b, a) => MAX */
2944 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2945 match_commutative | match_am | match_two_users);
2947 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2948 if (cmp_left == mux_true && cmp_right == mux_false) {
2949 /* Mux(a >= b, a, b) => MAX */
2950 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2951 match_commutative | match_am | match_two_users);
2952 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2953 /* Mux(a >= b, b, a) => MIN */
2954 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2955 match_commutative | match_am | match_two_users);
2959 panic("cannot transform floating point Mux");
2965 assert(ia32_mode_needs_gp_reg(mode));
2967 if (is_Proj(cond)) {
2968 ir_node *cmp = get_Proj_pred(cond);
2970 ir_node *cmp_left = get_Cmp_left(cmp);
2971 ir_node *cmp_right = get_Cmp_right(cmp);
2972 pn_Cmp pnc = get_Proj_proj(cond);
2974 /* check for unsigned Doz first */
2975 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2976 is_Const_0(mux_false) && is_Sub(mux_true) &&
2977 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2978 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2979 return create_Doz(node, cmp_left, cmp_right);
2980 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2981 is_Const_0(mux_true) && is_Sub(mux_false) &&
2982 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2983 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2984 return create_Doz(node, cmp_left, cmp_right);
2989 flags = get_flags_node(cond, &pnc);
2991 if (is_Const(mux_true) && is_Const(mux_false)) {
2992 /* both are const, good */
2993 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2994 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2995 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2996 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2998 /* Not that simple. */
3003 new_node = create_CMov(node, cond, flags, pnc);
3011 * Create a conversion from x87 state register to general purpose.
3013 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3015 ir_node *block = be_transform_node(get_nodes_block(node));
3016 ir_node *op = get_Conv_op(node);
3017 ir_node *new_op = be_transform_node(op);
3018 ia32_code_gen_t *cg = env_cg;
3019 ir_graph *irg = current_ir_graph;
3020 dbg_info *dbgi = get_irn_dbg_info(node);
3021 ir_node *noreg = ia32_new_NoReg_gp(cg);
3022 ir_mode *mode = get_irn_mode(node);
3023 ir_node *fist, *load, *mem;
3025 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3026 set_irn_pinned(fist, op_pin_state_floats);
3027 set_ia32_use_frame(fist);
3028 set_ia32_op_type(fist, ia32_AddrModeD);
3030 assert(get_mode_size_bits(mode) <= 32);
3031 /* exception we can only store signed 32 bit integers, so for unsigned
3032 we store a 64bit (signed) integer and load the lower bits */
3033 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3034 set_ia32_ls_mode(fist, mode_Ls);
3036 set_ia32_ls_mode(fist, mode_Is);
3038 SET_IA32_ORIG_NODE(fist, node);
3041 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg, mem);
3043 set_irn_pinned(load, op_pin_state_floats);
3044 set_ia32_use_frame(load);
3045 set_ia32_op_type(load, ia32_AddrModeS);
3046 set_ia32_ls_mode(load, mode_Is);
3047 if (get_ia32_ls_mode(fist) == mode_Ls) {
3048 ia32_attr_t *attr = get_ia32_attr(load);
3049 attr->data.need_64bit_stackent = 1;
3051 ia32_attr_t *attr = get_ia32_attr(load);
3052 attr->data.need_32bit_stackent = 1;
3054 SET_IA32_ORIG_NODE(load, node);
3056 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3060 * Creates a x87 strict Conv by placing a Store and a Load
3062 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3064 ir_node *block = get_nodes_block(node);
3065 ir_graph *irg = current_ir_graph;
3066 dbg_info *dbgi = get_irn_dbg_info(node);
3067 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3068 ir_node *nomem = new_NoMem();
3069 ir_node *frame = get_irg_frame(irg);
3070 ir_node *store, *load;
3073 store = new_bd_ia32_vfst(dbgi, block, frame, noreg, nomem, node, tgt_mode);
3074 set_ia32_use_frame(store);
3075 set_ia32_op_type(store, ia32_AddrModeD);
3076 SET_IA32_ORIG_NODE(store, node);
3078 load = new_bd_ia32_vfld(dbgi, block, frame, noreg, store, tgt_mode);
3079 set_ia32_use_frame(load);
3080 set_ia32_op_type(load, ia32_AddrModeS);
3081 SET_IA32_ORIG_NODE(load, node);
3083 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3087 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3088 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3090 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3092 func = get_mode_size_bits(mode) == 8 ?
3093 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3094 return func(dbgi, block, base, index, mem, val, mode);
3098 * Create a conversion from general purpose to x87 register
3100 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3102 ir_node *src_block = get_nodes_block(node);
3103 ir_node *block = be_transform_node(src_block);
3104 ir_graph *irg = current_ir_graph;
3105 dbg_info *dbgi = get_irn_dbg_info(node);
3106 ir_node *op = get_Conv_op(node);
3107 ir_node *new_op = NULL;
3111 ir_mode *store_mode;
3116 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3117 if (possible_int_mode_for_fp(src_mode)) {
3118 ia32_address_mode_t am;
3120 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3121 if (am.op_type == ia32_AddrModeS) {
3122 ia32_address_t *addr = &am.addr;
3124 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index,
3126 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3129 set_am_attributes(fild, &am);
3130 SET_IA32_ORIG_NODE(fild, node);
3132 fix_mem_proj(fild, &am);
3137 if (new_op == NULL) {
3138 new_op = be_transform_node(op);
3141 noreg = ia32_new_NoReg_gp(env_cg);
3142 nomem = new_NoMem();
3143 mode = get_irn_mode(op);
3145 /* first convert to 32 bit signed if necessary */
3146 if (get_mode_size_bits(src_mode) < 32) {
3147 if (!upper_bits_clean(new_op, src_mode)) {
3148 new_op = create_Conv_I2I(dbgi, block, noreg, noreg, nomem, new_op, src_mode);
3149 SET_IA32_ORIG_NODE(new_op, node);
3154 assert(get_mode_size_bits(mode) == 32);
3157 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg, nomem,
3160 set_ia32_use_frame(store);
3161 set_ia32_op_type(store, ia32_AddrModeD);
3162 set_ia32_ls_mode(store, mode_Iu);
3164 /* exception for 32bit unsigned, do a 64bit spill+load */
3165 if (!mode_is_signed(mode)) {
3168 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3170 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3171 noreg, nomem, zero_const);
3173 set_ia32_use_frame(zero_store);
3174 set_ia32_op_type(zero_store, ia32_AddrModeD);
3175 add_ia32_am_offs_int(zero_store, 4);
3176 set_ia32_ls_mode(zero_store, mode_Iu);
3181 store = new_rd_Sync(dbgi, irg, block, 2, in);
3182 store_mode = mode_Ls;
3184 store_mode = mode_Is;
3188 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg, store);
3190 set_ia32_use_frame(fild);
3191 set_ia32_op_type(fild, ia32_AddrModeS);
3192 set_ia32_ls_mode(fild, store_mode);
3194 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3200 * Create a conversion from one integer mode into another one
3202 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3203 dbg_info *dbgi, ir_node *block, ir_node *op,
3206 ir_node *new_block = be_transform_node(block);
3208 ir_mode *smaller_mode;
3209 ia32_address_mode_t am;
3210 ia32_address_t *addr = &am.addr;
3213 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3214 smaller_mode = src_mode;
3216 smaller_mode = tgt_mode;
3219 #ifdef DEBUG_libfirm
3221 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3226 match_arguments(&am, block, NULL, op, NULL,
3227 match_am | match_8bit_am | match_16bit_am);
3229 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3230 /* unnecessary conv. in theory it shouldn't have been AM */
3231 assert(is_ia32_NoReg_GP(addr->base));
3232 assert(is_ia32_NoReg_GP(addr->index));
3233 assert(is_NoMem(addr->mem));
3234 assert(am.addr.offset == 0);
3235 assert(am.addr.symconst_ent == NULL);
3239 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3240 addr->mem, am.new_op2, smaller_mode);
3241 set_am_attributes(new_node, &am);
3242 /* match_arguments assume that out-mode = in-mode, this isn't true here
3244 set_ia32_ls_mode(new_node, smaller_mode);
3245 SET_IA32_ORIG_NODE(new_node, node);
3246 new_node = fix_mem_proj(new_node, &am);
3251 * Transforms a Conv node.
3253 * @return The created ia32 Conv node
3255 static ir_node *gen_Conv(ir_node *node)
3257 ir_node *block = get_nodes_block(node);
3258 ir_node *new_block = be_transform_node(block);
3259 ir_node *op = get_Conv_op(node);
3260 ir_node *new_op = NULL;
3261 dbg_info *dbgi = get_irn_dbg_info(node);
3262 ir_mode *src_mode = get_irn_mode(op);
3263 ir_mode *tgt_mode = get_irn_mode(node);
3264 int src_bits = get_mode_size_bits(src_mode);
3265 int tgt_bits = get_mode_size_bits(tgt_mode);
3266 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3267 ir_node *nomem = new_NoMem();
3268 ir_node *res = NULL;
3270 assert(!mode_is_int(src_mode) || src_bits <= 32);
3271 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3273 if (src_mode == mode_b) {
3274 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3275 /* nothing to do, we already model bools as 0/1 ints */
3276 return be_transform_node(op);
3279 if (src_mode == tgt_mode) {
3280 if (get_Conv_strict(node)) {
3281 if (ia32_cg_config.use_sse2) {
3282 /* when we are in SSE mode, we can kill all strict no-op conversion */
3283 return be_transform_node(op);
3286 /* this should be optimized already, but who knows... */
3287 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3288 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3289 return be_transform_node(op);
3293 if (mode_is_float(src_mode)) {
3294 new_op = be_transform_node(op);
3295 /* we convert from float ... */
3296 if (mode_is_float(tgt_mode)) {
3297 if (src_mode == mode_E && tgt_mode == mode_D
3298 && !get_Conv_strict(node)) {
3299 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3304 if (ia32_cg_config.use_sse2) {
3305 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3306 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg, noreg,
3308 set_ia32_ls_mode(res, tgt_mode);
3310 if (get_Conv_strict(node)) {
3311 res = gen_x87_strict_conv(tgt_mode, new_op);
3312 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3315 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3320 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3321 if (ia32_cg_config.use_sse2) {
3322 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg, noreg,
3324 set_ia32_ls_mode(res, src_mode);
3326 return gen_x87_fp_to_gp(node);
3330 /* we convert from int ... */
3331 if (mode_is_float(tgt_mode)) {
3333 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3334 if (ia32_cg_config.use_sse2) {
3335 new_op = be_transform_node(op);
3336 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg, noreg,
3338 set_ia32_ls_mode(res, tgt_mode);
3340 res = gen_x87_gp_to_fp(node, src_mode);
3341 if (get_Conv_strict(node)) {
3342 /* The strict-Conv is only necessary, if the int mode has more bits
3343 * than the float mantissa */
3344 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3345 size_t float_mantissa;
3346 /* FIXME There is no way to get the mantissa size of a mode */
3347 switch (get_mode_size_bits(tgt_mode)) {
3348 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3349 case 64: float_mantissa = 52 + 1; break;
3351 case 96: float_mantissa = 64; break;
3352 default: float_mantissa = 0; break;
3354 if (float_mantissa < int_mantissa) {
3355 res = gen_x87_strict_conv(tgt_mode, res);
3356 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3361 } else if (tgt_mode == mode_b) {
3362 /* mode_b lowering already took care that we only have 0/1 values */
3363 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3364 src_mode, tgt_mode));
3365 return be_transform_node(op);
3368 if (src_bits == tgt_bits) {
3369 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3370 src_mode, tgt_mode));
3371 return be_transform_node(op);
3374 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3382 static ir_node *create_immediate_or_transform(ir_node *node,
3383 char immediate_constraint_type)
3385 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3386 if (new_node == NULL) {
3387 new_node = be_transform_node(node);
3393 * Transforms a FrameAddr into an ia32 Add.
3395 static ir_node *gen_be_FrameAddr(ir_node *node)
3397 ir_node *block = be_transform_node(get_nodes_block(node));
3398 ir_node *op = be_get_FrameAddr_frame(node);
3399 ir_node *new_op = be_transform_node(op);
3400 dbg_info *dbgi = get_irn_dbg_info(node);
3401 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3404 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg);
3405 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3406 set_ia32_use_frame(new_node);
3408 SET_IA32_ORIG_NODE(new_node, node);
3414 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3416 static ir_node *gen_be_Return(ir_node *node)
3418 ir_graph *irg = current_ir_graph;
3419 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3420 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3421 ir_entity *ent = get_irg_entity(irg);
3422 ir_type *tp = get_entity_type(ent);
3427 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3428 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3431 int pn_ret_val, pn_ret_mem, arity, i;
3433 assert(ret_val != NULL);
3434 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3435 return be_duplicate_node(node);
3438 res_type = get_method_res_type(tp, 0);
3440 if (! is_Primitive_type(res_type)) {
3441 return be_duplicate_node(node);
3444 mode = get_type_mode(res_type);
3445 if (! mode_is_float(mode)) {
3446 return be_duplicate_node(node);
3449 assert(get_method_n_ress(tp) == 1);
3451 pn_ret_val = get_Proj_proj(ret_val);
3452 pn_ret_mem = get_Proj_proj(ret_mem);
3454 /* get the Barrier */
3455 barrier = get_Proj_pred(ret_val);
3457 /* get result input of the Barrier */
3458 ret_val = get_irn_n(barrier, pn_ret_val);
3459 new_ret_val = be_transform_node(ret_val);
3461 /* get memory input of the Barrier */
3462 ret_mem = get_irn_n(barrier, pn_ret_mem);
3463 new_ret_mem = be_transform_node(ret_mem);
3465 frame = get_irg_frame(irg);
3467 dbgi = get_irn_dbg_info(barrier);
3468 block = be_transform_node(get_nodes_block(barrier));
3470 noreg = ia32_new_NoReg_gp(env_cg);
3472 /* store xmm0 onto stack */
3473 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg,
3474 new_ret_mem, new_ret_val);
3475 set_ia32_ls_mode(sse_store, mode);
3476 set_ia32_op_type(sse_store, ia32_AddrModeD);
3477 set_ia32_use_frame(sse_store);
3479 /* load into x87 register */
3480 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg, sse_store, mode);
3481 set_ia32_op_type(fld, ia32_AddrModeS);
3482 set_ia32_use_frame(fld);
3484 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3485 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3487 /* create a new barrier */
3488 arity = get_irn_arity(barrier);
3489 in = ALLOCAN(ir_node*, arity);
3490 for (i = 0; i < arity; ++i) {
3493 if (i == pn_ret_val) {
3495 } else if (i == pn_ret_mem) {
3498 ir_node *in = get_irn_n(barrier, i);
3499 new_in = be_transform_node(in);
3504 new_barrier = new_ir_node(dbgi, irg, block,
3505 get_irn_op(barrier), get_irn_mode(barrier),
3507 copy_node_attr(barrier, new_barrier);
3508 be_duplicate_deps(barrier, new_barrier);
3509 be_set_transformed_node(barrier, new_barrier);
3511 /* transform normally */
3512 return be_duplicate_node(node);
3516 * Transform a be_AddSP into an ia32_SubSP.
3518 static ir_node *gen_be_AddSP(ir_node *node)
3520 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3521 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3523 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3524 match_am | match_immediate);
3528 * Transform a be_SubSP into an ia32_AddSP
3530 static ir_node *gen_be_SubSP(ir_node *node)
3532 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3533 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3535 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3536 match_am | match_immediate);
3540 * Change some phi modes
3542 static ir_node *gen_Phi(ir_node *node)
3544 ir_node *block = be_transform_node(get_nodes_block(node));
3545 ir_graph *irg = current_ir_graph;
3546 dbg_info *dbgi = get_irn_dbg_info(node);
3547 ir_mode *mode = get_irn_mode(node);
3550 if (ia32_mode_needs_gp_reg(mode)) {
3551 /* we shouldn't have any 64bit stuff around anymore */
3552 assert(get_mode_size_bits(mode) <= 32);
3553 /* all integer operations are on 32bit registers now */
3555 } else if (mode_is_float(mode)) {
3556 if (ia32_cg_config.use_sse2) {
3563 /* phi nodes allow loops, so we use the old arguments for now
3564 * and fix this later */
3565 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3566 get_irn_in(node) + 1);
3567 copy_node_attr(node, phi);
3568 be_duplicate_deps(node, phi);
3570 be_enqueue_preds(node);
3578 static ir_node *gen_IJmp(ir_node *node)
3580 ir_node *block = get_nodes_block(node);
3581 ir_node *new_block = be_transform_node(block);
3582 dbg_info *dbgi = get_irn_dbg_info(node);
3583 ir_node *op = get_IJmp_target(node);
3585 ia32_address_mode_t am;
3586 ia32_address_t *addr = &am.addr;
3588 assert(get_irn_mode(op) == mode_P);
3590 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3592 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3593 addr->mem, am.new_op2);
3594 set_am_attributes(new_node, &am);
3595 SET_IA32_ORIG_NODE(new_node, node);
3597 new_node = fix_mem_proj(new_node, &am);
3603 * Transform a Bound node.
3605 static ir_node *gen_Bound(ir_node *node)
3608 ir_node *lower = get_Bound_lower(node);
3609 dbg_info *dbgi = get_irn_dbg_info(node);
3611 if (is_Const_0(lower)) {
3612 /* typical case for Java */
3613 ir_node *sub, *res, *flags, *block;
3614 ir_graph *irg = current_ir_graph;
3616 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3617 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3619 block = get_nodes_block(res);
3620 if (! is_Proj(res)) {
3622 set_irn_mode(sub, mode_T);
3623 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3625 sub = get_Proj_pred(res);
3627 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3628 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3629 SET_IA32_ORIG_NODE(new_node, node);
3631 panic("generic Bound not supported in ia32 Backend");
3637 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3639 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3640 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3642 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3643 match_immediate | match_mode_neutral);
3646 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3648 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3649 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3650 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3654 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3656 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3657 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3658 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3662 static ir_node *gen_ia32_l_Add(ir_node *node)
3664 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3665 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3666 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3667 match_commutative | match_am | match_immediate |
3668 match_mode_neutral);
3670 if (is_Proj(lowered)) {
3671 lowered = get_Proj_pred(lowered);
3673 assert(is_ia32_Add(lowered));
3674 set_irn_mode(lowered, mode_T);
3680 static ir_node *gen_ia32_l_Adc(ir_node *node)
3682 return gen_binop_flags(node, new_bd_ia32_Adc,
3683 match_commutative | match_am | match_immediate |
3684 match_mode_neutral);
3688 * Transforms a l_MulS into a "real" MulS node.
3690 * @return the created ia32 Mul node
3692 static ir_node *gen_ia32_l_Mul(ir_node *node)
3694 ir_node *left = get_binop_left(node);
3695 ir_node *right = get_binop_right(node);
3697 return gen_binop(node, left, right, new_bd_ia32_Mul,
3698 match_commutative | match_am | match_mode_neutral);
3702 * Transforms a l_IMulS into a "real" IMul1OPS node.
3704 * @return the created ia32 IMul1OP node
3706 static ir_node *gen_ia32_l_IMul(ir_node *node)
3708 ir_node *left = get_binop_left(node);
3709 ir_node *right = get_binop_right(node);
3711 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3712 match_commutative | match_am | match_mode_neutral);
3715 static ir_node *gen_ia32_l_Sub(ir_node *node)
3717 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3718 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3719 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3720 match_am | match_immediate | match_mode_neutral);
3722 if (is_Proj(lowered)) {
3723 lowered = get_Proj_pred(lowered);
3725 assert(is_ia32_Sub(lowered));
3726 set_irn_mode(lowered, mode_T);
3732 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3734 return gen_binop_flags(node, new_bd_ia32_Sbb,
3735 match_am | match_immediate | match_mode_neutral);
3739 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3740 * op1 - target to be shifted
3741 * op2 - contains bits to be shifted into target
3743 * Only op3 can be an immediate.
3745 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3746 ir_node *low, ir_node *count)
3748 ir_node *block = get_nodes_block(node);
3749 ir_node *new_block = be_transform_node(block);
3750 dbg_info *dbgi = get_irn_dbg_info(node);
3751 ir_node *new_high = be_transform_node(high);
3752 ir_node *new_low = be_transform_node(low);
3756 /* the shift amount can be any mode that is bigger than 5 bits, since all
3757 * other bits are ignored anyway */
3758 while (is_Conv(count) &&
3759 get_irn_n_edges(count) == 1 &&
3760 mode_is_int(get_irn_mode(count))) {
3761 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3762 count = get_Conv_op(count);
3764 new_count = create_immediate_or_transform(count, 0);
3766 if (is_ia32_l_ShlD(node)) {
3767 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3770 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3773 SET_IA32_ORIG_NODE(new_node, node);
3778 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3780 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3781 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3782 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3783 return gen_lowered_64bit_shifts(node, high, low, count);
3786 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3788 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3789 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3790 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3791 return gen_lowered_64bit_shifts(node, high, low, count);
3794 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3796 ir_node *src_block = get_nodes_block(node);
3797 ir_node *block = be_transform_node(src_block);
3798 ir_graph *irg = current_ir_graph;
3799 dbg_info *dbgi = get_irn_dbg_info(node);
3800 ir_node *frame = get_irg_frame(irg);
3801 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3802 ir_node *nomem = new_NoMem();
3803 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3804 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3805 ir_node *new_val_low = be_transform_node(val_low);
3806 ir_node *new_val_high = be_transform_node(val_high);
3808 ir_node *sync, *fild, *res;
3809 ir_node *store_low, *store_high;
3811 if (ia32_cg_config.use_sse2) {
3812 panic("ia32_l_LLtoFloat not implemented for SSE2");
3816 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3818 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3820 SET_IA32_ORIG_NODE(store_low, node);
3821 SET_IA32_ORIG_NODE(store_high, node);
3823 set_ia32_use_frame(store_low);
3824 set_ia32_use_frame(store_high);
3825 set_ia32_op_type(store_low, ia32_AddrModeD);
3826 set_ia32_op_type(store_high, ia32_AddrModeD);
3827 set_ia32_ls_mode(store_low, mode_Iu);
3828 set_ia32_ls_mode(store_high, mode_Is);
3829 add_ia32_am_offs_int(store_high, 4);
3833 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3836 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg, sync);
3838 set_ia32_use_frame(fild);
3839 set_ia32_op_type(fild, ia32_AddrModeS);
3840 set_ia32_ls_mode(fild, mode_Ls);
3842 SET_IA32_ORIG_NODE(fild, node);
3844 res = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3846 if (! mode_is_signed(get_irn_mode(val_high))) {
3847 ia32_address_mode_t am;
3849 ir_node *count = create_Immediate(NULL, 0, 31);
3852 am.addr.base = ia32_new_NoReg_gp(env_cg);
3853 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
3854 am.addr.mem = nomem;
3857 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
3858 am.addr.use_frame = 0;
3859 am.addr.frame_entity = NULL;
3860 am.addr.symconst_sign = 0;
3861 am.ls_mode = mode_F;
3862 am.mem_proj = nomem;
3863 am.op_type = ia32_AddrModeS;
3865 am.new_op2 = ia32_new_NoReg_vfp(env_cg);
3866 am.pinned = op_pin_state_floats;
3868 am.ins_permuted = 0;
3870 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
3871 am.new_op1, am.new_op2, get_fpcw());
3872 set_am_attributes(fadd, &am);
3874 set_irn_mode(fadd, mode_T);
3875 res = new_rd_Proj(NULL, irg, block, fadd, mode_vfp, pn_ia32_res);
3880 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3882 ir_node *src_block = get_nodes_block(node);
3883 ir_node *block = be_transform_node(src_block);
3884 ir_graph *irg = current_ir_graph;
3885 dbg_info *dbgi = get_irn_dbg_info(node);
3886 ir_node *frame = get_irg_frame(irg);
3887 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3888 ir_node *nomem = new_NoMem();
3889 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3890 ir_node *new_val = be_transform_node(val);
3891 ir_node *fist, *mem;
3893 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3894 SET_IA32_ORIG_NODE(fist, node);
3895 set_ia32_use_frame(fist);
3896 set_ia32_op_type(fist, ia32_AddrModeD);
3897 set_ia32_ls_mode(fist, mode_Ls);
3903 * the BAD transformer.
3905 static ir_node *bad_transform(ir_node *node)
3907 panic("No transform function for %+F available.", node);
3911 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3913 ir_graph *irg = current_ir_graph;
3914 ir_node *block = be_transform_node(get_nodes_block(node));
3915 ir_node *pred = get_Proj_pred(node);
3916 ir_node *new_pred = be_transform_node(pred);
3917 ir_node *frame = get_irg_frame(irg);
3918 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3919 dbg_info *dbgi = get_irn_dbg_info(node);
3920 long pn = get_Proj_proj(node);
3925 load = new_bd_ia32_Load(dbgi, block, frame, noreg, new_pred);
3926 SET_IA32_ORIG_NODE(load, node);
3927 set_ia32_use_frame(load);
3928 set_ia32_op_type(load, ia32_AddrModeS);
3929 set_ia32_ls_mode(load, mode_Iu);
3930 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3931 * 32 bit from it with this particular load */
3932 attr = get_ia32_attr(load);
3933 attr->data.need_64bit_stackent = 1;
3935 if (pn == pn_ia32_l_FloattoLL_res_high) {
3936 add_ia32_am_offs_int(load, 4);
3938 assert(pn == pn_ia32_l_FloattoLL_res_low);
3941 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3947 * Transform the Projs of an AddSP.
3949 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3951 ir_node *block = be_transform_node(get_nodes_block(node));
3952 ir_node *pred = get_Proj_pred(node);
3953 ir_node *new_pred = be_transform_node(pred);
3954 ir_graph *irg = current_ir_graph;
3955 dbg_info *dbgi = get_irn_dbg_info(node);
3956 long proj = get_Proj_proj(node);
3958 if (proj == pn_be_AddSP_sp) {
3959 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3960 pn_ia32_SubSP_stack);
3961 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3963 } else if (proj == pn_be_AddSP_res) {
3964 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3965 pn_ia32_SubSP_addr);
3966 } else if (proj == pn_be_AddSP_M) {
3967 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3970 panic("No idea how to transform proj->AddSP");
3974 * Transform the Projs of a SubSP.
3976 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3978 ir_node *block = be_transform_node(get_nodes_block(node));
3979 ir_node *pred = get_Proj_pred(node);
3980 ir_node *new_pred = be_transform_node(pred);
3981 ir_graph *irg = current_ir_graph;
3982 dbg_info *dbgi = get_irn_dbg_info(node);
3983 long proj = get_Proj_proj(node);
3985 if (proj == pn_be_SubSP_sp) {
3986 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3987 pn_ia32_AddSP_stack);
3988 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3990 } else if (proj == pn_be_SubSP_M) {
3991 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3994 panic("No idea how to transform proj->SubSP");
3998 * Transform and renumber the Projs from a Load.
4000 static ir_node *gen_Proj_Load(ir_node *node)
4003 ir_node *block = be_transform_node(get_nodes_block(node));
4004 ir_node *pred = get_Proj_pred(node);
4005 ir_graph *irg = current_ir_graph;
4006 dbg_info *dbgi = get_irn_dbg_info(node);
4007 long proj = get_Proj_proj(node);
4009 /* loads might be part of source address mode matches, so we don't
4010 * transform the ProjMs yet (with the exception of loads whose result is
4013 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4016 /* this is needed, because sometimes we have loops that are only
4017 reachable through the ProjM */
4018 be_enqueue_preds(node);
4019 /* do it in 2 steps, to silence firm verifier */
4020 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4021 set_Proj_proj(res, pn_ia32_mem);
4025 /* renumber the proj */
4026 new_pred = be_transform_node(pred);
4027 if (is_ia32_Load(new_pred)) {
4030 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4032 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4033 case pn_Load_X_regular:
4034 return new_rd_Jmp(dbgi, irg, block);
4035 case pn_Load_X_except:
4036 /* This Load might raise an exception. Mark it. */
4037 set_ia32_exc_label(new_pred, 1);
4038 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4042 } else if (is_ia32_Conv_I2I(new_pred) ||
4043 is_ia32_Conv_I2I8Bit(new_pred)) {
4044 set_irn_mode(new_pred, mode_T);
4045 if (proj == pn_Load_res) {
4046 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4047 } else if (proj == pn_Load_M) {
4048 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4050 } else if (is_ia32_xLoad(new_pred)) {
4053 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4055 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4056 case pn_Load_X_regular:
4057 return new_rd_Jmp(dbgi, irg, block);
4058 case pn_Load_X_except:
4059 /* This Load might raise an exception. Mark it. */
4060 set_ia32_exc_label(new_pred, 1);
4061 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4065 } else if (is_ia32_vfld(new_pred)) {
4068 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4070 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4071 case pn_Load_X_regular:
4072 return new_rd_Jmp(dbgi, irg, block);
4073 case pn_Load_X_except:
4074 /* This Load might raise an exception. Mark it. */
4075 set_ia32_exc_label(new_pred, 1);
4076 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4081 /* can happen for ProJMs when source address mode happened for the
4084 /* however it should not be the result proj, as that would mean the
4085 load had multiple users and should not have been used for
4087 if (proj != pn_Load_M) {
4088 panic("internal error: transformed node not a Load");
4090 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4093 panic("No idea how to transform proj");
4097 * Transform and renumber the Projs from a DivMod like instruction.
4099 static ir_node *gen_Proj_DivMod(ir_node *node)
4101 ir_node *block = be_transform_node(get_nodes_block(node));
4102 ir_node *pred = get_Proj_pred(node);
4103 ir_node *new_pred = be_transform_node(pred);
4104 ir_graph *irg = current_ir_graph;
4105 dbg_info *dbgi = get_irn_dbg_info(node);
4106 long proj = get_Proj_proj(node);
4108 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4110 switch (get_irn_opcode(pred)) {
4114 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4116 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4117 case pn_Div_X_regular:
4118 return new_rd_Jmp(dbgi, irg, block);
4119 case pn_Div_X_except:
4120 set_ia32_exc_label(new_pred, 1);
4121 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4129 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4131 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4132 case pn_Mod_X_except:
4133 set_ia32_exc_label(new_pred, 1);
4134 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4142 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4143 case pn_DivMod_res_div:
4144 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4145 case pn_DivMod_res_mod:
4146 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4147 case pn_DivMod_X_regular:
4148 return new_rd_Jmp(dbgi, irg, block);
4149 case pn_DivMod_X_except:
4150 set_ia32_exc_label(new_pred, 1);
4151 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4160 panic("No idea how to transform proj->DivMod");
4164 * Transform and renumber the Projs from a CopyB.
4166 static ir_node *gen_Proj_CopyB(ir_node *node)
4168 ir_node *block = be_transform_node(get_nodes_block(node));
4169 ir_node *pred = get_Proj_pred(node);
4170 ir_node *new_pred = be_transform_node(pred);
4171 ir_graph *irg = current_ir_graph;
4172 dbg_info *dbgi = get_irn_dbg_info(node);
4173 long proj = get_Proj_proj(node);
4176 case pn_CopyB_M_regular:
4177 if (is_ia32_CopyB_i(new_pred)) {
4178 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4179 } else if (is_ia32_CopyB(new_pred)) {
4180 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4187 panic("No idea how to transform proj->CopyB");
4191 * Transform and renumber the Projs from a Quot.
4193 static ir_node *gen_Proj_Quot(ir_node *node)
4195 ir_node *block = be_transform_node(get_nodes_block(node));
4196 ir_node *pred = get_Proj_pred(node);
4197 ir_node *new_pred = be_transform_node(pred);
4198 ir_graph *irg = current_ir_graph;
4199 dbg_info *dbgi = get_irn_dbg_info(node);
4200 long proj = get_Proj_proj(node);
4204 if (is_ia32_xDiv(new_pred)) {
4205 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4206 } else if (is_ia32_vfdiv(new_pred)) {
4207 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4211 if (is_ia32_xDiv(new_pred)) {
4212 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4213 } else if (is_ia32_vfdiv(new_pred)) {
4214 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4217 case pn_Quot_X_regular:
4218 case pn_Quot_X_except:
4223 panic("No idea how to transform proj->Quot");
4226 static ir_node *gen_be_Call(ir_node *node)
4228 dbg_info *const dbgi = get_irn_dbg_info(node);
4229 ir_graph *const irg = current_ir_graph;
4230 ir_node *const src_block = get_nodes_block(node);
4231 ir_node *const block = be_transform_node(src_block);
4232 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4233 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4234 ir_node *const sp = be_transform_node(src_sp);
4235 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4236 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4237 ia32_address_mode_t am;
4238 ia32_address_t *const addr = &am.addr;
4243 ir_node * eax = noreg;
4244 ir_node * ecx = noreg;
4245 ir_node * edx = noreg;
4246 unsigned const pop = be_Call_get_pop(node);
4247 ir_type *const call_tp = be_Call_get_type(node);
4249 /* Run the x87 simulator if the call returns a float value */
4250 if (get_method_n_ress(call_tp) > 0) {
4251 ir_type *const res_type = get_method_res_type(call_tp, 0);
4252 ir_mode *const res_mode = get_type_mode(res_type);
4254 if (res_mode != NULL && mode_is_float(res_mode)) {
4255 env_cg->do_x87_sim = 1;
4259 /* We do not want be_Call direct calls */
4260 assert(be_Call_get_entity(node) == NULL);
4262 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4263 match_am | match_immediate);
4265 i = get_irn_arity(node) - 1;
4266 fpcw = be_transform_node(get_irn_n(node, i--));
4267 for (; i >= be_pos_Call_first_arg; --i) {
4268 arch_register_req_t const *const req = arch_get_register_req(node, i);
4269 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4271 assert(req->type == arch_register_req_type_limited);
4272 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4274 switch (*req->limited) {
4275 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4276 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4277 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4278 default: panic("Invalid GP register for register parameter");
4282 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4283 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4284 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4285 set_am_attributes(call, &am);
4286 call = fix_mem_proj(call, &am);
4288 if (get_irn_pinned(node) == op_pin_state_pinned)
4289 set_irn_pinned(call, op_pin_state_pinned);
4291 SET_IA32_ORIG_NODE(call, node);
4295 static ir_node *gen_be_IncSP(ir_node *node)
4297 ir_node *res = be_duplicate_node(node);
4298 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4304 * Transform the Projs from a be_Call.
4306 static ir_node *gen_Proj_be_Call(ir_node *node)
4308 ir_node *block = be_transform_node(get_nodes_block(node));
4309 ir_node *call = get_Proj_pred(node);
4310 ir_node *new_call = be_transform_node(call);
4311 ir_graph *irg = current_ir_graph;
4312 dbg_info *dbgi = get_irn_dbg_info(node);
4313 ir_type *method_type = be_Call_get_type(call);
4314 int n_res = get_method_n_ress(method_type);
4315 long proj = get_Proj_proj(node);
4316 ir_mode *mode = get_irn_mode(node);
4320 /* The following is kinda tricky: If we're using SSE, then we have to
4321 * move the result value of the call in floating point registers to an
4322 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4323 * after the call, we have to make sure to correctly make the
4324 * MemProj and the result Proj use these 2 nodes
4326 if (proj == pn_be_Call_M_regular) {
4327 // get new node for result, are we doing the sse load/store hack?
4328 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4329 ir_node *call_res_new;
4330 ir_node *call_res_pred = NULL;
4332 if (call_res != NULL) {
4333 call_res_new = be_transform_node(call_res);
4334 call_res_pred = get_Proj_pred(call_res_new);
4337 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4338 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4341 assert(is_ia32_xLoad(call_res_pred));
4342 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4346 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4347 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4349 ir_node *frame = get_irg_frame(irg);
4350 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4352 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4355 /* in case there is no memory output: create one to serialize the copy
4357 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4358 pn_be_Call_M_regular);
4359 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4360 pn_be_Call_first_res);
4362 /* store st(0) onto stack */
4363 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg, call_mem,
4365 set_ia32_op_type(fstp, ia32_AddrModeD);
4366 set_ia32_use_frame(fstp);
4368 /* load into SSE register */
4369 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg, fstp, mode);
4370 set_ia32_op_type(sse_load, ia32_AddrModeS);
4371 set_ia32_use_frame(sse_load);
4373 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4379 /* transform call modes */
4380 if (mode_is_data(mode)) {
4381 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4385 /* Map from be_Call to ia32_Call proj number */
4386 if (proj == pn_be_Call_sp) {
4387 proj = pn_ia32_Call_stack;
4388 } else if (proj == pn_be_Call_M_regular) {
4389 proj = pn_ia32_Call_M;
4391 arch_register_req_t const *const req = arch_get_register_req_out(node);
4392 int const n_outs = arch_irn_get_n_outs(new_call);
4395 assert(proj >= pn_be_Call_first_res);
4396 assert(req->type & arch_register_req_type_limited);
4398 for (i = 0; i < n_outs; ++i) {
4399 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4401 if (!(new_req->type & arch_register_req_type_limited) ||
4402 new_req->cls != req->cls ||
4403 *new_req->limited != *req->limited)
4412 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4414 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4416 case pn_ia32_Call_stack:
4417 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4420 case pn_ia32_Call_fpcw:
4421 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4429 * Transform the Projs from a Cmp.
4431 static ir_node *gen_Proj_Cmp(ir_node *node)
4433 /* this probably means not all mode_b nodes were lowered... */
4434 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4439 * Transform the Projs from a Bound.
4441 static ir_node *gen_Proj_Bound(ir_node *node)
4443 ir_node *new_node, *block;
4444 ir_node *pred = get_Proj_pred(node);
4446 switch (get_Proj_proj(node)) {
4448 return be_transform_node(get_Bound_mem(pred));
4449 case pn_Bound_X_regular:
4450 new_node = be_transform_node(pred);
4451 block = get_nodes_block(new_node);
4452 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4453 case pn_Bound_X_except:
4454 new_node = be_transform_node(pred);
4455 block = get_nodes_block(new_node);
4456 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4458 return be_transform_node(get_Bound_index(pred));
4460 panic("unsupported Proj from Bound");
4464 static ir_node *gen_Proj_ASM(ir_node *node)
4470 if (get_irn_mode(node) != mode_M)
4471 return be_duplicate_node(node);
4473 pred = get_Proj_pred(node);
4474 new_pred = be_transform_node(pred);
4475 block = get_nodes_block(new_pred);
4476 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4477 arch_irn_get_n_outs(new_pred) + 1);
4481 * Transform and potentially renumber Proj nodes.
4483 static ir_node *gen_Proj(ir_node *node)
4485 ir_node *pred = get_Proj_pred(node);
4488 switch (get_irn_opcode(pred)) {
4490 proj = get_Proj_proj(node);
4491 if (proj == pn_Store_M) {
4492 return be_transform_node(pred);
4494 panic("No idea how to transform proj->Store");
4497 return gen_Proj_Load(node);
4499 return gen_Proj_ASM(node);
4503 return gen_Proj_DivMod(node);
4505 return gen_Proj_CopyB(node);
4507 return gen_Proj_Quot(node);
4509 return gen_Proj_be_SubSP(node);
4511 return gen_Proj_be_AddSP(node);
4513 return gen_Proj_be_Call(node);
4515 return gen_Proj_Cmp(node);
4517 return gen_Proj_Bound(node);
4519 proj = get_Proj_proj(node);
4521 case pn_Start_X_initial_exec: {
4522 ir_node *block = get_nodes_block(pred);
4523 ir_node *new_block = be_transform_node(block);
4524 dbg_info *dbgi = get_irn_dbg_info(node);
4525 /* we exchange the ProjX with a jump */
4526 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4531 case pn_Start_P_tls:
4532 return gen_Proj_tls(node);
4537 if (is_ia32_l_FloattoLL(pred)) {
4538 return gen_Proj_l_FloattoLL(node);
4540 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4544 ir_mode *mode = get_irn_mode(node);
4545 if (ia32_mode_needs_gp_reg(mode)) {
4546 ir_node *new_pred = be_transform_node(pred);
4547 ir_node *block = be_transform_node(get_nodes_block(node));
4548 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4549 mode_Iu, get_Proj_proj(node));
4550 #ifdef DEBUG_libfirm
4551 new_proj->node_nr = node->node_nr;
4557 return be_duplicate_node(node);
4561 * Enters all transform functions into the generic pointer
4563 static void register_transformers(void)
4567 /* first clear the generic function pointer for all ops */
4568 clear_irp_opcodes_generic_func();
4570 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4571 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4609 /* transform ops from intrinsic lowering */
4621 GEN(ia32_l_LLtoFloat);
4622 GEN(ia32_l_FloattoLL);
4628 /* we should never see these nodes */
4643 /* handle generic backend nodes */
4652 op_Mulh = get_op_Mulh();
4661 * Pre-transform all unknown and noreg nodes.
4663 static void ia32_pretransform_node(void)
4665 ia32_code_gen_t *cg = env_cg;
4667 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4668 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4669 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4670 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4671 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4672 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4677 * Walker, checks if all ia32 nodes producing more than one result have their
4678 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4680 static void add_missing_keep_walker(ir_node *node, void *data)
4683 unsigned found_projs = 0;
4684 const ir_edge_t *edge;
4685 ir_mode *mode = get_irn_mode(node);
4690 if (!is_ia32_irn(node))
4693 n_outs = arch_irn_get_n_outs(node);
4696 if (is_ia32_SwitchJmp(node))
4699 assert(n_outs < (int) sizeof(unsigned) * 8);
4700 foreach_out_edge(node, edge) {
4701 ir_node *proj = get_edge_src_irn(edge);
4704 /* The node could be kept */
4708 if (get_irn_mode(proj) == mode_M)
4711 pn = get_Proj_proj(proj);
4712 assert(pn < n_outs);
4713 found_projs |= 1 << pn;
4717 /* are keeps missing? */
4719 for (i = 0; i < n_outs; ++i) {
4722 const arch_register_req_t *req;
4723 const arch_register_class_t *cls;
4725 if (found_projs & (1 << i)) {
4729 req = get_ia32_out_req(node, i);
4734 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4738 block = get_nodes_block(node);
4739 in[0] = new_r_Proj(current_ir_graph, block, node,
4740 arch_register_class_mode(cls), i);
4741 if (last_keep != NULL) {
4742 be_Keep_add_node(last_keep, cls, in[0]);
4744 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4745 if (sched_is_scheduled(node)) {
4746 sched_add_after(node, last_keep);
4753 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4756 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4758 ir_graph *irg = be_get_birg_irg(cg->birg);
4759 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4762 /* do the transformation */
4763 void ia32_transform_graph(ia32_code_gen_t *cg)
4767 register_transformers();
4769 initial_fpcw = NULL;
4771 BE_TIMER_PUSH(t_heights);
4772 heights = heights_new(cg->irg);
4773 BE_TIMER_POP(t_heights);
4774 ia32_calculate_non_address_mode_nodes(cg->birg);
4776 /* the transform phase is not safe for CSE (yet) because several nodes get
4777 * attributes set after their creation */
4778 cse_last = get_opt_cse();
4781 be_transform_graph(cg->birg, ia32_pretransform_node);
4783 set_opt_cse(cse_last);
4785 ia32_free_non_address_mode_nodes();
4786 heights_free(heights);
4790 void ia32_init_transform(void)
4792 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");