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_INT_MAX "ia32_int_max"
86 #define TP_ULL_BIAS "ia32_ull_bias"
88 #define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
89 #define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
90 #define ENT_SFP_ABS ".LC_ia32_sfp_abs"
91 #define ENT_DFP_ABS ".LC_ia32_dfp_abs"
92 #define ENT_INT_MAX ".LC_ia32_int_max"
93 #define ENT_ULL_BIAS ".LC_ia32_ull_bias"
95 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
96 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
98 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
100 static ir_node *initial_fpcw = NULL;
102 extern ir_op *get_op_Mulh(void);
104 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
105 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
108 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
109 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
112 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
113 ir_node *op1, ir_node *op2);
115 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
116 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
118 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
119 ir_node *base, ir_node *index, ir_node *mem);
121 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
122 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
125 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
127 static ir_node *create_immediate_or_transform(ir_node *node,
128 char immediate_constraint_type);
130 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
131 dbg_info *dbgi, ir_node *block,
132 ir_node *op, ir_node *orig_node);
134 /** Return non-zero is a node represents the 0 constant. */
135 static bool is_Const_0(ir_node *node)
137 return is_Const(node) && is_Const_null(node);
140 /** Return non-zero is a node represents the 1 constant. */
141 static bool is_Const_1(ir_node *node)
143 return is_Const(node) && is_Const_one(node);
146 /** Return non-zero is a node represents the -1 constant. */
147 static bool is_Const_Minus_1(ir_node *node)
149 return is_Const(node) && is_Const_all_one(node);
153 * returns true if constant can be created with a simple float command
155 static bool is_simple_x87_Const(ir_node *node)
157 tarval *tv = get_Const_tarval(node);
158 if (tarval_is_null(tv) || tarval_is_one(tv))
161 /* TODO: match all the other float constants */
166 * returns true if constant can be created with a simple float command
168 static bool is_simple_sse_Const(ir_node *node)
170 tarval *tv = get_Const_tarval(node);
171 ir_mode *mode = get_tarval_mode(tv);
176 if (tarval_is_null(tv) || tarval_is_one(tv))
179 if (mode == mode_D) {
180 unsigned val = get_tarval_sub_bits(tv, 0) |
181 (get_tarval_sub_bits(tv, 1) << 8) |
182 (get_tarval_sub_bits(tv, 2) << 16) |
183 (get_tarval_sub_bits(tv, 3) << 24);
185 /* lower 32bit are zero, really a 32bit constant */
189 /* TODO: match all the other float constants */
194 * Transforms a Const.
196 static ir_node *gen_Const(ir_node *node)
198 ir_node *old_block = get_nodes_block(node);
199 ir_node *block = be_transform_node(old_block);
200 dbg_info *dbgi = get_irn_dbg_info(node);
201 ir_mode *mode = get_irn_mode(node);
203 assert(is_Const(node));
205 if (mode_is_float(mode)) {
207 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
208 ir_node *nomem = new_NoMem();
212 if (ia32_cg_config.use_sse2) {
213 tarval *tv = get_Const_tarval(node);
214 if (tarval_is_null(tv)) {
215 load = new_bd_ia32_xZero(dbgi, block);
216 set_ia32_ls_mode(load, mode);
218 } else if (tarval_is_one(tv)) {
219 int cnst = mode == mode_F ? 26 : 55;
220 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
221 ir_node *imm2 = create_Immediate(NULL, 0, 2);
222 ir_node *pslld, *psrld;
224 load = new_bd_ia32_xAllOnes(dbgi, block);
225 set_ia32_ls_mode(load, mode);
226 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
227 set_ia32_ls_mode(pslld, mode);
228 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
229 set_ia32_ls_mode(psrld, mode);
231 } else if (mode == mode_F) {
232 /* we can place any 32bit constant by using a movd gp, sse */
233 unsigned val = get_tarval_sub_bits(tv, 0) |
234 (get_tarval_sub_bits(tv, 1) << 8) |
235 (get_tarval_sub_bits(tv, 2) << 16) |
236 (get_tarval_sub_bits(tv, 3) << 24);
237 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
238 load = new_bd_ia32_xMovd(dbgi, block, cnst);
239 set_ia32_ls_mode(load, mode);
242 if (mode == mode_D) {
243 unsigned val = get_tarval_sub_bits(tv, 0) |
244 (get_tarval_sub_bits(tv, 1) << 8) |
245 (get_tarval_sub_bits(tv, 2) << 16) |
246 (get_tarval_sub_bits(tv, 3) << 24);
248 ir_node *imm32 = create_Immediate(NULL, 0, 32);
249 ir_node *cnst, *psllq;
251 /* fine, lower 32bit are zero, produce 32bit value */
252 val = get_tarval_sub_bits(tv, 4) |
253 (get_tarval_sub_bits(tv, 5) << 8) |
254 (get_tarval_sub_bits(tv, 6) << 16) |
255 (get_tarval_sub_bits(tv, 7) << 24);
256 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
257 load = new_bd_ia32_xMovd(dbgi, block, cnst);
258 set_ia32_ls_mode(load, mode);
259 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
260 set_ia32_ls_mode(psllq, mode);
265 floatent = create_float_const_entity(node);
267 load = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem,
269 set_ia32_op_type(load, ia32_AddrModeS);
270 set_ia32_am_sc(load, floatent);
271 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
272 res = new_r_Proj(current_ir_graph, block, load, mode_xmm, pn_ia32_xLoad_res);
275 if (is_Const_null(node)) {
276 load = new_bd_ia32_vfldz(dbgi, block);
278 set_ia32_ls_mode(load, mode);
279 } else if (is_Const_one(node)) {
280 load = new_bd_ia32_vfld1(dbgi, block);
282 set_ia32_ls_mode(load, mode);
284 floatent = create_float_const_entity(node);
286 load = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode);
287 set_ia32_op_type(load, ia32_AddrModeS);
288 set_ia32_am_sc(load, floatent);
289 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
290 res = new_r_Proj(current_ir_graph, block, load, mode_vfp, pn_ia32_vfld_res);
291 /* take the mode from the entity */
292 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
296 SET_IA32_ORIG_NODE(load, node);
298 be_dep_on_frame(load);
300 } else { /* non-float mode */
302 tarval *tv = get_Const_tarval(node);
305 tv = tarval_convert_to(tv, mode_Iu);
307 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
309 panic("couldn't convert constant tarval (%+F)", node);
311 val = get_tarval_long(tv);
313 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
314 SET_IA32_ORIG_NODE(cnst, node);
316 be_dep_on_frame(cnst);
322 * Transforms a SymConst.
324 static ir_node *gen_SymConst(ir_node *node)
326 ir_node *old_block = get_nodes_block(node);
327 ir_node *block = be_transform_node(old_block);
328 dbg_info *dbgi = get_irn_dbg_info(node);
329 ir_mode *mode = get_irn_mode(node);
332 if (mode_is_float(mode)) {
333 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
334 ir_node *nomem = new_NoMem();
336 if (ia32_cg_config.use_sse2)
337 cnst = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem, mode_E);
339 cnst = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode_E);
340 set_ia32_am_sc(cnst, get_SymConst_entity(node));
341 set_ia32_use_frame(cnst);
345 if (get_SymConst_kind(node) != symconst_addr_ent) {
346 panic("backend only support symconst_addr_ent (at %+F)", node);
348 entity = get_SymConst_entity(node);
349 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0);
352 SET_IA32_ORIG_NODE(cnst, node);
354 be_dep_on_frame(cnst);
358 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
359 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
361 static const struct {
363 const char *ent_name;
364 const char *cnst_str;
367 } names [ia32_known_const_max] = {
368 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
369 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
370 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
371 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
372 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 }, /* ia32_INTMAX */
373 { TP_ULL_BIAS, ENT_ULL_BIAS, ULL_BIAS, 3, 4 } /* ia32_ULLBIAS */
375 static ir_entity *ent_cache[ia32_known_const_max];
377 const char *tp_name, *ent_name, *cnst_str;
383 ent_name = names[kct].ent_name;
384 if (! ent_cache[kct]) {
385 tp_name = names[kct].tp_name;
386 cnst_str = names[kct].cnst_str;
388 switch (names[kct].mode) {
389 case 0: mode = mode_Iu; break;
390 case 1: mode = mode_Lu; break;
391 default: mode = mode_F; break;
393 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
394 tp = new_type_primitive(new_id_from_str(tp_name), mode);
395 /* set the specified alignment */
396 set_type_alignment_bytes(tp, names[kct].align);
398 if (kct == ia32_ULLBIAS) {
399 /* we are in the backend, construct a fixed type here */
400 unsigned size = get_type_size_bytes(tp);
401 tp = new_type_array(new_id_from_str(tp_name), 1, tp);
402 set_type_alignment_bytes(tp, names[kct].align);
403 set_type_size_bytes(tp, 2 * size);
404 set_type_state(tp, layout_fixed);
406 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
408 set_entity_ld_ident(ent, get_entity_ident(ent));
409 set_entity_visibility(ent, visibility_local);
410 set_entity_variability(ent, variability_constant);
411 set_entity_allocation(ent, allocation_static);
413 if (kct == ia32_ULLBIAS) {
414 ir_initializer_t *initializer = create_initializer_compound(2);
416 set_initializer_compound_value(initializer, 0,
417 create_initializer_tarval(get_tarval_null(mode)));
418 set_initializer_compound_value(initializer, 1,
419 create_initializer_tarval(tv));
421 set_entity_initializer(ent, initializer);
423 set_entity_initializer(ent, create_initializer_tarval(tv));
426 /* cache the entry */
427 ent_cache[kct] = ent;
430 return ent_cache[kct];
434 * return true if the node is a Proj(Load) and could be used in source address
435 * mode for another node. Will return only true if the @p other node is not
436 * dependent on the memory of the Load (for binary operations use the other
437 * input here, for unary operations use NULL).
439 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
440 ir_node *other, ir_node *other2, match_flags_t flags)
445 /* float constants are always available */
446 if (is_Const(node)) {
447 ir_mode *mode = get_irn_mode(node);
448 if (mode_is_float(mode)) {
449 if (ia32_cg_config.use_sse2) {
450 if (is_simple_sse_Const(node))
453 if (is_simple_x87_Const(node))
456 if (get_irn_n_edges(node) > 1)
464 load = get_Proj_pred(node);
465 pn = get_Proj_proj(node);
466 if (!is_Load(load) || pn != pn_Load_res)
468 if (get_nodes_block(load) != block)
470 /* we only use address mode if we're the only user of the load */
471 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
473 /* in some edge cases with address mode we might reach the load normally
474 * and through some AM sequence, if it is already materialized then we
475 * can't create an AM node from it */
476 if (be_is_transformed(node))
479 /* don't do AM if other node inputs depend on the load (via mem-proj) */
480 if (other != NULL && prevents_AM(block, load, other))
483 if (other2 != NULL && prevents_AM(block, load, other2))
489 typedef struct ia32_address_mode_t ia32_address_mode_t;
490 struct ia32_address_mode_t {
495 ia32_op_type_t op_type;
499 unsigned commutative : 1;
500 unsigned ins_permuted : 1;
503 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
507 /* construct load address */
508 memset(addr, 0, sizeof(addr[0]));
509 ia32_create_address_mode(addr, ptr, 0);
511 noreg_gp = ia32_new_NoReg_gp(env_cg);
512 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
513 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
514 addr->mem = be_transform_node(mem);
517 static void build_address(ia32_address_mode_t *am, ir_node *node,
518 ia32_create_am_flags_t flags)
520 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
521 ia32_address_t *addr = &am->addr;
527 if (is_Const(node)) {
528 ir_entity *entity = create_float_const_entity(node);
529 addr->base = noreg_gp;
530 addr->index = noreg_gp;
531 addr->mem = new_NoMem();
532 addr->symconst_ent = entity;
534 am->ls_mode = get_type_mode(get_entity_type(entity));
535 am->pinned = op_pin_state_floats;
539 load = get_Proj_pred(node);
540 ptr = get_Load_ptr(load);
541 mem = get_Load_mem(load);
542 new_mem = be_transform_node(mem);
543 am->pinned = get_irn_pinned(load);
544 am->ls_mode = get_Load_mode(load);
545 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
548 /* construct load address */
549 ia32_create_address_mode(addr, ptr, flags);
551 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
552 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
556 static void set_address(ir_node *node, const ia32_address_t *addr)
558 set_ia32_am_scale(node, addr->scale);
559 set_ia32_am_sc(node, addr->symconst_ent);
560 set_ia32_am_offs_int(node, addr->offset);
561 if (addr->symconst_sign)
562 set_ia32_am_sc_sign(node);
564 set_ia32_use_frame(node);
565 set_ia32_frame_ent(node, addr->frame_entity);
569 * Apply attributes of a given address mode to a node.
571 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
573 set_address(node, &am->addr);
575 set_ia32_op_type(node, am->op_type);
576 set_ia32_ls_mode(node, am->ls_mode);
577 if (am->pinned == op_pin_state_pinned) {
578 /* beware: some nodes are already pinned and did not allow to change the state */
579 if (get_irn_pinned(node) != op_pin_state_pinned)
580 set_irn_pinned(node, op_pin_state_pinned);
583 set_ia32_commutative(node);
587 * Check, if a given node is a Down-Conv, ie. a integer Conv
588 * from a mode with a mode with more bits to a mode with lesser bits.
589 * Moreover, we return only true if the node has not more than 1 user.
591 * @param node the node
592 * @return non-zero if node is a Down-Conv
594 static int is_downconv(const ir_node *node)
602 /* we only want to skip the conv when we're the only user
603 * (not optimal but for now...)
605 if (get_irn_n_edges(node) > 1)
608 src_mode = get_irn_mode(get_Conv_op(node));
609 dest_mode = get_irn_mode(node);
611 ia32_mode_needs_gp_reg(src_mode) &&
612 ia32_mode_needs_gp_reg(dest_mode) &&
613 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
616 /* Skip all Down-Conv's on a given node and return the resulting node. */
617 ir_node *ia32_skip_downconv(ir_node *node)
619 while (is_downconv(node))
620 node = get_Conv_op(node);
625 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
627 ir_mode *mode = get_irn_mode(node);
632 if (mode_is_signed(mode)) {
637 block = get_nodes_block(node);
638 dbgi = get_irn_dbg_info(node);
640 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
644 * matches operands of a node into ia32 addressing/operand modes. This covers
645 * usage of source address mode, immediates, operations with non 32-bit modes,
647 * The resulting data is filled into the @p am struct. block is the block
648 * of the node whose arguments are matched. op1, op2 are the first and second
649 * input that are matched (op1 may be NULL). other_op is another unrelated
650 * input that is not matched! but which is needed sometimes to check if AM
651 * for op1/op2 is legal.
652 * @p flags describes the supported modes of the operation in detail.
654 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
655 ir_node *op1, ir_node *op2, ir_node *other_op,
658 ia32_address_t *addr = &am->addr;
659 ir_mode *mode = get_irn_mode(op2);
660 int mode_bits = get_mode_size_bits(mode);
661 ir_node *noreg_gp, *new_op1, *new_op2;
663 unsigned commutative;
664 int use_am_and_immediates;
667 memset(am, 0, sizeof(am[0]));
669 commutative = (flags & match_commutative) != 0;
670 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
671 use_am = (flags & match_am) != 0;
672 use_immediate = (flags & match_immediate) != 0;
673 assert(!use_am_and_immediates || use_immediate);
676 assert(!commutative || op1 != NULL);
677 assert(use_am || !(flags & match_8bit_am));
678 assert(use_am || !(flags & match_16bit_am));
680 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
681 (mode_bits == 16 && !(flags & match_16bit_am))) {
685 /* we can simply skip downconvs for mode neutral nodes: the upper bits
686 * can be random for these operations */
687 if (flags & match_mode_neutral) {
688 op2 = ia32_skip_downconv(op2);
690 op1 = ia32_skip_downconv(op1);
694 /* match immediates. firm nodes are normalized: constants are always on the
697 if (!(flags & match_try_am) && use_immediate) {
698 new_op2 = try_create_Immediate(op2, 0);
701 noreg_gp = ia32_new_NoReg_gp(env_cg);
702 if (new_op2 == NULL &&
703 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
704 build_address(am, op2, 0);
705 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
706 if (mode_is_float(mode)) {
707 new_op2 = ia32_new_NoReg_vfp(env_cg);
711 am->op_type = ia32_AddrModeS;
712 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
714 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
716 build_address(am, op1, 0);
718 if (mode_is_float(mode)) {
719 noreg = ia32_new_NoReg_vfp(env_cg);
724 if (new_op2 != NULL) {
727 new_op1 = be_transform_node(op2);
729 am->ins_permuted = 1;
731 am->op_type = ia32_AddrModeS;
733 am->op_type = ia32_Normal;
735 if (flags & match_try_am) {
741 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
743 new_op2 = be_transform_node(op2);
745 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
747 if (addr->base == NULL)
748 addr->base = noreg_gp;
749 if (addr->index == NULL)
750 addr->index = noreg_gp;
751 if (addr->mem == NULL)
752 addr->mem = new_NoMem();
754 am->new_op1 = new_op1;
755 am->new_op2 = new_op2;
756 am->commutative = commutative;
759 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
764 if (am->mem_proj == NULL)
767 /* we have to create a mode_T so the old MemProj can attach to us */
768 mode = get_irn_mode(node);
769 load = get_Proj_pred(am->mem_proj);
771 be_set_transformed_node(load, node);
773 if (mode != mode_T) {
774 set_irn_mode(node, mode_T);
775 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
782 * Construct a standard binary operation, set AM and immediate if required.
784 * @param node The original node for which the binop is created
785 * @param op1 The first operand
786 * @param op2 The second operand
787 * @param func The node constructor function
788 * @return The constructed ia32 node.
790 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
791 construct_binop_func *func, match_flags_t flags)
794 ir_node *block, *new_block, *new_node;
795 ia32_address_mode_t am;
796 ia32_address_t *addr = &am.addr;
798 block = get_nodes_block(node);
799 match_arguments(&am, block, op1, op2, NULL, flags);
801 dbgi = get_irn_dbg_info(node);
802 new_block = be_transform_node(block);
803 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
804 am.new_op1, am.new_op2);
805 set_am_attributes(new_node, &am);
806 /* we can't use source address mode anymore when using immediates */
807 if (!(flags & match_am_and_immediates) &&
808 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
809 set_ia32_am_support(new_node, ia32_am_none);
810 SET_IA32_ORIG_NODE(new_node, node);
812 new_node = fix_mem_proj(new_node, &am);
819 n_ia32_l_binop_right,
820 n_ia32_l_binop_eflags
822 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
823 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
824 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
825 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
826 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
827 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
830 * Construct a binary operation which also consumes the eflags.
832 * @param node The node to transform
833 * @param func The node constructor function
834 * @param flags The match flags
835 * @return The constructor ia32 node
837 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
840 ir_node *src_block = get_nodes_block(node);
841 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
842 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
843 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
845 ir_node *block, *new_node, *new_eflags;
846 ia32_address_mode_t am;
847 ia32_address_t *addr = &am.addr;
849 match_arguments(&am, src_block, op1, op2, eflags, flags);
851 dbgi = get_irn_dbg_info(node);
852 block = be_transform_node(src_block);
853 new_eflags = be_transform_node(eflags);
854 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
855 am.new_op1, am.new_op2, new_eflags);
856 set_am_attributes(new_node, &am);
857 /* we can't use source address mode anymore when using immediates */
858 if (!(flags & match_am_and_immediates) &&
859 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
860 set_ia32_am_support(new_node, ia32_am_none);
861 SET_IA32_ORIG_NODE(new_node, node);
863 new_node = fix_mem_proj(new_node, &am);
868 static ir_node *get_fpcw(void)
871 if (initial_fpcw != NULL)
874 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
875 &ia32_fp_cw_regs[REG_FPCW]);
876 initial_fpcw = be_transform_node(fpcw);
882 * Construct a standard binary operation, set AM and immediate if required.
884 * @param op1 The first operand
885 * @param op2 The second operand
886 * @param func The node constructor function
887 * @return The constructed ia32 node.
889 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
890 construct_binop_float_func *func)
892 ir_mode *mode = get_irn_mode(node);
894 ir_node *block, *new_block, *new_node;
895 ia32_address_mode_t am;
896 ia32_address_t *addr = &am.addr;
897 ia32_x87_attr_t *attr;
898 /* All operations are considered commutative, because there are reverse
900 match_flags_t flags = match_commutative;
902 /* cannot use address mode with long double on x87 */
903 if (get_mode_size_bits(mode) <= 64)
906 block = get_nodes_block(node);
907 match_arguments(&am, block, op1, op2, NULL, flags);
909 dbgi = get_irn_dbg_info(node);
910 new_block = be_transform_node(block);
911 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
912 am.new_op1, am.new_op2, get_fpcw());
913 set_am_attributes(new_node, &am);
915 attr = get_ia32_x87_attr(new_node);
916 attr->attr.data.ins_permuted = am.ins_permuted;
918 SET_IA32_ORIG_NODE(new_node, node);
920 new_node = fix_mem_proj(new_node, &am);
926 * Construct a shift/rotate binary operation, sets AM and immediate if required.
928 * @param op1 The first operand
929 * @param op2 The second operand
930 * @param func The node constructor function
931 * @return The constructed ia32 node.
933 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
934 construct_shift_func *func,
938 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
940 assert(! mode_is_float(get_irn_mode(node)));
941 assert(flags & match_immediate);
942 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
944 if (flags & match_mode_neutral) {
945 op1 = ia32_skip_downconv(op1);
946 new_op1 = be_transform_node(op1);
947 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
948 new_op1 = create_upconv(op1, node);
950 new_op1 = be_transform_node(op1);
953 /* the shift amount can be any mode that is bigger than 5 bits, since all
954 * other bits are ignored anyway */
955 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
956 ir_node *const op = get_Conv_op(op2);
957 if (mode_is_float(get_irn_mode(op)))
960 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
962 new_op2 = create_immediate_or_transform(op2, 0);
964 dbgi = get_irn_dbg_info(node);
965 block = get_nodes_block(node);
966 new_block = be_transform_node(block);
967 new_node = func(dbgi, new_block, new_op1, new_op2);
968 SET_IA32_ORIG_NODE(new_node, node);
970 /* lowered shift instruction may have a dependency operand, handle it here */
971 if (get_irn_arity(node) == 3) {
972 /* we have a dependency */
973 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
974 add_irn_dep(new_node, new_dep);
982 * Construct a standard unary operation, set AM and immediate if required.
984 * @param op The operand
985 * @param func The node constructor function
986 * @return The constructed ia32 node.
988 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
992 ir_node *block, *new_block, *new_op, *new_node;
994 assert(flags == 0 || flags == match_mode_neutral);
995 if (flags & match_mode_neutral) {
996 op = ia32_skip_downconv(op);
999 new_op = be_transform_node(op);
1000 dbgi = get_irn_dbg_info(node);
1001 block = get_nodes_block(node);
1002 new_block = be_transform_node(block);
1003 new_node = func(dbgi, new_block, new_op);
1005 SET_IA32_ORIG_NODE(new_node, node);
1010 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1011 ia32_address_t *addr)
1013 ir_node *base, *index, *res;
1017 base = ia32_new_NoReg_gp(env_cg);
1019 base = be_transform_node(base);
1022 index = addr->index;
1023 if (index == NULL) {
1024 index = ia32_new_NoReg_gp(env_cg);
1026 index = be_transform_node(index);
1029 res = new_bd_ia32_Lea(dbgi, block, base, index);
1030 set_address(res, addr);
1036 * Returns non-zero if a given address mode has a symbolic or
1037 * numerical offset != 0.
1039 static int am_has_immediates(const ia32_address_t *addr)
1041 return addr->offset != 0 || addr->symconst_ent != NULL
1042 || addr->frame_entity || addr->use_frame;
1046 * Creates an ia32 Add.
1048 * @return the created ia32 Add node
1050 static ir_node *gen_Add(ir_node *node)
1052 ir_mode *mode = get_irn_mode(node);
1053 ir_node *op1 = get_Add_left(node);
1054 ir_node *op2 = get_Add_right(node);
1056 ir_node *block, *new_block, *new_node, *add_immediate_op;
1057 ia32_address_t addr;
1058 ia32_address_mode_t am;
1060 if (mode_is_float(mode)) {
1061 if (ia32_cg_config.use_sse2)
1062 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1063 match_commutative | match_am);
1065 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1068 ia32_mark_non_am(node);
1070 op2 = ia32_skip_downconv(op2);
1071 op1 = ia32_skip_downconv(op1);
1075 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1076 * 1. Add with immediate -> Lea
1077 * 2. Add with possible source address mode -> Add
1078 * 3. Otherwise -> Lea
1080 memset(&addr, 0, sizeof(addr));
1081 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1082 add_immediate_op = NULL;
1084 dbgi = get_irn_dbg_info(node);
1085 block = get_nodes_block(node);
1086 new_block = be_transform_node(block);
1089 if (addr.base == NULL && addr.index == NULL) {
1090 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1091 addr.symconst_sign, addr.offset);
1092 be_dep_on_frame(new_node);
1093 SET_IA32_ORIG_NODE(new_node, node);
1096 /* add with immediate? */
1097 if (addr.index == NULL) {
1098 add_immediate_op = addr.base;
1099 } else if (addr.base == NULL && addr.scale == 0) {
1100 add_immediate_op = addr.index;
1103 if (add_immediate_op != NULL) {
1104 if (!am_has_immediates(&addr)) {
1105 #ifdef DEBUG_libfirm
1106 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1109 return be_transform_node(add_immediate_op);
1112 new_node = create_lea_from_address(dbgi, new_block, &addr);
1113 SET_IA32_ORIG_NODE(new_node, node);
1117 /* test if we can use source address mode */
1118 match_arguments(&am, block, op1, op2, NULL, match_commutative
1119 | match_mode_neutral | match_am | match_immediate | match_try_am);
1121 /* construct an Add with source address mode */
1122 if (am.op_type == ia32_AddrModeS) {
1123 ia32_address_t *am_addr = &am.addr;
1124 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1125 am_addr->index, am_addr->mem, am.new_op1,
1127 set_am_attributes(new_node, &am);
1128 SET_IA32_ORIG_NODE(new_node, node);
1130 new_node = fix_mem_proj(new_node, &am);
1135 /* otherwise construct a lea */
1136 new_node = create_lea_from_address(dbgi, new_block, &addr);
1137 SET_IA32_ORIG_NODE(new_node, node);
1142 * Creates an ia32 Mul.
1144 * @return the created ia32 Mul node
1146 static ir_node *gen_Mul(ir_node *node)
1148 ir_node *op1 = get_Mul_left(node);
1149 ir_node *op2 = get_Mul_right(node);
1150 ir_mode *mode = get_irn_mode(node);
1152 if (mode_is_float(mode)) {
1153 if (ia32_cg_config.use_sse2)
1154 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1155 match_commutative | match_am);
1157 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1159 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1160 match_commutative | match_am | match_mode_neutral |
1161 match_immediate | match_am_and_immediates);
1165 * Creates an ia32 Mulh.
1166 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1167 * this result while Mul returns the lower 32 bit.
1169 * @return the created ia32 Mulh node
1171 static ir_node *gen_Mulh(ir_node *node)
1173 ir_node *block = get_nodes_block(node);
1174 ir_node *new_block = be_transform_node(block);
1175 dbg_info *dbgi = get_irn_dbg_info(node);
1176 ir_node *op1 = get_Mulh_left(node);
1177 ir_node *op2 = get_Mulh_right(node);
1178 ir_mode *mode = get_irn_mode(node);
1180 ir_node *proj_res_high;
1182 if (mode_is_signed(mode)) {
1183 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1184 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1185 mode_Iu, pn_ia32_IMul1OP_res_high);
1187 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1188 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1189 mode_Iu, pn_ia32_Mul_res_high);
1191 return proj_res_high;
1195 * Creates an ia32 And.
1197 * @return The created ia32 And node
1199 static ir_node *gen_And(ir_node *node)
1201 ir_node *op1 = get_And_left(node);
1202 ir_node *op2 = get_And_right(node);
1203 assert(! mode_is_float(get_irn_mode(node)));
1205 /* is it a zero extension? */
1206 if (is_Const(op2)) {
1207 tarval *tv = get_Const_tarval(op2);
1208 long v = get_tarval_long(tv);
1210 if (v == 0xFF || v == 0xFFFF) {
1211 dbg_info *dbgi = get_irn_dbg_info(node);
1212 ir_node *block = get_nodes_block(node);
1219 assert(v == 0xFFFF);
1222 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1227 return gen_binop(node, op1, op2, new_bd_ia32_And,
1228 match_commutative | match_mode_neutral | match_am | match_immediate);
1234 * Creates an ia32 Or.
1236 * @return The created ia32 Or node
1238 static ir_node *gen_Or(ir_node *node)
1240 ir_node *op1 = get_Or_left(node);
1241 ir_node *op2 = get_Or_right(node);
1243 assert (! mode_is_float(get_irn_mode(node)));
1244 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1245 | match_mode_neutral | match_am | match_immediate);
1251 * Creates an ia32 Eor.
1253 * @return The created ia32 Eor node
1255 static ir_node *gen_Eor(ir_node *node)
1257 ir_node *op1 = get_Eor_left(node);
1258 ir_node *op2 = get_Eor_right(node);
1260 assert(! mode_is_float(get_irn_mode(node)));
1261 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1262 | match_mode_neutral | match_am | match_immediate);
1267 * Creates an ia32 Sub.
1269 * @return The created ia32 Sub node
1271 static ir_node *gen_Sub(ir_node *node)
1273 ir_node *op1 = get_Sub_left(node);
1274 ir_node *op2 = get_Sub_right(node);
1275 ir_mode *mode = get_irn_mode(node);
1277 if (mode_is_float(mode)) {
1278 if (ia32_cg_config.use_sse2)
1279 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1281 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1284 if (is_Const(op2)) {
1285 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1289 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1290 | match_am | match_immediate);
1293 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1294 ir_node *const src_val,
1295 ir_node *const src_mem,
1296 ir_node *const am_mem)
1298 if (is_NoMem(am_mem)) {
1299 return be_transform_node(src_mem);
1300 } else if (is_Proj(src_val) &&
1302 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1303 /* avoid memory loop */
1305 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1306 ir_node *const ptr_pred = get_Proj_pred(src_val);
1307 int const arity = get_Sync_n_preds(src_mem);
1312 NEW_ARR_A(ir_node*, ins, arity + 1);
1314 /* NOTE: This sometimes produces dead-code because the old sync in
1315 * src_mem might not be used anymore, we should detect this case
1316 * and kill the sync... */
1317 for (i = arity - 1; i >= 0; --i) {
1318 ir_node *const pred = get_Sync_pred(src_mem, i);
1320 /* avoid memory loop */
1321 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1324 ins[n++] = be_transform_node(pred);
1329 return new_r_Sync(irg, block, n, ins);
1333 ins[0] = be_transform_node(src_mem);
1335 return new_r_Sync(irg, block, 2, ins);
1339 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1340 ir_node *val, const ir_node *orig)
1345 if (ia32_cg_config.use_short_sex_eax) {
1346 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1347 be_dep_on_frame(pval);
1348 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1350 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1351 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1353 SET_IA32_ORIG_NODE(res, orig);
1358 * Generates an ia32 DivMod with additional infrastructure for the
1359 * register allocator if needed.
1361 static ir_node *create_Div(ir_node *node)
1363 dbg_info *dbgi = get_irn_dbg_info(node);
1364 ir_node *block = get_nodes_block(node);
1365 ir_node *new_block = be_transform_node(block);
1372 ir_node *sign_extension;
1373 ia32_address_mode_t am;
1374 ia32_address_t *addr = &am.addr;
1376 /* the upper bits have random contents for smaller modes */
1377 switch (get_irn_opcode(node)) {
1379 op1 = get_Div_left(node);
1380 op2 = get_Div_right(node);
1381 mem = get_Div_mem(node);
1382 mode = get_Div_resmode(node);
1385 op1 = get_Mod_left(node);
1386 op2 = get_Mod_right(node);
1387 mem = get_Mod_mem(node);
1388 mode = get_Mod_resmode(node);
1391 op1 = get_DivMod_left(node);
1392 op2 = get_DivMod_right(node);
1393 mem = get_DivMod_mem(node);
1394 mode = get_DivMod_resmode(node);
1397 panic("invalid divmod node %+F", node);
1400 match_arguments(&am, block, op1, op2, NULL, match_am);
1402 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1403 is the memory of the consumed address. We can have only the second op as address
1404 in Div nodes, so check only op2. */
1405 new_mem = transform_AM_mem(current_ir_graph, block, op2, mem, addr->mem);
1407 if (mode_is_signed(mode)) {
1408 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1409 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1410 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1412 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0);
1413 be_dep_on_frame(sign_extension);
1415 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1416 addr->index, new_mem, am.new_op2,
1417 am.new_op1, sign_extension);
1420 set_irn_pinned(new_node, get_irn_pinned(node));
1422 set_am_attributes(new_node, &am);
1423 SET_IA32_ORIG_NODE(new_node, node);
1425 new_node = fix_mem_proj(new_node, &am);
1431 static ir_node *gen_Mod(ir_node *node)
1433 return create_Div(node);
1436 static ir_node *gen_Div(ir_node *node)
1438 return create_Div(node);
1441 static ir_node *gen_DivMod(ir_node *node)
1443 return create_Div(node);
1449 * Creates an ia32 floating Div.
1451 * @return The created ia32 xDiv node
1453 static ir_node *gen_Quot(ir_node *node)
1455 ir_node *op1 = get_Quot_left(node);
1456 ir_node *op2 = get_Quot_right(node);
1458 if (ia32_cg_config.use_sse2) {
1459 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1461 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1467 * Creates an ia32 Shl.
1469 * @return The created ia32 Shl node
1471 static ir_node *gen_Shl(ir_node *node)
1473 ir_node *left = get_Shl_left(node);
1474 ir_node *right = get_Shl_right(node);
1476 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1477 match_mode_neutral | match_immediate);
1481 * Creates an ia32 Shr.
1483 * @return The created ia32 Shr node
1485 static ir_node *gen_Shr(ir_node *node)
1487 ir_node *left = get_Shr_left(node);
1488 ir_node *right = get_Shr_right(node);
1490 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1496 * Creates an ia32 Sar.
1498 * @return The created ia32 Shrs node
1500 static ir_node *gen_Shrs(ir_node *node)
1502 ir_node *left = get_Shrs_left(node);
1503 ir_node *right = get_Shrs_right(node);
1504 ir_mode *mode = get_irn_mode(node);
1506 if (is_Const(right) && mode == mode_Is) {
1507 tarval *tv = get_Const_tarval(right);
1508 long val = get_tarval_long(tv);
1510 /* this is a sign extension */
1511 dbg_info *dbgi = get_irn_dbg_info(node);
1512 ir_node *block = be_transform_node(get_nodes_block(node));
1513 ir_node *new_op = be_transform_node(left);
1515 return create_sex_32_64(dbgi, block, new_op, node);
1519 /* 8 or 16 bit sign extension? */
1520 if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1521 ir_node *shl_left = get_Shl_left(left);
1522 ir_node *shl_right = get_Shl_right(left);
1523 if (is_Const(shl_right)) {
1524 tarval *tv1 = get_Const_tarval(right);
1525 tarval *tv2 = get_Const_tarval(shl_right);
1526 if (tv1 == tv2 && tarval_is_long(tv1)) {
1527 long val = get_tarval_long(tv1);
1528 if (val == 16 || val == 24) {
1529 dbg_info *dbgi = get_irn_dbg_info(node);
1530 ir_node *block = get_nodes_block(node);
1540 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1549 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1555 * Creates an ia32 Rol.
1557 * @param op1 The first operator
1558 * @param op2 The second operator
1559 * @return The created ia32 RotL node
1561 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1563 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1569 * Creates an ia32 Ror.
1570 * NOTE: There is no RotR with immediate because this would always be a RotL
1571 * "imm-mode_size_bits" which can be pre-calculated.
1573 * @param op1 The first operator
1574 * @param op2 The second operator
1575 * @return The created ia32 RotR node
1577 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1579 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1585 * Creates an ia32 RotR or RotL (depending on the found pattern).
1587 * @return The created ia32 RotL or RotR node
1589 static ir_node *gen_Rotl(ir_node *node)
1591 ir_node *rotate = NULL;
1592 ir_node *op1 = get_Rotl_left(node);
1593 ir_node *op2 = get_Rotl_right(node);
1595 /* Firm has only RotL, so we are looking for a right (op2)
1596 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1597 that means we can create a RotR instead of an Add and a RotL */
1601 ir_node *left = get_Add_left(add);
1602 ir_node *right = get_Add_right(add);
1603 if (is_Const(right)) {
1604 tarval *tv = get_Const_tarval(right);
1605 ir_mode *mode = get_irn_mode(node);
1606 long bits = get_mode_size_bits(mode);
1608 if (is_Minus(left) &&
1609 tarval_is_long(tv) &&
1610 get_tarval_long(tv) == bits &&
1613 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1614 rotate = gen_Ror(node, op1, get_Minus_op(left));
1619 if (rotate == NULL) {
1620 rotate = gen_Rol(node, op1, op2);
1629 * Transforms a Minus node.
1631 * @return The created ia32 Minus node
1633 static ir_node *gen_Minus(ir_node *node)
1635 ir_node *op = get_Minus_op(node);
1636 ir_node *block = be_transform_node(get_nodes_block(node));
1637 dbg_info *dbgi = get_irn_dbg_info(node);
1638 ir_mode *mode = get_irn_mode(node);
1643 if (mode_is_float(mode)) {
1644 ir_node *new_op = be_transform_node(op);
1645 if (ia32_cg_config.use_sse2) {
1646 /* TODO: non-optimal... if we have many xXors, then we should
1647 * rather create a load for the const and use that instead of
1648 * several AM nodes... */
1649 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1650 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1651 ir_node *nomem = new_NoMem();
1653 new_node = new_bd_ia32_xXor(dbgi, block, noreg_gp, noreg_gp,
1654 nomem, new_op, noreg_xmm);
1656 size = get_mode_size_bits(mode);
1657 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1659 set_ia32_am_sc(new_node, ent);
1660 set_ia32_op_type(new_node, ia32_AddrModeS);
1661 set_ia32_ls_mode(new_node, mode);
1663 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1666 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1669 SET_IA32_ORIG_NODE(new_node, node);
1675 * Transforms a Not node.
1677 * @return The created ia32 Not node
1679 static ir_node *gen_Not(ir_node *node)
1681 ir_node *op = get_Not_op(node);
1683 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1684 assert (! mode_is_float(get_irn_mode(node)));
1686 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1692 * Transforms an Abs node.
1694 * @return The created ia32 Abs node
1696 static ir_node *gen_Abs(ir_node *node)
1698 ir_node *block = get_nodes_block(node);
1699 ir_node *new_block = be_transform_node(block);
1700 ir_node *op = get_Abs_op(node);
1701 dbg_info *dbgi = get_irn_dbg_info(node);
1702 ir_mode *mode = get_irn_mode(node);
1703 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1704 ir_node *nomem = new_NoMem();
1710 if (mode_is_float(mode)) {
1711 new_op = be_transform_node(op);
1713 if (ia32_cg_config.use_sse2) {
1714 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1715 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_gp, noreg_gp,
1716 nomem, new_op, noreg_fp);
1718 size = get_mode_size_bits(mode);
1719 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1721 set_ia32_am_sc(new_node, ent);
1723 SET_IA32_ORIG_NODE(new_node, node);
1725 set_ia32_op_type(new_node, ia32_AddrModeS);
1726 set_ia32_ls_mode(new_node, mode);
1728 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1729 SET_IA32_ORIG_NODE(new_node, node);
1732 ir_node *xor, *sign_extension;
1734 if (get_mode_size_bits(mode) == 32) {
1735 new_op = be_transform_node(op);
1737 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1740 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1742 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_gp, noreg_gp,
1743 nomem, new_op, sign_extension);
1744 SET_IA32_ORIG_NODE(xor, node);
1746 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_gp, noreg_gp,
1747 nomem, xor, sign_extension);
1748 SET_IA32_ORIG_NODE(new_node, node);
1755 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1757 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1759 dbg_info *dbgi = get_irn_dbg_info(cmp);
1760 ir_node *block = get_nodes_block(cmp);
1761 ir_node *new_block = be_transform_node(block);
1762 ir_node *op1 = be_transform_node(x);
1763 ir_node *op2 = be_transform_node(n);
1765 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1769 * Transform a node returning a "flag" result.
1771 * @param node the node to transform
1772 * @param pnc_out the compare mode to use
1774 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1783 /* we have a Cmp as input */
1784 if (is_Proj(node)) {
1785 ir_node *pred = get_Proj_pred(node);
1787 pn_Cmp pnc = get_Proj_proj(node);
1788 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1789 ir_node *l = get_Cmp_left(pred);
1790 ir_node *r = get_Cmp_right(pred);
1792 ir_node *la = get_And_left(l);
1793 ir_node *ra = get_And_right(l);
1795 ir_node *c = get_Shl_left(la);
1796 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1797 /* (1 << n) & ra) */
1798 ir_node *n = get_Shl_right(la);
1799 flags = gen_bt(pred, ra, n);
1800 /* we must generate a Jc/Jnc jump */
1801 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1804 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1809 ir_node *c = get_Shl_left(ra);
1810 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1811 /* la & (1 << n)) */
1812 ir_node *n = get_Shl_right(ra);
1813 flags = gen_bt(pred, la, n);
1814 /* we must generate a Jc/Jnc jump */
1815 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1818 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1824 flags = be_transform_node(pred);
1830 /* a mode_b value, we have to compare it against 0 */
1831 dbgi = get_irn_dbg_info(node);
1832 new_block = be_transform_node(get_nodes_block(node));
1833 new_op = be_transform_node(node);
1834 noreg = ia32_new_NoReg_gp(env_cg);
1835 nomem = new_NoMem();
1836 flags = new_bd_ia32_Test(dbgi, new_block, noreg, noreg, nomem, new_op,
1837 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1838 *pnc_out = pn_Cmp_Lg;
1843 * Transforms a Load.
1845 * @return the created ia32 Load node
1847 static ir_node *gen_Load(ir_node *node)
1849 ir_node *old_block = get_nodes_block(node);
1850 ir_node *block = be_transform_node(old_block);
1851 ir_node *ptr = get_Load_ptr(node);
1852 ir_node *mem = get_Load_mem(node);
1853 ir_node *new_mem = be_transform_node(mem);
1856 dbg_info *dbgi = get_irn_dbg_info(node);
1857 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1858 ir_mode *mode = get_Load_mode(node);
1861 ia32_address_t addr;
1863 /* construct load address */
1864 memset(&addr, 0, sizeof(addr));
1865 ia32_create_address_mode(&addr, ptr, 0);
1872 base = be_transform_node(base);
1875 if (index == NULL) {
1878 index = be_transform_node(index);
1881 if (mode_is_float(mode)) {
1882 if (ia32_cg_config.use_sse2) {
1883 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1885 res_mode = mode_xmm;
1887 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1889 res_mode = mode_vfp;
1892 assert(mode != mode_b);
1894 /* create a conv node with address mode for smaller modes */
1895 if (get_mode_size_bits(mode) < 32) {
1896 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1897 new_mem, noreg, mode);
1899 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1904 set_irn_pinned(new_node, get_irn_pinned(node));
1905 set_ia32_op_type(new_node, ia32_AddrModeS);
1906 set_ia32_ls_mode(new_node, mode);
1907 set_address(new_node, &addr);
1909 if (get_irn_pinned(node) == op_pin_state_floats) {
1910 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1911 && pn_ia32_vfld_res == pn_ia32_Load_res
1912 && pn_ia32_Load_res == pn_ia32_res);
1913 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1916 SET_IA32_ORIG_NODE(new_node, node);
1918 be_dep_on_frame(new_node);
1922 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1923 ir_node *ptr, ir_node *other)
1930 /* we only use address mode if we're the only user of the load */
1931 if (get_irn_n_edges(node) > 1)
1934 load = get_Proj_pred(node);
1937 if (get_nodes_block(load) != block)
1940 /* store should have the same pointer as the load */
1941 if (get_Load_ptr(load) != ptr)
1944 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1945 if (other != NULL &&
1946 get_nodes_block(other) == block &&
1947 heights_reachable_in_block(heights, other, load)) {
1951 if (prevents_AM(block, load, mem))
1953 /* Store should be attached to the load via mem */
1954 assert(heights_reachable_in_block(heights, mem, load));
1959 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1960 ir_node *mem, ir_node *ptr, ir_mode *mode,
1961 construct_binop_dest_func *func,
1962 construct_binop_dest_func *func8bit,
1963 match_flags_t flags)
1965 ir_node *src_block = get_nodes_block(node);
1967 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1974 ia32_address_mode_t am;
1975 ia32_address_t *addr = &am.addr;
1976 memset(&am, 0, sizeof(am));
1978 assert(flags & match_immediate); /* there is no destam node without... */
1979 commutative = (flags & match_commutative) != 0;
1981 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1982 build_address(&am, op1, ia32_create_am_double_use);
1983 new_op = create_immediate_or_transform(op2, 0);
1984 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1985 build_address(&am, op2, ia32_create_am_double_use);
1986 new_op = create_immediate_or_transform(op1, 0);
1991 if (addr->base == NULL)
1992 addr->base = noreg_gp;
1993 if (addr->index == NULL)
1994 addr->index = noreg_gp;
1995 if (addr->mem == NULL)
1996 addr->mem = new_NoMem();
1998 dbgi = get_irn_dbg_info(node);
1999 block = be_transform_node(src_block);
2000 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2002 if (get_mode_size_bits(mode) == 8) {
2003 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2005 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2007 set_address(new_node, addr);
2008 set_ia32_op_type(new_node, ia32_AddrModeD);
2009 set_ia32_ls_mode(new_node, mode);
2010 SET_IA32_ORIG_NODE(new_node, node);
2012 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2013 mem_proj = be_transform_node(am.mem_proj);
2014 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2019 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2020 ir_node *ptr, ir_mode *mode,
2021 construct_unop_dest_func *func)
2023 ir_node *src_block = get_nodes_block(node);
2029 ia32_address_mode_t am;
2030 ia32_address_t *addr = &am.addr;
2032 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2035 memset(&am, 0, sizeof(am));
2036 build_address(&am, op, ia32_create_am_double_use);
2038 dbgi = get_irn_dbg_info(node);
2039 block = be_transform_node(src_block);
2040 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2041 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2042 set_address(new_node, addr);
2043 set_ia32_op_type(new_node, ia32_AddrModeD);
2044 set_ia32_ls_mode(new_node, mode);
2045 SET_IA32_ORIG_NODE(new_node, node);
2047 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2048 mem_proj = be_transform_node(am.mem_proj);
2049 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2054 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2056 ir_mode *mode = get_irn_mode(node);
2057 ir_node *mux_true = get_Mux_true(node);
2058 ir_node *mux_false = get_Mux_false(node);
2068 ia32_address_t addr;
2070 if (get_mode_size_bits(mode) != 8)
2073 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2075 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2081 build_address_ptr(&addr, ptr, mem);
2083 dbgi = get_irn_dbg_info(node);
2084 block = get_nodes_block(node);
2085 new_block = be_transform_node(block);
2086 cond = get_Mux_sel(node);
2087 flags = get_flags_node(cond, &pnc);
2088 new_mem = be_transform_node(mem);
2089 new_node = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2090 addr.index, addr.mem, flags, pnc, negated);
2091 set_address(new_node, &addr);
2092 set_ia32_op_type(new_node, ia32_AddrModeD);
2093 set_ia32_ls_mode(new_node, mode);
2094 SET_IA32_ORIG_NODE(new_node, node);
2099 static ir_node *try_create_dest_am(ir_node *node)
2101 ir_node *val = get_Store_value(node);
2102 ir_node *mem = get_Store_mem(node);
2103 ir_node *ptr = get_Store_ptr(node);
2104 ir_mode *mode = get_irn_mode(val);
2105 unsigned bits = get_mode_size_bits(mode);
2110 /* handle only GP modes for now... */
2111 if (!ia32_mode_needs_gp_reg(mode))
2115 /* store must be the only user of the val node */
2116 if (get_irn_n_edges(val) > 1)
2118 /* skip pointless convs */
2120 ir_node *conv_op = get_Conv_op(val);
2121 ir_mode *pred_mode = get_irn_mode(conv_op);
2122 if (!ia32_mode_needs_gp_reg(pred_mode))
2124 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2132 /* value must be in the same block */
2133 if (get_nodes_block(node) != get_nodes_block(val))
2136 switch (get_irn_opcode(val)) {
2138 op1 = get_Add_left(val);
2139 op2 = get_Add_right(val);
2140 if (ia32_cg_config.use_incdec) {
2141 if (is_Const_1(op2)) {
2142 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2144 } else if (is_Const_Minus_1(op2)) {
2145 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2149 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2150 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2151 match_commutative | match_immediate);
2154 op1 = get_Sub_left(val);
2155 op2 = get_Sub_right(val);
2156 if (is_Const(op2)) {
2157 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2159 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2160 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2164 op1 = get_And_left(val);
2165 op2 = get_And_right(val);
2166 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2167 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2168 match_commutative | match_immediate);
2171 op1 = get_Or_left(val);
2172 op2 = get_Or_right(val);
2173 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2174 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2175 match_commutative | match_immediate);
2178 op1 = get_Eor_left(val);
2179 op2 = get_Eor_right(val);
2180 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2181 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2182 match_commutative | match_immediate);
2185 op1 = get_Shl_left(val);
2186 op2 = get_Shl_right(val);
2187 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2188 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2192 op1 = get_Shr_left(val);
2193 op2 = get_Shr_right(val);
2194 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2195 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2199 op1 = get_Shrs_left(val);
2200 op2 = get_Shrs_right(val);
2201 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2202 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2206 op1 = get_Rotl_left(val);
2207 op2 = get_Rotl_right(val);
2208 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2209 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2212 /* TODO: match ROR patterns... */
2214 new_node = try_create_SetMem(val, ptr, mem);
2217 op1 = get_Minus_op(val);
2218 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2221 /* should be lowered already */
2222 assert(mode != mode_b);
2223 op1 = get_Not_op(val);
2224 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2230 if (new_node != NULL) {
2231 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2232 get_irn_pinned(node) == op_pin_state_pinned) {
2233 set_irn_pinned(new_node, op_pin_state_pinned);
2240 static bool possible_int_mode_for_fp(ir_mode *mode)
2244 if (!mode_is_signed(mode))
2246 size = get_mode_size_bits(mode);
2247 if (size != 16 && size != 32)
2252 static int is_float_to_int_conv(const ir_node *node)
2254 ir_mode *mode = get_irn_mode(node);
2258 if (!possible_int_mode_for_fp(mode))
2263 conv_op = get_Conv_op(node);
2264 conv_mode = get_irn_mode(conv_op);
2266 if (!mode_is_float(conv_mode))
2273 * Transform a Store(floatConst) into a sequence of
2276 * @return the created ia32 Store node
2278 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2280 ir_mode *mode = get_irn_mode(cns);
2281 unsigned size = get_mode_size_bytes(mode);
2282 tarval *tv = get_Const_tarval(cns);
2283 ir_node *block = get_nodes_block(node);
2284 ir_node *new_block = be_transform_node(block);
2285 ir_node *ptr = get_Store_ptr(node);
2286 ir_node *mem = get_Store_mem(node);
2287 dbg_info *dbgi = get_irn_dbg_info(node);
2291 ia32_address_t addr;
2293 assert(size % 4 == 0);
2296 build_address_ptr(&addr, ptr, mem);
2300 get_tarval_sub_bits(tv, ofs) |
2301 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2302 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2303 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2304 ir_node *imm = create_Immediate(NULL, 0, val);
2306 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2307 addr.index, addr.mem, imm);
2309 set_irn_pinned(new_node, get_irn_pinned(node));
2310 set_ia32_op_type(new_node, ia32_AddrModeD);
2311 set_ia32_ls_mode(new_node, mode_Iu);
2312 set_address(new_node, &addr);
2313 SET_IA32_ORIG_NODE(new_node, node);
2316 ins[i++] = new_node;
2321 } while (size != 0);
2324 return new_rd_Sync(dbgi, current_ir_graph, new_block, i, ins);
2331 * Generate a vfist or vfisttp instruction.
2333 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2334 ir_node *mem, ir_node *val, ir_node **fist)
2338 if (ia32_cg_config.use_fisttp) {
2339 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2340 if other users exists */
2341 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2342 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2343 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2344 be_new_Keep(reg_class, irg, block, 1, &value);
2346 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2349 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2352 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2358 * Transforms a general (no special case) Store.
2360 * @return the created ia32 Store node
2362 static ir_node *gen_general_Store(ir_node *node)
2364 ir_node *val = get_Store_value(node);
2365 ir_mode *mode = get_irn_mode(val);
2366 ir_node *block = get_nodes_block(node);
2367 ir_node *new_block = be_transform_node(block);
2368 ir_node *ptr = get_Store_ptr(node);
2369 ir_node *mem = get_Store_mem(node);
2370 dbg_info *dbgi = get_irn_dbg_info(node);
2371 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2372 ir_node *new_val, *new_node, *store;
2373 ia32_address_t addr;
2375 /* check for destination address mode */
2376 new_node = try_create_dest_am(node);
2377 if (new_node != NULL)
2380 /* construct store address */
2381 memset(&addr, 0, sizeof(addr));
2382 ia32_create_address_mode(&addr, ptr, 0);
2384 if (addr.base == NULL) {
2387 addr.base = be_transform_node(addr.base);
2390 if (addr.index == NULL) {
2393 addr.index = be_transform_node(addr.index);
2395 addr.mem = be_transform_node(mem);
2397 if (mode_is_float(mode)) {
2398 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2400 while (is_Conv(val) && mode == get_irn_mode(val)) {
2401 ir_node *op = get_Conv_op(val);
2402 if (!mode_is_float(get_irn_mode(op)))
2406 new_val = be_transform_node(val);
2407 if (ia32_cg_config.use_sse2) {
2408 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2409 addr.index, addr.mem, new_val);
2411 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2412 addr.index, addr.mem, new_val, mode);
2415 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2416 val = get_Conv_op(val);
2418 /* TODO: is this optimisation still necessary at all (middleend)? */
2419 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2420 while (is_Conv(val)) {
2421 ir_node *op = get_Conv_op(val);
2422 if (!mode_is_float(get_irn_mode(op)))
2424 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2428 new_val = be_transform_node(val);
2429 new_node = gen_vfist(dbgi, current_ir_graph, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2431 new_val = create_immediate_or_transform(val, 0);
2432 assert(mode != mode_b);
2434 if (get_mode_size_bits(mode) == 8) {
2435 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2436 addr.index, addr.mem, new_val);
2438 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2439 addr.index, addr.mem, new_val);
2444 set_irn_pinned(store, get_irn_pinned(node));
2445 set_ia32_op_type(store, ia32_AddrModeD);
2446 set_ia32_ls_mode(store, mode);
2448 set_address(store, &addr);
2449 SET_IA32_ORIG_NODE(store, node);
2455 * Transforms a Store.
2457 * @return the created ia32 Store node
2459 static ir_node *gen_Store(ir_node *node)
2461 ir_node *val = get_Store_value(node);
2462 ir_mode *mode = get_irn_mode(val);
2464 if (mode_is_float(mode) && is_Const(val)) {
2465 /* We can transform every floating const store
2466 into a sequence of integer stores.
2467 If the constant is already in a register,
2468 it would be better to use it, but we don't
2469 have this information here. */
2470 return gen_float_const_Store(node, val);
2472 return gen_general_Store(node);
2476 * Transforms a Switch.
2478 * @return the created ia32 SwitchJmp node
2480 static ir_node *create_Switch(ir_node *node)
2482 dbg_info *dbgi = get_irn_dbg_info(node);
2483 ir_node *block = be_transform_node(get_nodes_block(node));
2484 ir_node *sel = get_Cond_selector(node);
2485 ir_node *new_sel = be_transform_node(sel);
2486 int switch_min = INT_MAX;
2487 int switch_max = INT_MIN;
2488 long default_pn = get_Cond_defaultProj(node);
2490 const ir_edge_t *edge;
2492 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2494 /* determine the smallest switch case value */
2495 foreach_out_edge(node, edge) {
2496 ir_node *proj = get_edge_src_irn(edge);
2497 long pn = get_Proj_proj(proj);
2498 if (pn == default_pn)
2501 if (pn < switch_min)
2503 if (pn > switch_max)
2507 if ((unsigned) (switch_max - switch_min) > 256000) {
2508 panic("Size of switch %+F bigger than 256000", node);
2511 if (switch_min != 0) {
2512 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2514 /* if smallest switch case is not 0 we need an additional sub */
2515 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg);
2516 add_ia32_am_offs_int(new_sel, -switch_min);
2517 set_ia32_op_type(new_sel, ia32_AddrModeS);
2519 SET_IA32_ORIG_NODE(new_sel, node);
2522 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2523 SET_IA32_ORIG_NODE(new_node, node);
2529 * Transform a Cond node.
2531 static ir_node *gen_Cond(ir_node *node)
2533 ir_node *block = get_nodes_block(node);
2534 ir_node *new_block = be_transform_node(block);
2535 dbg_info *dbgi = get_irn_dbg_info(node);
2536 ir_node *sel = get_Cond_selector(node);
2537 ir_mode *sel_mode = get_irn_mode(sel);
2538 ir_node *flags = NULL;
2542 if (sel_mode != mode_b) {
2543 return create_Switch(node);
2546 /* we get flags from a Cmp */
2547 flags = get_flags_node(sel, &pnc);
2549 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2550 SET_IA32_ORIG_NODE(new_node, node);
2555 static ir_node *gen_be_Copy(ir_node *node)
2557 ir_node *new_node = be_duplicate_node(node);
2558 ir_mode *mode = get_irn_mode(new_node);
2560 if (ia32_mode_needs_gp_reg(mode)) {
2561 set_irn_mode(new_node, mode_Iu);
2567 static ir_node *create_Fucom(ir_node *node)
2569 dbg_info *dbgi = get_irn_dbg_info(node);
2570 ir_node *block = get_nodes_block(node);
2571 ir_node *new_block = be_transform_node(block);
2572 ir_node *left = get_Cmp_left(node);
2573 ir_node *new_left = be_transform_node(left);
2574 ir_node *right = get_Cmp_right(node);
2578 if (ia32_cg_config.use_fucomi) {
2579 new_right = be_transform_node(right);
2580 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2582 set_ia32_commutative(new_node);
2583 SET_IA32_ORIG_NODE(new_node, node);
2585 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2586 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2588 new_right = be_transform_node(right);
2589 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2592 set_ia32_commutative(new_node);
2594 SET_IA32_ORIG_NODE(new_node, node);
2596 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2597 SET_IA32_ORIG_NODE(new_node, node);
2603 static ir_node *create_Ucomi(ir_node *node)
2605 dbg_info *dbgi = get_irn_dbg_info(node);
2606 ir_node *src_block = get_nodes_block(node);
2607 ir_node *new_block = be_transform_node(src_block);
2608 ir_node *left = get_Cmp_left(node);
2609 ir_node *right = get_Cmp_right(node);
2611 ia32_address_mode_t am;
2612 ia32_address_t *addr = &am.addr;
2614 match_arguments(&am, src_block, left, right, NULL,
2615 match_commutative | match_am);
2617 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2618 addr->mem, am.new_op1, am.new_op2,
2620 set_am_attributes(new_node, &am);
2622 SET_IA32_ORIG_NODE(new_node, node);
2624 new_node = fix_mem_proj(new_node, &am);
2630 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2631 * to fold an and into a test node
2633 static bool can_fold_test_and(ir_node *node)
2635 const ir_edge_t *edge;
2637 /** we can only have eq and lg projs */
2638 foreach_out_edge(node, edge) {
2639 ir_node *proj = get_edge_src_irn(edge);
2640 pn_Cmp pnc = get_Proj_proj(proj);
2641 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2649 * returns true if it is assured, that the upper bits of a node are "clean"
2650 * which means for a 16 or 8 bit value, that the upper bits in the register
2651 * are 0 for unsigned and a copy of the last significant bit for signed
2654 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2656 assert(ia32_mode_needs_gp_reg(mode));
2657 if (get_mode_size_bits(mode) >= 32)
2660 if (is_Proj(transformed_node))
2661 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2663 switch (get_ia32_irn_opcode(transformed_node)) {
2664 case iro_ia32_Conv_I2I:
2665 case iro_ia32_Conv_I2I8Bit: {
2666 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2667 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2669 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2676 if (mode_is_signed(mode)) {
2677 return false; /* TODO handle signed modes */
2679 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2680 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2681 const ia32_immediate_attr_t *attr
2682 = get_ia32_immediate_attr_const(right);
2683 if (attr->symconst == 0 &&
2684 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2688 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2692 /* TODO too conservative if shift amount is constant */
2693 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2696 if (!mode_is_signed(mode)) {
2698 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2699 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2701 /* TODO if one is known to be zero extended, then || is sufficient */
2706 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2707 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2709 case iro_ia32_Const:
2710 case iro_ia32_Immediate: {
2711 const ia32_immediate_attr_t *attr =
2712 get_ia32_immediate_attr_const(transformed_node);
2713 if (mode_is_signed(mode)) {
2714 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2715 return shifted == 0 || shifted == -1;
2717 unsigned long shifted = (unsigned long)attr->offset;
2718 shifted >>= get_mode_size_bits(mode);
2719 return shifted == 0;
2729 * Generate code for a Cmp.
2731 static ir_node *gen_Cmp(ir_node *node)
2733 dbg_info *dbgi = get_irn_dbg_info(node);
2734 ir_node *block = get_nodes_block(node);
2735 ir_node *new_block = be_transform_node(block);
2736 ir_node *left = get_Cmp_left(node);
2737 ir_node *right = get_Cmp_right(node);
2738 ir_mode *cmp_mode = get_irn_mode(left);
2740 ia32_address_mode_t am;
2741 ia32_address_t *addr = &am.addr;
2744 if (mode_is_float(cmp_mode)) {
2745 if (ia32_cg_config.use_sse2) {
2746 return create_Ucomi(node);
2748 return create_Fucom(node);
2752 assert(ia32_mode_needs_gp_reg(cmp_mode));
2754 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2755 cmp_unsigned = !mode_is_signed(cmp_mode);
2756 if (is_Const_0(right) &&
2758 get_irn_n_edges(left) == 1 &&
2759 can_fold_test_and(node)) {
2760 /* Test(and_left, and_right) */
2761 ir_node *and_left = get_And_left(left);
2762 ir_node *and_right = get_And_right(left);
2764 /* matze: code here used mode instead of cmd_mode, I think it is always
2765 * the same as cmp_mode, but I leave this here to see if this is really
2768 assert(get_irn_mode(and_left) == cmp_mode);
2770 match_arguments(&am, block, and_left, and_right, NULL,
2772 match_am | match_8bit_am | match_16bit_am |
2773 match_am_and_immediates | match_immediate);
2775 /* use 32bit compare mode if possible since the opcode is smaller */
2776 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2777 upper_bits_clean(am.new_op2, cmp_mode)) {
2778 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2781 if (get_mode_size_bits(cmp_mode) == 8) {
2782 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2783 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2786 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2787 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2790 /* Cmp(left, right) */
2791 match_arguments(&am, block, left, right, NULL,
2792 match_commutative | match_am | match_8bit_am |
2793 match_16bit_am | match_am_and_immediates |
2795 /* use 32bit compare mode if possible since the opcode is smaller */
2796 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2797 upper_bits_clean(am.new_op2, cmp_mode)) {
2798 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2801 if (get_mode_size_bits(cmp_mode) == 8) {
2802 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2803 addr->index, addr->mem, am.new_op1,
2804 am.new_op2, am.ins_permuted,
2807 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2808 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2811 set_am_attributes(new_node, &am);
2812 set_ia32_ls_mode(new_node, cmp_mode);
2814 SET_IA32_ORIG_NODE(new_node, node);
2816 new_node = fix_mem_proj(new_node, &am);
2821 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2824 dbg_info *dbgi = get_irn_dbg_info(node);
2825 ir_node *block = get_nodes_block(node);
2826 ir_node *new_block = be_transform_node(block);
2827 ir_node *val_true = get_Mux_true(node);
2828 ir_node *val_false = get_Mux_false(node);
2830 ia32_address_mode_t am;
2831 ia32_address_t *addr;
2833 assert(ia32_cg_config.use_cmov);
2834 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2838 match_arguments(&am, block, val_false, val_true, flags,
2839 match_commutative | match_am | match_16bit_am | match_mode_neutral);
2841 new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2842 addr->mem, am.new_op1, am.new_op2, new_flags,
2843 am.ins_permuted, pnc);
2844 set_am_attributes(new_node, &am);
2846 SET_IA32_ORIG_NODE(new_node, node);
2848 new_node = fix_mem_proj(new_node, &am);
2854 * Creates a ia32 Setcc instruction.
2856 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2857 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2860 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2861 ir_node *nomem = new_NoMem();
2862 ir_mode *mode = get_irn_mode(orig_node);
2865 new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2866 SET_IA32_ORIG_NODE(new_node, orig_node);
2868 /* we might need to conv the result up */
2869 if (get_mode_size_bits(mode) > 8) {
2870 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg, noreg,
2871 nomem, new_node, mode_Bu);
2872 SET_IA32_ORIG_NODE(new_node, orig_node);
2879 * Create instruction for an unsigned Difference or Zero.
2881 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2883 ir_graph *irg = current_ir_graph;
2884 ir_mode *mode = get_irn_mode(psi);
2885 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2888 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2889 match_mode_neutral | match_am | match_immediate | match_two_users);
2891 block = get_nodes_block(new_node);
2893 if (is_Proj(new_node)) {
2894 sub = get_Proj_pred(new_node);
2895 assert(is_ia32_Sub(sub));
2898 set_irn_mode(sub, mode_T);
2899 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2901 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2903 dbgi = get_irn_dbg_info(psi);
2904 noreg = ia32_new_NoReg_gp(env_cg);
2905 tmpreg = new_bd_ia32_ProduceVal(dbgi, block);
2906 nomem = new_NoMem();
2907 sbb = new_bd_ia32_Sbb(dbgi, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2909 new_node = new_bd_ia32_And(dbgi, block, noreg, noreg, nomem, new_node, sbb);
2910 set_ia32_commutative(new_node);
2915 * Transforms a Mux node into CMov.
2917 * @return The transformed node.
2919 static ir_node *gen_Mux(ir_node *node)
2921 dbg_info *dbgi = get_irn_dbg_info(node);
2922 ir_node *block = get_nodes_block(node);
2923 ir_node *new_block = be_transform_node(block);
2924 ir_node *mux_true = get_Mux_true(node);
2925 ir_node *mux_false = get_Mux_false(node);
2926 ir_node *cond = get_Mux_sel(node);
2927 ir_mode *mode = get_irn_mode(node);
2930 assert(get_irn_mode(cond) == mode_b);
2932 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2933 if (mode_is_float(mode)) {
2934 ir_node *cmp = get_Proj_pred(cond);
2935 ir_node *cmp_left = get_Cmp_left(cmp);
2936 ir_node *cmp_right = get_Cmp_right(cmp);
2937 pn_Cmp pnc = get_Proj_proj(cond);
2939 if (ia32_cg_config.use_sse2) {
2940 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2941 if (cmp_left == mux_true && cmp_right == mux_false) {
2942 /* Mux(a <= b, a, b) => MIN */
2943 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2944 match_commutative | match_am | match_two_users);
2945 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2946 /* Mux(a <= b, b, a) => MAX */
2947 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2948 match_commutative | match_am | match_two_users);
2950 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2951 if (cmp_left == mux_true && cmp_right == mux_false) {
2952 /* Mux(a >= b, a, b) => MAX */
2953 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2954 match_commutative | match_am | match_two_users);
2955 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2956 /* Mux(a >= b, b, a) => MIN */
2957 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2958 match_commutative | match_am | match_two_users);
2962 panic("cannot transform floating point Mux");
2968 assert(ia32_mode_needs_gp_reg(mode));
2970 if (is_Proj(cond)) {
2971 ir_node *cmp = get_Proj_pred(cond);
2973 ir_node *cmp_left = get_Cmp_left(cmp);
2974 ir_node *cmp_right = get_Cmp_right(cmp);
2975 pn_Cmp pnc = get_Proj_proj(cond);
2977 /* check for unsigned Doz first */
2978 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2979 is_Const_0(mux_false) && is_Sub(mux_true) &&
2980 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2981 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2982 return create_Doz(node, cmp_left, cmp_right);
2983 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2984 is_Const_0(mux_true) && is_Sub(mux_false) &&
2985 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2986 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2987 return create_Doz(node, cmp_left, cmp_right);
2992 flags = get_flags_node(cond, &pnc);
2994 if (is_Const(mux_true) && is_Const(mux_false)) {
2995 /* both are const, good */
2996 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2997 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2998 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2999 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3001 /* Not that simple. */
3006 new_node = create_CMov(node, cond, flags, pnc);
3014 * Create a conversion from x87 state register to general purpose.
3016 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3018 ir_node *block = be_transform_node(get_nodes_block(node));
3019 ir_node *op = get_Conv_op(node);
3020 ir_node *new_op = be_transform_node(op);
3021 ia32_code_gen_t *cg = env_cg;
3022 ir_graph *irg = current_ir_graph;
3023 dbg_info *dbgi = get_irn_dbg_info(node);
3024 ir_node *noreg = ia32_new_NoReg_gp(cg);
3025 ir_mode *mode = get_irn_mode(node);
3026 ir_node *fist, *load, *mem;
3028 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3029 set_irn_pinned(fist, op_pin_state_floats);
3030 set_ia32_use_frame(fist);
3031 set_ia32_op_type(fist, ia32_AddrModeD);
3033 assert(get_mode_size_bits(mode) <= 32);
3034 /* exception we can only store signed 32 bit integers, so for unsigned
3035 we store a 64bit (signed) integer and load the lower bits */
3036 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3037 set_ia32_ls_mode(fist, mode_Ls);
3039 set_ia32_ls_mode(fist, mode_Is);
3041 SET_IA32_ORIG_NODE(fist, node);
3044 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg, mem);
3046 set_irn_pinned(load, op_pin_state_floats);
3047 set_ia32_use_frame(load);
3048 set_ia32_op_type(load, ia32_AddrModeS);
3049 set_ia32_ls_mode(load, mode_Is);
3050 if (get_ia32_ls_mode(fist) == mode_Ls) {
3051 ia32_attr_t *attr = get_ia32_attr(load);
3052 attr->data.need_64bit_stackent = 1;
3054 ia32_attr_t *attr = get_ia32_attr(load);
3055 attr->data.need_32bit_stackent = 1;
3057 SET_IA32_ORIG_NODE(load, node);
3059 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3063 * Creates a x87 strict Conv by placing a Store and a Load
3065 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3067 ir_node *block = get_nodes_block(node);
3068 ir_graph *irg = current_ir_graph;
3069 dbg_info *dbgi = get_irn_dbg_info(node);
3070 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3071 ir_node *nomem = new_NoMem();
3072 ir_node *frame = get_irg_frame(irg);
3073 ir_node *store, *load;
3076 store = new_bd_ia32_vfst(dbgi, block, frame, noreg, nomem, node, tgt_mode);
3077 set_ia32_use_frame(store);
3078 set_ia32_op_type(store, ia32_AddrModeD);
3079 SET_IA32_ORIG_NODE(store, node);
3081 load = new_bd_ia32_vfld(dbgi, block, frame, noreg, store, tgt_mode);
3082 set_ia32_use_frame(load);
3083 set_ia32_op_type(load, ia32_AddrModeS);
3084 SET_IA32_ORIG_NODE(load, node);
3086 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3090 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3091 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3093 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3095 func = get_mode_size_bits(mode) == 8 ?
3096 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3097 return func(dbgi, block, base, index, mem, val, mode);
3101 * Create a conversion from general purpose to x87 register
3103 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3105 ir_node *src_block = get_nodes_block(node);
3106 ir_node *block = be_transform_node(src_block);
3107 ir_graph *irg = current_ir_graph;
3108 dbg_info *dbgi = get_irn_dbg_info(node);
3109 ir_node *op = get_Conv_op(node);
3110 ir_node *new_op = NULL;
3114 ir_mode *store_mode;
3119 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3120 if (possible_int_mode_for_fp(src_mode)) {
3121 ia32_address_mode_t am;
3123 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3124 if (am.op_type == ia32_AddrModeS) {
3125 ia32_address_t *addr = &am.addr;
3127 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index,
3129 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3132 set_am_attributes(fild, &am);
3133 SET_IA32_ORIG_NODE(fild, node);
3135 fix_mem_proj(fild, &am);
3140 if (new_op == NULL) {
3141 new_op = be_transform_node(op);
3144 noreg = ia32_new_NoReg_gp(env_cg);
3145 nomem = new_NoMem();
3146 mode = get_irn_mode(op);
3148 /* first convert to 32 bit signed if necessary */
3149 if (get_mode_size_bits(src_mode) < 32) {
3150 if (!upper_bits_clean(new_op, src_mode)) {
3151 new_op = create_Conv_I2I(dbgi, block, noreg, noreg, nomem, new_op, src_mode);
3152 SET_IA32_ORIG_NODE(new_op, node);
3157 assert(get_mode_size_bits(mode) == 32);
3160 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg, nomem,
3163 set_ia32_use_frame(store);
3164 set_ia32_op_type(store, ia32_AddrModeD);
3165 set_ia32_ls_mode(store, mode_Iu);
3167 /* exception for 32bit unsigned, do a 64bit spill+load */
3168 if (!mode_is_signed(mode)) {
3171 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3173 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3174 noreg, nomem, zero_const);
3176 set_ia32_use_frame(zero_store);
3177 set_ia32_op_type(zero_store, ia32_AddrModeD);
3178 add_ia32_am_offs_int(zero_store, 4);
3179 set_ia32_ls_mode(zero_store, mode_Iu);
3184 store = new_rd_Sync(dbgi, irg, block, 2, in);
3185 store_mode = mode_Ls;
3187 store_mode = mode_Is;
3191 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg, store);
3193 set_ia32_use_frame(fild);
3194 set_ia32_op_type(fild, ia32_AddrModeS);
3195 set_ia32_ls_mode(fild, store_mode);
3197 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3203 * Create a conversion from one integer mode into another one
3205 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3206 dbg_info *dbgi, ir_node *block, ir_node *op,
3209 ir_node *new_block = be_transform_node(block);
3211 ir_mode *smaller_mode;
3212 ia32_address_mode_t am;
3213 ia32_address_t *addr = &am.addr;
3216 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3217 smaller_mode = src_mode;
3219 smaller_mode = tgt_mode;
3222 #ifdef DEBUG_libfirm
3224 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3229 match_arguments(&am, block, NULL, op, NULL,
3230 match_am | match_8bit_am | match_16bit_am);
3232 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3233 /* unnecessary conv. in theory it shouldn't have been AM */
3234 assert(is_ia32_NoReg_GP(addr->base));
3235 assert(is_ia32_NoReg_GP(addr->index));
3236 assert(is_NoMem(addr->mem));
3237 assert(am.addr.offset == 0);
3238 assert(am.addr.symconst_ent == NULL);
3242 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3243 addr->mem, am.new_op2, smaller_mode);
3244 set_am_attributes(new_node, &am);
3245 /* match_arguments assume that out-mode = in-mode, this isn't true here
3247 set_ia32_ls_mode(new_node, smaller_mode);
3248 SET_IA32_ORIG_NODE(new_node, node);
3249 new_node = fix_mem_proj(new_node, &am);
3254 * Transforms a Conv node.
3256 * @return The created ia32 Conv node
3258 static ir_node *gen_Conv(ir_node *node)
3260 ir_node *block = get_nodes_block(node);
3261 ir_node *new_block = be_transform_node(block);
3262 ir_node *op = get_Conv_op(node);
3263 ir_node *new_op = NULL;
3264 dbg_info *dbgi = get_irn_dbg_info(node);
3265 ir_mode *src_mode = get_irn_mode(op);
3266 ir_mode *tgt_mode = get_irn_mode(node);
3267 int src_bits = get_mode_size_bits(src_mode);
3268 int tgt_bits = get_mode_size_bits(tgt_mode);
3269 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3270 ir_node *nomem = new_NoMem();
3271 ir_node *res = NULL;
3273 assert(!mode_is_int(src_mode) || src_bits <= 32);
3274 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3276 if (src_mode == mode_b) {
3277 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3278 /* nothing to do, we already model bools as 0/1 ints */
3279 return be_transform_node(op);
3282 if (src_mode == tgt_mode) {
3283 if (get_Conv_strict(node)) {
3284 if (ia32_cg_config.use_sse2) {
3285 /* when we are in SSE mode, we can kill all strict no-op conversion */
3286 return be_transform_node(op);
3289 /* this should be optimized already, but who knows... */
3290 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3291 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3292 return be_transform_node(op);
3296 if (mode_is_float(src_mode)) {
3297 new_op = be_transform_node(op);
3298 /* we convert from float ... */
3299 if (mode_is_float(tgt_mode)) {
3300 if (src_mode == mode_E && tgt_mode == mode_D
3301 && !get_Conv_strict(node)) {
3302 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3307 if (ia32_cg_config.use_sse2) {
3308 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3309 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg, noreg,
3311 set_ia32_ls_mode(res, tgt_mode);
3313 if (get_Conv_strict(node)) {
3314 res = gen_x87_strict_conv(tgt_mode, new_op);
3315 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3318 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3323 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3324 if (ia32_cg_config.use_sse2) {
3325 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg, noreg,
3327 set_ia32_ls_mode(res, src_mode);
3329 return gen_x87_fp_to_gp(node);
3333 /* we convert from int ... */
3334 if (mode_is_float(tgt_mode)) {
3336 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3337 if (ia32_cg_config.use_sse2) {
3338 new_op = be_transform_node(op);
3339 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg, noreg,
3341 set_ia32_ls_mode(res, tgt_mode);
3343 res = gen_x87_gp_to_fp(node, src_mode);
3344 if (get_Conv_strict(node)) {
3345 /* The strict-Conv is only necessary, if the int mode has more bits
3346 * than the float mantissa */
3347 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3348 size_t float_mantissa;
3349 /* FIXME There is no way to get the mantissa size of a mode */
3350 switch (get_mode_size_bits(tgt_mode)) {
3351 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3352 case 64: float_mantissa = 52 + 1; break;
3354 case 96: float_mantissa = 64; break;
3355 default: float_mantissa = 0; break;
3357 if (float_mantissa < int_mantissa) {
3358 res = gen_x87_strict_conv(tgt_mode, res);
3359 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3364 } else if (tgt_mode == mode_b) {
3365 /* mode_b lowering already took care that we only have 0/1 values */
3366 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3367 src_mode, tgt_mode));
3368 return be_transform_node(op);
3371 if (src_bits == tgt_bits) {
3372 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3373 src_mode, tgt_mode));
3374 return be_transform_node(op);
3377 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3385 static ir_node *create_immediate_or_transform(ir_node *node,
3386 char immediate_constraint_type)
3388 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3389 if (new_node == NULL) {
3390 new_node = be_transform_node(node);
3396 * Transforms a FrameAddr into an ia32 Add.
3398 static ir_node *gen_be_FrameAddr(ir_node *node)
3400 ir_node *block = be_transform_node(get_nodes_block(node));
3401 ir_node *op = be_get_FrameAddr_frame(node);
3402 ir_node *new_op = be_transform_node(op);
3403 dbg_info *dbgi = get_irn_dbg_info(node);
3404 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3407 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg);
3408 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3409 set_ia32_use_frame(new_node);
3411 SET_IA32_ORIG_NODE(new_node, node);
3417 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3419 static ir_node *gen_be_Return(ir_node *node)
3421 ir_graph *irg = current_ir_graph;
3422 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3423 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3424 ir_entity *ent = get_irg_entity(irg);
3425 ir_type *tp = get_entity_type(ent);
3430 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3431 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3434 int pn_ret_val, pn_ret_mem, arity, i;
3436 assert(ret_val != NULL);
3437 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3438 return be_duplicate_node(node);
3441 res_type = get_method_res_type(tp, 0);
3443 if (! is_Primitive_type(res_type)) {
3444 return be_duplicate_node(node);
3447 mode = get_type_mode(res_type);
3448 if (! mode_is_float(mode)) {
3449 return be_duplicate_node(node);
3452 assert(get_method_n_ress(tp) == 1);
3454 pn_ret_val = get_Proj_proj(ret_val);
3455 pn_ret_mem = get_Proj_proj(ret_mem);
3457 /* get the Barrier */
3458 barrier = get_Proj_pred(ret_val);
3460 /* get result input of the Barrier */
3461 ret_val = get_irn_n(barrier, pn_ret_val);
3462 new_ret_val = be_transform_node(ret_val);
3464 /* get memory input of the Barrier */
3465 ret_mem = get_irn_n(barrier, pn_ret_mem);
3466 new_ret_mem = be_transform_node(ret_mem);
3468 frame = get_irg_frame(irg);
3470 dbgi = get_irn_dbg_info(barrier);
3471 block = be_transform_node(get_nodes_block(barrier));
3473 noreg = ia32_new_NoReg_gp(env_cg);
3475 /* store xmm0 onto stack */
3476 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg,
3477 new_ret_mem, new_ret_val);
3478 set_ia32_ls_mode(sse_store, mode);
3479 set_ia32_op_type(sse_store, ia32_AddrModeD);
3480 set_ia32_use_frame(sse_store);
3482 /* load into x87 register */
3483 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg, sse_store, mode);
3484 set_ia32_op_type(fld, ia32_AddrModeS);
3485 set_ia32_use_frame(fld);
3487 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3488 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3490 /* create a new barrier */
3491 arity = get_irn_arity(barrier);
3492 in = ALLOCAN(ir_node*, arity);
3493 for (i = 0; i < arity; ++i) {
3496 if (i == pn_ret_val) {
3498 } else if (i == pn_ret_mem) {
3501 ir_node *in = get_irn_n(barrier, i);
3502 new_in = be_transform_node(in);
3507 new_barrier = new_ir_node(dbgi, irg, block,
3508 get_irn_op(barrier), get_irn_mode(barrier),
3510 copy_node_attr(barrier, new_barrier);
3511 be_duplicate_deps(barrier, new_barrier);
3512 be_set_transformed_node(barrier, new_barrier);
3514 /* transform normally */
3515 return be_duplicate_node(node);
3519 * Transform a be_AddSP into an ia32_SubSP.
3521 static ir_node *gen_be_AddSP(ir_node *node)
3523 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3524 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3526 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3527 match_am | match_immediate);
3531 * Transform a be_SubSP into an ia32_AddSP
3533 static ir_node *gen_be_SubSP(ir_node *node)
3535 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3536 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3538 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3539 match_am | match_immediate);
3543 * Change some phi modes
3545 static ir_node *gen_Phi(ir_node *node)
3547 ir_node *block = be_transform_node(get_nodes_block(node));
3548 ir_graph *irg = current_ir_graph;
3549 dbg_info *dbgi = get_irn_dbg_info(node);
3550 ir_mode *mode = get_irn_mode(node);
3553 if (ia32_mode_needs_gp_reg(mode)) {
3554 /* we shouldn't have any 64bit stuff around anymore */
3555 assert(get_mode_size_bits(mode) <= 32);
3556 /* all integer operations are on 32bit registers now */
3558 } else if (mode_is_float(mode)) {
3559 if (ia32_cg_config.use_sse2) {
3566 /* phi nodes allow loops, so we use the old arguments for now
3567 * and fix this later */
3568 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3569 get_irn_in(node) + 1);
3570 copy_node_attr(node, phi);
3571 be_duplicate_deps(node, phi);
3573 be_enqueue_preds(node);
3581 static ir_node *gen_IJmp(ir_node *node)
3583 ir_node *block = get_nodes_block(node);
3584 ir_node *new_block = be_transform_node(block);
3585 dbg_info *dbgi = get_irn_dbg_info(node);
3586 ir_node *op = get_IJmp_target(node);
3588 ia32_address_mode_t am;
3589 ia32_address_t *addr = &am.addr;
3591 assert(get_irn_mode(op) == mode_P);
3593 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3595 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3596 addr->mem, am.new_op2);
3597 set_am_attributes(new_node, &am);
3598 SET_IA32_ORIG_NODE(new_node, node);
3600 new_node = fix_mem_proj(new_node, &am);
3606 * Transform a Bound node.
3608 static ir_node *gen_Bound(ir_node *node)
3611 ir_node *lower = get_Bound_lower(node);
3612 dbg_info *dbgi = get_irn_dbg_info(node);
3614 if (is_Const_0(lower)) {
3615 /* typical case for Java */
3616 ir_node *sub, *res, *flags, *block;
3617 ir_graph *irg = current_ir_graph;
3619 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3620 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3622 block = get_nodes_block(res);
3623 if (! is_Proj(res)) {
3625 set_irn_mode(sub, mode_T);
3626 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3628 sub = get_Proj_pred(res);
3630 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3631 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3632 SET_IA32_ORIG_NODE(new_node, node);
3634 panic("generic Bound not supported in ia32 Backend");
3640 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3642 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3643 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3645 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3646 match_immediate | match_mode_neutral);
3649 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3651 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3652 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3653 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3657 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3659 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3660 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3661 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3665 static ir_node *gen_ia32_l_Add(ir_node *node)
3667 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3668 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3669 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3670 match_commutative | match_am | match_immediate |
3671 match_mode_neutral);
3673 if (is_Proj(lowered)) {
3674 lowered = get_Proj_pred(lowered);
3676 assert(is_ia32_Add(lowered));
3677 set_irn_mode(lowered, mode_T);
3683 static ir_node *gen_ia32_l_Adc(ir_node *node)
3685 return gen_binop_flags(node, new_bd_ia32_Adc,
3686 match_commutative | match_am | match_immediate |
3687 match_mode_neutral);
3691 * Transforms a l_MulS into a "real" MulS node.
3693 * @return the created ia32 Mul node
3695 static ir_node *gen_ia32_l_Mul(ir_node *node)
3697 ir_node *left = get_binop_left(node);
3698 ir_node *right = get_binop_right(node);
3700 return gen_binop(node, left, right, new_bd_ia32_Mul,
3701 match_commutative | match_am | match_mode_neutral);
3705 * Transforms a l_IMulS into a "real" IMul1OPS node.
3707 * @return the created ia32 IMul1OP node
3709 static ir_node *gen_ia32_l_IMul(ir_node *node)
3711 ir_node *left = get_binop_left(node);
3712 ir_node *right = get_binop_right(node);
3714 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3715 match_commutative | match_am | match_mode_neutral);
3718 static ir_node *gen_ia32_l_Sub(ir_node *node)
3720 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3721 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3722 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3723 match_am | match_immediate | match_mode_neutral);
3725 if (is_Proj(lowered)) {
3726 lowered = get_Proj_pred(lowered);
3728 assert(is_ia32_Sub(lowered));
3729 set_irn_mode(lowered, mode_T);
3735 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3737 return gen_binop_flags(node, new_bd_ia32_Sbb,
3738 match_am | match_immediate | match_mode_neutral);
3742 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3743 * op1 - target to be shifted
3744 * op2 - contains bits to be shifted into target
3746 * Only op3 can be an immediate.
3748 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3749 ir_node *low, ir_node *count)
3751 ir_node *block = get_nodes_block(node);
3752 ir_node *new_block = be_transform_node(block);
3753 dbg_info *dbgi = get_irn_dbg_info(node);
3754 ir_node *new_high = be_transform_node(high);
3755 ir_node *new_low = be_transform_node(low);
3759 /* the shift amount can be any mode that is bigger than 5 bits, since all
3760 * other bits are ignored anyway */
3761 while (is_Conv(count) &&
3762 get_irn_n_edges(count) == 1 &&
3763 mode_is_int(get_irn_mode(count))) {
3764 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3765 count = get_Conv_op(count);
3767 new_count = create_immediate_or_transform(count, 0);
3769 if (is_ia32_l_ShlD(node)) {
3770 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3773 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3776 SET_IA32_ORIG_NODE(new_node, node);
3781 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3783 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3784 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3785 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3786 return gen_lowered_64bit_shifts(node, high, low, count);
3789 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3791 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3792 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3793 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3794 return gen_lowered_64bit_shifts(node, high, low, count);
3797 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3799 ir_node *src_block = get_nodes_block(node);
3800 ir_node *block = be_transform_node(src_block);
3801 ir_graph *irg = current_ir_graph;
3802 dbg_info *dbgi = get_irn_dbg_info(node);
3803 ir_node *frame = get_irg_frame(irg);
3804 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3805 ir_node *nomem = new_NoMem();
3806 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3807 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3808 ir_node *new_val_low = be_transform_node(val_low);
3809 ir_node *new_val_high = be_transform_node(val_high);
3811 ir_node *sync, *fild, *res;
3812 ir_node *store_low, *store_high;
3814 if (ia32_cg_config.use_sse2) {
3815 panic("ia32_l_LLtoFloat not implemented for SSE2");
3819 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3821 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3823 SET_IA32_ORIG_NODE(store_low, node);
3824 SET_IA32_ORIG_NODE(store_high, node);
3826 set_ia32_use_frame(store_low);
3827 set_ia32_use_frame(store_high);
3828 set_ia32_op_type(store_low, ia32_AddrModeD);
3829 set_ia32_op_type(store_high, ia32_AddrModeD);
3830 set_ia32_ls_mode(store_low, mode_Iu);
3831 set_ia32_ls_mode(store_high, mode_Is);
3832 add_ia32_am_offs_int(store_high, 4);
3836 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3839 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg, sync);
3841 set_ia32_use_frame(fild);
3842 set_ia32_op_type(fild, ia32_AddrModeS);
3843 set_ia32_ls_mode(fild, mode_Ls);
3845 SET_IA32_ORIG_NODE(fild, node);
3847 res = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3849 if (! mode_is_signed(get_irn_mode(val_high))) {
3850 ia32_address_mode_t am;
3852 ir_node *count = create_Immediate(NULL, 0, 31);
3855 am.addr.base = ia32_new_NoReg_gp(env_cg);
3856 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
3857 am.addr.mem = nomem;
3860 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
3861 am.addr.use_frame = 0;
3862 am.addr.frame_entity = NULL;
3863 am.addr.symconst_sign = 0;
3864 am.ls_mode = mode_F;
3865 am.mem_proj = nomem;
3866 am.op_type = ia32_AddrModeS;
3868 am.new_op2 = ia32_new_NoReg_vfp(env_cg);
3869 am.pinned = op_pin_state_floats;
3871 am.ins_permuted = 0;
3873 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
3874 am.new_op1, am.new_op2, get_fpcw());
3875 set_am_attributes(fadd, &am);
3877 set_irn_mode(fadd, mode_T);
3878 res = new_rd_Proj(NULL, irg, block, fadd, mode_vfp, pn_ia32_res);
3883 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3885 ir_node *src_block = get_nodes_block(node);
3886 ir_node *block = be_transform_node(src_block);
3887 ir_graph *irg = current_ir_graph;
3888 dbg_info *dbgi = get_irn_dbg_info(node);
3889 ir_node *frame = get_irg_frame(irg);
3890 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3891 ir_node *nomem = new_NoMem();
3892 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3893 ir_node *new_val = be_transform_node(val);
3894 ir_node *fist, *mem;
3896 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3897 SET_IA32_ORIG_NODE(fist, node);
3898 set_ia32_use_frame(fist);
3899 set_ia32_op_type(fist, ia32_AddrModeD);
3900 set_ia32_ls_mode(fist, mode_Ls);
3906 * the BAD transformer.
3908 static ir_node *bad_transform(ir_node *node)
3910 panic("No transform function for %+F available.", node);
3914 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3916 ir_graph *irg = current_ir_graph;
3917 ir_node *block = be_transform_node(get_nodes_block(node));
3918 ir_node *pred = get_Proj_pred(node);
3919 ir_node *new_pred = be_transform_node(pred);
3920 ir_node *frame = get_irg_frame(irg);
3921 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3922 dbg_info *dbgi = get_irn_dbg_info(node);
3923 long pn = get_Proj_proj(node);
3928 load = new_bd_ia32_Load(dbgi, block, frame, noreg, new_pred);
3929 SET_IA32_ORIG_NODE(load, node);
3930 set_ia32_use_frame(load);
3931 set_ia32_op_type(load, ia32_AddrModeS);
3932 set_ia32_ls_mode(load, mode_Iu);
3933 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3934 * 32 bit from it with this particular load */
3935 attr = get_ia32_attr(load);
3936 attr->data.need_64bit_stackent = 1;
3938 if (pn == pn_ia32_l_FloattoLL_res_high) {
3939 add_ia32_am_offs_int(load, 4);
3941 assert(pn == pn_ia32_l_FloattoLL_res_low);
3944 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3950 * Transform the Projs of an AddSP.
3952 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3954 ir_node *block = be_transform_node(get_nodes_block(node));
3955 ir_node *pred = get_Proj_pred(node);
3956 ir_node *new_pred = be_transform_node(pred);
3957 ir_graph *irg = current_ir_graph;
3958 dbg_info *dbgi = get_irn_dbg_info(node);
3959 long proj = get_Proj_proj(node);
3961 if (proj == pn_be_AddSP_sp) {
3962 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3963 pn_ia32_SubSP_stack);
3964 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3966 } else if (proj == pn_be_AddSP_res) {
3967 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3968 pn_ia32_SubSP_addr);
3969 } else if (proj == pn_be_AddSP_M) {
3970 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3973 panic("No idea how to transform proj->AddSP");
3977 * Transform the Projs of a SubSP.
3979 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3981 ir_node *block = be_transform_node(get_nodes_block(node));
3982 ir_node *pred = get_Proj_pred(node);
3983 ir_node *new_pred = be_transform_node(pred);
3984 ir_graph *irg = current_ir_graph;
3985 dbg_info *dbgi = get_irn_dbg_info(node);
3986 long proj = get_Proj_proj(node);
3988 if (proj == pn_be_SubSP_sp) {
3989 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3990 pn_ia32_AddSP_stack);
3991 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3993 } else if (proj == pn_be_SubSP_M) {
3994 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3997 panic("No idea how to transform proj->SubSP");
4001 * Transform and renumber the Projs from a Load.
4003 static ir_node *gen_Proj_Load(ir_node *node)
4006 ir_node *block = be_transform_node(get_nodes_block(node));
4007 ir_node *pred = get_Proj_pred(node);
4008 ir_graph *irg = current_ir_graph;
4009 dbg_info *dbgi = get_irn_dbg_info(node);
4010 long proj = get_Proj_proj(node);
4012 /* loads might be part of source address mode matches, so we don't
4013 * transform the ProjMs yet (with the exception of loads whose result is
4016 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4019 /* this is needed, because sometimes we have loops that are only
4020 reachable through the ProjM */
4021 be_enqueue_preds(node);
4022 /* do it in 2 steps, to silence firm verifier */
4023 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4024 set_Proj_proj(res, pn_ia32_mem);
4028 /* renumber the proj */
4029 new_pred = be_transform_node(pred);
4030 if (is_ia32_Load(new_pred)) {
4033 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4035 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4036 case pn_Load_X_regular:
4037 return new_rd_Jmp(dbgi, irg, block);
4038 case pn_Load_X_except:
4039 /* This Load might raise an exception. Mark it. */
4040 set_ia32_exc_label(new_pred, 1);
4041 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4045 } else if (is_ia32_Conv_I2I(new_pred) ||
4046 is_ia32_Conv_I2I8Bit(new_pred)) {
4047 set_irn_mode(new_pred, mode_T);
4048 if (proj == pn_Load_res) {
4049 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4050 } else if (proj == pn_Load_M) {
4051 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4053 } else if (is_ia32_xLoad(new_pred)) {
4056 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4058 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4059 case pn_Load_X_regular:
4060 return new_rd_Jmp(dbgi, irg, block);
4061 case pn_Load_X_except:
4062 /* This Load might raise an exception. Mark it. */
4063 set_ia32_exc_label(new_pred, 1);
4064 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4068 } else if (is_ia32_vfld(new_pred)) {
4071 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4073 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4074 case pn_Load_X_regular:
4075 return new_rd_Jmp(dbgi, irg, block);
4076 case pn_Load_X_except:
4077 /* This Load might raise an exception. Mark it. */
4078 set_ia32_exc_label(new_pred, 1);
4079 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4084 /* can happen for ProJMs when source address mode happened for the
4087 /* however it should not be the result proj, as that would mean the
4088 load had multiple users and should not have been used for
4090 if (proj != pn_Load_M) {
4091 panic("internal error: transformed node not a Load");
4093 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4096 panic("No idea how to transform proj");
4100 * Transform and renumber the Projs from a DivMod like instruction.
4102 static ir_node *gen_Proj_DivMod(ir_node *node)
4104 ir_node *block = be_transform_node(get_nodes_block(node));
4105 ir_node *pred = get_Proj_pred(node);
4106 ir_node *new_pred = be_transform_node(pred);
4107 ir_graph *irg = current_ir_graph;
4108 dbg_info *dbgi = get_irn_dbg_info(node);
4109 long proj = get_Proj_proj(node);
4111 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4113 switch (get_irn_opcode(pred)) {
4117 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4119 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4120 case pn_Div_X_regular:
4121 return new_rd_Jmp(dbgi, irg, block);
4122 case pn_Div_X_except:
4123 set_ia32_exc_label(new_pred, 1);
4124 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4132 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4134 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4135 case pn_Mod_X_except:
4136 set_ia32_exc_label(new_pred, 1);
4137 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4145 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4146 case pn_DivMod_res_div:
4147 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4148 case pn_DivMod_res_mod:
4149 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4150 case pn_DivMod_X_regular:
4151 return new_rd_Jmp(dbgi, irg, block);
4152 case pn_DivMod_X_except:
4153 set_ia32_exc_label(new_pred, 1);
4154 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4163 panic("No idea how to transform proj->DivMod");
4167 * Transform and renumber the Projs from a CopyB.
4169 static ir_node *gen_Proj_CopyB(ir_node *node)
4171 ir_node *block = be_transform_node(get_nodes_block(node));
4172 ir_node *pred = get_Proj_pred(node);
4173 ir_node *new_pred = be_transform_node(pred);
4174 ir_graph *irg = current_ir_graph;
4175 dbg_info *dbgi = get_irn_dbg_info(node);
4176 long proj = get_Proj_proj(node);
4179 case pn_CopyB_M_regular:
4180 if (is_ia32_CopyB_i(new_pred)) {
4181 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4182 } else if (is_ia32_CopyB(new_pred)) {
4183 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4190 panic("No idea how to transform proj->CopyB");
4194 * Transform and renumber the Projs from a Quot.
4196 static ir_node *gen_Proj_Quot(ir_node *node)
4198 ir_node *block = be_transform_node(get_nodes_block(node));
4199 ir_node *pred = get_Proj_pred(node);
4200 ir_node *new_pred = be_transform_node(pred);
4201 ir_graph *irg = current_ir_graph;
4202 dbg_info *dbgi = get_irn_dbg_info(node);
4203 long proj = get_Proj_proj(node);
4207 if (is_ia32_xDiv(new_pred)) {
4208 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4209 } else if (is_ia32_vfdiv(new_pred)) {
4210 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4214 if (is_ia32_xDiv(new_pred)) {
4215 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4216 } else if (is_ia32_vfdiv(new_pred)) {
4217 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4220 case pn_Quot_X_regular:
4221 case pn_Quot_X_except:
4226 panic("No idea how to transform proj->Quot");
4229 static ir_node *gen_be_Call(ir_node *node)
4231 dbg_info *const dbgi = get_irn_dbg_info(node);
4232 ir_graph *const irg = current_ir_graph;
4233 ir_node *const src_block = get_nodes_block(node);
4234 ir_node *const block = be_transform_node(src_block);
4235 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4236 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4237 ir_node *const sp = be_transform_node(src_sp);
4238 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4239 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4240 ia32_address_mode_t am;
4241 ia32_address_t *const addr = &am.addr;
4246 ir_node * eax = noreg;
4247 ir_node * ecx = noreg;
4248 ir_node * edx = noreg;
4249 unsigned const pop = be_Call_get_pop(node);
4250 ir_type *const call_tp = be_Call_get_type(node);
4252 /* Run the x87 simulator if the call returns a float value */
4253 if (get_method_n_ress(call_tp) > 0) {
4254 ir_type *const res_type = get_method_res_type(call_tp, 0);
4255 ir_mode *const res_mode = get_type_mode(res_type);
4257 if (res_mode != NULL && mode_is_float(res_mode)) {
4258 env_cg->do_x87_sim = 1;
4262 /* We do not want be_Call direct calls */
4263 assert(be_Call_get_entity(node) == NULL);
4265 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4266 match_am | match_immediate);
4268 i = get_irn_arity(node) - 1;
4269 fpcw = be_transform_node(get_irn_n(node, i--));
4270 for (; i >= be_pos_Call_first_arg; --i) {
4271 arch_register_req_t const *const req = arch_get_register_req(node, i);
4272 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4274 assert(req->type == arch_register_req_type_limited);
4275 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4277 switch (*req->limited) {
4278 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4279 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4280 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4281 default: panic("Invalid GP register for register parameter");
4285 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4286 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4287 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4288 set_am_attributes(call, &am);
4289 call = fix_mem_proj(call, &am);
4291 if (get_irn_pinned(node) == op_pin_state_pinned)
4292 set_irn_pinned(call, op_pin_state_pinned);
4294 SET_IA32_ORIG_NODE(call, node);
4298 static ir_node *gen_be_IncSP(ir_node *node)
4300 ir_node *res = be_duplicate_node(node);
4301 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4307 * Transform the Projs from a be_Call.
4309 static ir_node *gen_Proj_be_Call(ir_node *node)
4311 ir_node *block = be_transform_node(get_nodes_block(node));
4312 ir_node *call = get_Proj_pred(node);
4313 ir_node *new_call = be_transform_node(call);
4314 ir_graph *irg = current_ir_graph;
4315 dbg_info *dbgi = get_irn_dbg_info(node);
4316 ir_type *method_type = be_Call_get_type(call);
4317 int n_res = get_method_n_ress(method_type);
4318 long proj = get_Proj_proj(node);
4319 ir_mode *mode = get_irn_mode(node);
4323 /* The following is kinda tricky: If we're using SSE, then we have to
4324 * move the result value of the call in floating point registers to an
4325 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4326 * after the call, we have to make sure to correctly make the
4327 * MemProj and the result Proj use these 2 nodes
4329 if (proj == pn_be_Call_M_regular) {
4330 // get new node for result, are we doing the sse load/store hack?
4331 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4332 ir_node *call_res_new;
4333 ir_node *call_res_pred = NULL;
4335 if (call_res != NULL) {
4336 call_res_new = be_transform_node(call_res);
4337 call_res_pred = get_Proj_pred(call_res_new);
4340 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4341 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4344 assert(is_ia32_xLoad(call_res_pred));
4345 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4349 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4350 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4352 ir_node *frame = get_irg_frame(irg);
4353 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4355 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4358 /* in case there is no memory output: create one to serialize the copy
4360 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4361 pn_be_Call_M_regular);
4362 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4363 pn_be_Call_first_res);
4365 /* store st(0) onto stack */
4366 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg, call_mem,
4368 set_ia32_op_type(fstp, ia32_AddrModeD);
4369 set_ia32_use_frame(fstp);
4371 /* load into SSE register */
4372 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg, fstp, mode);
4373 set_ia32_op_type(sse_load, ia32_AddrModeS);
4374 set_ia32_use_frame(sse_load);
4376 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4382 /* transform call modes */
4383 if (mode_is_data(mode)) {
4384 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4388 /* Map from be_Call to ia32_Call proj number */
4389 if (proj == pn_be_Call_sp) {
4390 proj = pn_ia32_Call_stack;
4391 } else if (proj == pn_be_Call_M_regular) {
4392 proj = pn_ia32_Call_M;
4394 arch_register_req_t const *const req = arch_get_register_req_out(node);
4395 int const n_outs = arch_irn_get_n_outs(new_call);
4398 assert(proj >= pn_be_Call_first_res);
4399 assert(req->type & arch_register_req_type_limited);
4401 for (i = 0; i < n_outs; ++i) {
4402 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4404 if (!(new_req->type & arch_register_req_type_limited) ||
4405 new_req->cls != req->cls ||
4406 *new_req->limited != *req->limited)
4415 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4417 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4419 case pn_ia32_Call_stack:
4420 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4423 case pn_ia32_Call_fpcw:
4424 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4432 * Transform the Projs from a Cmp.
4434 static ir_node *gen_Proj_Cmp(ir_node *node)
4436 /* this probably means not all mode_b nodes were lowered... */
4437 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4442 * Transform the Projs from a Bound.
4444 static ir_node *gen_Proj_Bound(ir_node *node)
4446 ir_node *new_node, *block;
4447 ir_node *pred = get_Proj_pred(node);
4449 switch (get_Proj_proj(node)) {
4451 return be_transform_node(get_Bound_mem(pred));
4452 case pn_Bound_X_regular:
4453 new_node = be_transform_node(pred);
4454 block = get_nodes_block(new_node);
4455 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4456 case pn_Bound_X_except:
4457 new_node = be_transform_node(pred);
4458 block = get_nodes_block(new_node);
4459 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4461 return be_transform_node(get_Bound_index(pred));
4463 panic("unsupported Proj from Bound");
4467 static ir_node *gen_Proj_ASM(ir_node *node)
4473 if (get_irn_mode(node) != mode_M)
4474 return be_duplicate_node(node);
4476 pred = get_Proj_pred(node);
4477 new_pred = be_transform_node(pred);
4478 block = get_nodes_block(new_pred);
4479 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4480 arch_irn_get_n_outs(new_pred) + 1);
4484 * Transform and potentially renumber Proj nodes.
4486 static ir_node *gen_Proj(ir_node *node)
4488 ir_node *pred = get_Proj_pred(node);
4491 switch (get_irn_opcode(pred)) {
4493 proj = get_Proj_proj(node);
4494 if (proj == pn_Store_M) {
4495 return be_transform_node(pred);
4497 panic("No idea how to transform proj->Store");
4500 return gen_Proj_Load(node);
4502 return gen_Proj_ASM(node);
4506 return gen_Proj_DivMod(node);
4508 return gen_Proj_CopyB(node);
4510 return gen_Proj_Quot(node);
4512 return gen_Proj_be_SubSP(node);
4514 return gen_Proj_be_AddSP(node);
4516 return gen_Proj_be_Call(node);
4518 return gen_Proj_Cmp(node);
4520 return gen_Proj_Bound(node);
4522 proj = get_Proj_proj(node);
4524 case pn_Start_X_initial_exec: {
4525 ir_node *block = get_nodes_block(pred);
4526 ir_node *new_block = be_transform_node(block);
4527 dbg_info *dbgi = get_irn_dbg_info(node);
4528 /* we exchange the ProjX with a jump */
4529 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4534 case pn_Start_P_tls:
4535 return gen_Proj_tls(node);
4540 if (is_ia32_l_FloattoLL(pred)) {
4541 return gen_Proj_l_FloattoLL(node);
4543 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4547 ir_mode *mode = get_irn_mode(node);
4548 if (ia32_mode_needs_gp_reg(mode)) {
4549 ir_node *new_pred = be_transform_node(pred);
4550 ir_node *block = be_transform_node(get_nodes_block(node));
4551 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4552 mode_Iu, get_Proj_proj(node));
4553 #ifdef DEBUG_libfirm
4554 new_proj->node_nr = node->node_nr;
4560 return be_duplicate_node(node);
4564 * Enters all transform functions into the generic pointer
4566 static void register_transformers(void)
4570 /* first clear the generic function pointer for all ops */
4571 clear_irp_opcodes_generic_func();
4573 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4574 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4612 /* transform ops from intrinsic lowering */
4624 GEN(ia32_l_LLtoFloat);
4625 GEN(ia32_l_FloattoLL);
4631 /* we should never see these nodes */
4646 /* handle generic backend nodes */
4655 op_Mulh = get_op_Mulh();
4664 * Pre-transform all unknown and noreg nodes.
4666 static void ia32_pretransform_node(void)
4668 ia32_code_gen_t *cg = env_cg;
4670 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4671 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4672 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4673 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4674 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4675 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4680 * Walker, checks if all ia32 nodes producing more than one result have their
4681 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4683 static void add_missing_keep_walker(ir_node *node, void *data)
4686 unsigned found_projs = 0;
4687 const ir_edge_t *edge;
4688 ir_mode *mode = get_irn_mode(node);
4693 if (!is_ia32_irn(node))
4696 n_outs = arch_irn_get_n_outs(node);
4699 if (is_ia32_SwitchJmp(node))
4702 assert(n_outs < (int) sizeof(unsigned) * 8);
4703 foreach_out_edge(node, edge) {
4704 ir_node *proj = get_edge_src_irn(edge);
4707 /* The node could be kept */
4711 if (get_irn_mode(proj) == mode_M)
4714 pn = get_Proj_proj(proj);
4715 assert(pn < n_outs);
4716 found_projs |= 1 << pn;
4720 /* are keeps missing? */
4722 for (i = 0; i < n_outs; ++i) {
4725 const arch_register_req_t *req;
4726 const arch_register_class_t *cls;
4728 if (found_projs & (1 << i)) {
4732 req = get_ia32_out_req(node, i);
4737 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4741 block = get_nodes_block(node);
4742 in[0] = new_r_Proj(current_ir_graph, block, node,
4743 arch_register_class_mode(cls), i);
4744 if (last_keep != NULL) {
4745 be_Keep_add_node(last_keep, cls, in[0]);
4747 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4748 if (sched_is_scheduled(node)) {
4749 sched_add_after(node, last_keep);
4756 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4759 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4761 ir_graph *irg = be_get_birg_irg(cg->birg);
4762 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4765 /* do the transformation */
4766 void ia32_transform_graph(ia32_code_gen_t *cg)
4770 register_transformers();
4772 initial_fpcw = NULL;
4774 BE_TIMER_PUSH(t_heights);
4775 heights = heights_new(cg->irg);
4776 BE_TIMER_POP(t_heights);
4777 ia32_calculate_non_address_mode_nodes(cg->birg);
4779 /* the transform phase is not safe for CSE (yet) because several nodes get
4780 * attributes set after their creation */
4781 cse_last = get_opt_cse();
4784 be_transform_graph(cg->birg, ia32_pretransform_node);
4786 set_opt_cse(cse_last);
4788 ia32_free_non_address_mode_nodes();
4789 heights_free(heights);
4793 void ia32_init_transform(void)
4795 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");