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
36 #include "irgraph_t.h"
41 #include "iredges_t.h"
54 #include "../benode_t.h"
55 #include "../besched.h"
57 #include "../beutil.h"
58 #include "../beirg_t.h"
59 #include "../betranshlp.h"
62 #include "bearch_ia32_t.h"
63 #include "ia32_common_transform.h"
64 #include "ia32_nodes_attr.h"
65 #include "ia32_transform.h"
66 #include "ia32_new_nodes.h"
67 #include "ia32_map_regs.h"
68 #include "ia32_dbg_stat.h"
69 #include "ia32_optimize.h"
70 #include "ia32_util.h"
71 #include "ia32_address_mode.h"
72 #include "ia32_architecture.h"
74 #include "gen_ia32_regalloc_if.h"
76 #define SFP_SIGN "0x80000000"
77 #define DFP_SIGN "0x8000000000000000"
78 #define SFP_ABS "0x7FFFFFFF"
79 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
80 #define DFP_INTMAX "9223372036854775807"
82 #define TP_SFP_SIGN "ia32_sfp_sign"
83 #define TP_DFP_SIGN "ia32_dfp_sign"
84 #define TP_SFP_ABS "ia32_sfp_abs"
85 #define TP_DFP_ABS "ia32_dfp_abs"
86 #define TP_INT_MAX "ia32_int_max"
88 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
89 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
90 #define ENT_SFP_ABS "IA32_SFP_ABS"
91 #define ENT_DFP_ABS "IA32_DFP_ABS"
92 #define ENT_INT_MAX "IA32_INT_MAX"
94 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
95 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
97 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
99 static ir_node *initial_fpcw = NULL;
101 extern ir_op *get_op_Mulh(void);
103 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
104 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
105 ir_node *op1, ir_node *op2);
107 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
108 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
109 ir_node *op1, ir_node *op2, ir_node *flags);
111 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
112 ir_node *block, ir_node *op1, ir_node *op2);
114 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
115 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
118 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
119 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
121 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
122 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
123 ir_node *op1, ir_node *op2, ir_node *fpcw);
125 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
126 ir_node *block, ir_node *op);
128 static ir_node *create_immediate_or_transform(ir_node *node,
129 char immediate_constraint_type);
131 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
132 dbg_info *dbgi, ir_node *block,
133 ir_node *op, ir_node *orig_node);
135 /** Return non-zero is a node represents the 0 constant. */
136 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) {
142 return is_Const(node) && is_Const_one(node);
145 /** Return non-zero is a node represents the -1 constant. */
146 static bool is_Const_Minus_1(ir_node *node) {
147 return is_Const(node) && is_Const_all_one(node);
151 * returns true if constant can be created with a simple float command
153 static bool is_simple_x87_Const(ir_node *node)
155 tarval *tv = get_Const_tarval(node);
156 if (tarval_is_null(tv) || tarval_is_one(tv))
159 /* TODO: match all the other float constants */
164 * returns true if constant can be created with a simple float command
166 static bool is_simple_sse_Const(ir_node *node)
168 tarval *tv = get_Const_tarval(node);
169 ir_mode *mode = get_tarval_mode(tv);
174 if (tarval_is_null(tv) || tarval_is_one(tv))
177 if (mode == mode_D) {
178 unsigned val = get_tarval_sub_bits(tv, 0) |
179 (get_tarval_sub_bits(tv, 1) << 8) |
180 (get_tarval_sub_bits(tv, 2) << 16) |
181 (get_tarval_sub_bits(tv, 3) << 24);
183 /* lower 32bit are zero, really a 32bit constant */
187 /* TODO: match all the other float constants */
192 * Transforms a Const.
194 static ir_node *gen_Const(ir_node *node) {
195 ir_graph *irg = current_ir_graph;
196 ir_node *old_block = get_nodes_block(node);
197 ir_node *block = be_transform_node(old_block);
198 dbg_info *dbgi = get_irn_dbg_info(node);
199 ir_mode *mode = get_irn_mode(node);
201 assert(is_Const(node));
203 if (mode_is_float(mode)) {
205 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
206 ir_node *nomem = new_NoMem();
210 if (ia32_cg_config.use_sse2) {
211 tarval *tv = get_Const_tarval(node);
212 if (tarval_is_null(tv)) {
213 load = new_rd_ia32_xZero(dbgi, irg, block);
214 set_ia32_ls_mode(load, mode);
216 } else if (tarval_is_one(tv)) {
217 int cnst = mode == mode_F ? 26 : 55;
218 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
219 ir_node *imm2 = create_Immediate(NULL, 0, 2);
220 ir_node *pslld, *psrld;
222 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
223 set_ia32_ls_mode(load, mode);
224 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
225 set_ia32_ls_mode(pslld, mode);
226 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
227 set_ia32_ls_mode(psrld, mode);
229 } else if (mode == mode_F) {
230 /* we can place any 32bit constant by using a movd gp, sse */
231 unsigned val = get_tarval_sub_bits(tv, 0) |
232 (get_tarval_sub_bits(tv, 1) << 8) |
233 (get_tarval_sub_bits(tv, 2) << 16) |
234 (get_tarval_sub_bits(tv, 3) << 24);
235 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
236 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
237 set_ia32_ls_mode(load, mode);
240 if (mode == mode_D) {
241 unsigned val = get_tarval_sub_bits(tv, 0) |
242 (get_tarval_sub_bits(tv, 1) << 8) |
243 (get_tarval_sub_bits(tv, 2) << 16) |
244 (get_tarval_sub_bits(tv, 3) << 24);
246 ir_node *imm32 = create_Immediate(NULL, 0, 32);
247 ir_node *cnst, *psllq;
249 /* fine, lower 32bit are zero, produce 32bit value */
250 val = get_tarval_sub_bits(tv, 4) |
251 (get_tarval_sub_bits(tv, 5) << 8) |
252 (get_tarval_sub_bits(tv, 6) << 16) |
253 (get_tarval_sub_bits(tv, 7) << 24);
254 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
255 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
256 set_ia32_ls_mode(load, mode);
257 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
258 set_ia32_ls_mode(psllq, mode);
263 floatent = create_float_const_entity(node);
265 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
267 set_ia32_op_type(load, ia32_AddrModeS);
268 set_ia32_am_sc(load, floatent);
269 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
270 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
273 if (is_Const_null(node)) {
274 load = new_rd_ia32_vfldz(dbgi, irg, block);
276 set_ia32_ls_mode(load, mode);
277 } else if (is_Const_one(node)) {
278 load = new_rd_ia32_vfld1(dbgi, irg, block);
280 set_ia32_ls_mode(load, mode);
282 floatent = create_float_const_entity(node);
284 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
285 set_ia32_op_type(load, ia32_AddrModeS);
286 set_ia32_am_sc(load, floatent);
287 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
288 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
289 /* take the mode from the entity */
290 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
294 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
296 be_dep_on_frame(load);
298 } else { /* non-float mode */
300 tarval *tv = get_Const_tarval(node);
303 tv = tarval_convert_to(tv, mode_Iu);
305 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
307 panic("couldn't convert constant tarval (%+F)", node);
309 val = get_tarval_long(tv);
311 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
312 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
314 be_dep_on_frame(cnst);
320 * Transforms a SymConst.
322 static ir_node *gen_SymConst(ir_node *node) {
323 ir_graph *irg = current_ir_graph;
324 ir_node *old_block = get_nodes_block(node);
325 ir_node *block = be_transform_node(old_block);
326 dbg_info *dbgi = get_irn_dbg_info(node);
327 ir_mode *mode = get_irn_mode(node);
330 if (mode_is_float(mode)) {
331 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
332 ir_node *nomem = new_NoMem();
334 if (ia32_cg_config.use_sse2)
335 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
337 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
338 set_ia32_am_sc(cnst, get_SymConst_entity(node));
339 set_ia32_use_frame(cnst);
343 if(get_SymConst_kind(node) != symconst_addr_ent) {
344 panic("backend only support symconst_addr_ent (at %+F)", node);
346 entity = get_SymConst_entity(node);
347 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
350 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
352 be_dep_on_frame(cnst);
356 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
357 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
358 static const struct {
360 const char *ent_name;
361 const char *cnst_str;
364 } names [ia32_known_const_max] = {
365 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
366 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
367 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
368 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
369 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
371 static ir_entity *ent_cache[ia32_known_const_max];
373 const char *tp_name, *ent_name, *cnst_str;
381 ent_name = names[kct].ent_name;
382 if (! ent_cache[kct]) {
383 tp_name = names[kct].tp_name;
384 cnst_str = names[kct].cnst_str;
386 switch (names[kct].mode) {
387 case 0: mode = mode_Iu; break;
388 case 1: mode = mode_Lu; break;
389 default: mode = mode_F; break;
391 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
392 tp = new_type_primitive(new_id_from_str(tp_name), mode);
393 /* set the specified alignment */
394 set_type_alignment_bytes(tp, names[kct].align);
396 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
398 set_entity_ld_ident(ent, get_entity_ident(ent));
399 set_entity_visibility(ent, visibility_local);
400 set_entity_variability(ent, variability_constant);
401 set_entity_allocation(ent, allocation_static);
403 /* we create a new entity here: It's initialization must resist on the
405 rem = current_ir_graph;
406 current_ir_graph = get_const_code_irg();
407 cnst = new_Const(mode, tv);
408 current_ir_graph = rem;
410 set_atomic_ent_value(ent, cnst);
412 /* cache the entry */
413 ent_cache[kct] = ent;
416 return ent_cache[kct];
420 * return true if the node is a Proj(Load) and could be used in source address
421 * mode for another node. Will return only true if the @p other node is not
422 * dependent on the memory of the Load (for binary operations use the other
423 * input here, for unary operations use NULL).
425 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
426 ir_node *other, ir_node *other2, match_flags_t flags)
431 /* float constants are always available */
432 if (is_Const(node)) {
433 ir_mode *mode = get_irn_mode(node);
434 if (mode_is_float(mode)) {
435 if (ia32_cg_config.use_sse2) {
436 if (is_simple_sse_Const(node))
439 if (is_simple_x87_Const(node))
442 if (get_irn_n_edges(node) > 1)
450 load = get_Proj_pred(node);
451 pn = get_Proj_proj(node);
452 if (!is_Load(load) || pn != pn_Load_res)
454 if (get_nodes_block(load) != block)
456 /* we only use address mode if we're the only user of the load */
457 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
459 /* in some edge cases with address mode we might reach the load normally
460 * and through some AM sequence, if it is already materialized then we
461 * can't create an AM node from it */
462 if (be_is_transformed(node))
465 /* don't do AM if other node inputs depend on the load (via mem-proj) */
466 if (other != NULL && prevents_AM(block, load, other))
469 if (other2 != NULL && prevents_AM(block, load, other2))
475 typedef struct ia32_address_mode_t ia32_address_mode_t;
476 struct ia32_address_mode_t {
481 ia32_op_type_t op_type;
485 unsigned commutative : 1;
486 unsigned ins_permuted : 1;
489 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
493 /* construct load address */
494 memset(addr, 0, sizeof(addr[0]));
495 ia32_create_address_mode(addr, ptr, /*force=*/0);
497 noreg_gp = ia32_new_NoReg_gp(env_cg);
498 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
499 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
500 addr->mem = be_transform_node(mem);
503 static void build_address(ia32_address_mode_t *am, ir_node *node)
505 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
506 ia32_address_t *addr = &am->addr;
512 if (is_Const(node)) {
513 ir_entity *entity = create_float_const_entity(node);
514 addr->base = noreg_gp;
515 addr->index = noreg_gp;
516 addr->mem = new_NoMem();
517 addr->symconst_ent = entity;
519 am->ls_mode = get_type_mode(get_entity_type(entity));
520 am->pinned = op_pin_state_floats;
524 load = get_Proj_pred(node);
525 ptr = get_Load_ptr(load);
526 mem = get_Load_mem(load);
527 new_mem = be_transform_node(mem);
528 am->pinned = get_irn_pinned(load);
529 am->ls_mode = get_Load_mode(load);
530 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
533 /* construct load address */
534 ia32_create_address_mode(addr, ptr, /*force=*/0);
536 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
537 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
541 static void set_address(ir_node *node, const ia32_address_t *addr)
543 set_ia32_am_scale(node, addr->scale);
544 set_ia32_am_sc(node, addr->symconst_ent);
545 set_ia32_am_offs_int(node, addr->offset);
546 if(addr->symconst_sign)
547 set_ia32_am_sc_sign(node);
549 set_ia32_use_frame(node);
550 set_ia32_frame_ent(node, addr->frame_entity);
554 * Apply attributes of a given address mode to a node.
556 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
558 set_address(node, &am->addr);
560 set_ia32_op_type(node, am->op_type);
561 set_ia32_ls_mode(node, am->ls_mode);
562 if (am->pinned == op_pin_state_pinned) {
563 /* beware: some nodes are already pinned and did not allow to change the state */
564 if (get_irn_pinned(node) != op_pin_state_pinned)
565 set_irn_pinned(node, op_pin_state_pinned);
568 set_ia32_commutative(node);
572 * Check, if a given node is a Down-Conv, ie. a integer Conv
573 * from a mode with a mode with more bits to a mode with lesser bits.
574 * Moreover, we return only true if the node has not more than 1 user.
576 * @param node the node
577 * @return non-zero if node is a Down-Conv
579 static int is_downconv(const ir_node *node)
587 /* we only want to skip the conv when we're the only user
588 * (not optimal but for now...)
590 if(get_irn_n_edges(node) > 1)
593 src_mode = get_irn_mode(get_Conv_op(node));
594 dest_mode = get_irn_mode(node);
595 return ia32_mode_needs_gp_reg(src_mode)
596 && ia32_mode_needs_gp_reg(dest_mode)
597 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
600 /* Skip all Down-Conv's on a given node and return the resulting node. */
601 ir_node *ia32_skip_downconv(ir_node *node) {
602 while (is_downconv(node))
603 node = get_Conv_op(node);
608 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
610 ir_mode *mode = get_irn_mode(node);
615 if(mode_is_signed(mode)) {
620 block = get_nodes_block(node);
621 dbgi = get_irn_dbg_info(node);
623 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
627 * matches operands of a node into ia32 addressing/operand modes. This covers
628 * usage of source address mode, immediates, operations with non 32-bit modes,
630 * The resulting data is filled into the @p am struct. block is the block
631 * of the node whose arguments are matched. op1, op2 are the first and second
632 * input that are matched (op1 may be NULL). other_op is another unrelated
633 * input that is not matched! but which is needed sometimes to check if AM
634 * for op1/op2 is legal.
635 * @p flags describes the supported modes of the operation in detail.
637 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
638 ir_node *op1, ir_node *op2, ir_node *other_op,
641 ia32_address_t *addr = &am->addr;
642 ir_mode *mode = get_irn_mode(op2);
643 int mode_bits = get_mode_size_bits(mode);
644 ir_node *noreg_gp, *new_op1, *new_op2;
646 unsigned commutative;
647 int use_am_and_immediates;
650 memset(am, 0, sizeof(am[0]));
652 commutative = (flags & match_commutative) != 0;
653 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
654 use_am = (flags & match_am) != 0;
655 use_immediate = (flags & match_immediate) != 0;
656 assert(!use_am_and_immediates || use_immediate);
659 assert(!commutative || op1 != NULL);
660 assert(use_am || !(flags & match_8bit_am));
661 assert(use_am || !(flags & match_16bit_am));
663 if (mode_bits == 8) {
664 if (!(flags & match_8bit_am))
666 /* we don't automatically add upconvs yet */
667 assert((flags & match_mode_neutral) || (flags & match_8bit));
668 } else if (mode_bits == 16) {
669 if (!(flags & match_16bit_am))
671 /* we don't automatically add upconvs yet */
672 assert((flags & match_mode_neutral) || (flags & match_16bit));
675 /* we can simply skip downconvs for mode neutral nodes: the upper bits
676 * can be random for these operations */
677 if (flags & match_mode_neutral) {
678 op2 = ia32_skip_downconv(op2);
680 op1 = ia32_skip_downconv(op1);
684 /* match immediates. firm nodes are normalized: constants are always on the
687 if (!(flags & match_try_am) && use_immediate) {
688 new_op2 = try_create_Immediate(op2, 0);
691 noreg_gp = ia32_new_NoReg_gp(env_cg);
692 if (new_op2 == NULL &&
693 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
694 build_address(am, op2);
695 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
696 if (mode_is_float(mode)) {
697 new_op2 = ia32_new_NoReg_vfp(env_cg);
701 am->op_type = ia32_AddrModeS;
702 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
704 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
706 build_address(am, op1);
708 if (mode_is_float(mode)) {
709 noreg = ia32_new_NoReg_vfp(env_cg);
714 if (new_op2 != NULL) {
717 new_op1 = be_transform_node(op2);
719 am->ins_permuted = 1;
721 am->op_type = ia32_AddrModeS;
723 am->op_type = ia32_Normal;
725 if (flags & match_try_am) {
731 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
733 new_op2 = be_transform_node(op2);
735 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
737 if (addr->base == NULL)
738 addr->base = noreg_gp;
739 if (addr->index == NULL)
740 addr->index = noreg_gp;
741 if (addr->mem == NULL)
742 addr->mem = new_NoMem();
744 am->new_op1 = new_op1;
745 am->new_op2 = new_op2;
746 am->commutative = commutative;
749 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
754 if (am->mem_proj == NULL)
757 /* we have to create a mode_T so the old MemProj can attach to us */
758 mode = get_irn_mode(node);
759 load = get_Proj_pred(am->mem_proj);
761 be_set_transformed_node(load, node);
763 if (mode != mode_T) {
764 set_irn_mode(node, mode_T);
765 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
772 * Construct a standard binary operation, set AM and immediate if required.
774 * @param node The original node for which the binop is created
775 * @param op1 The first operand
776 * @param op2 The second operand
777 * @param func The node constructor function
778 * @return The constructed ia32 node.
780 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
781 construct_binop_func *func, match_flags_t flags)
784 ir_node *block, *new_block, *new_node;
785 ia32_address_mode_t am;
786 ia32_address_t *addr = &am.addr;
788 block = get_nodes_block(node);
789 match_arguments(&am, block, op1, op2, NULL, flags);
791 dbgi = get_irn_dbg_info(node);
792 new_block = be_transform_node(block);
793 new_node = func(dbgi, current_ir_graph, new_block,
794 addr->base, addr->index, addr->mem,
795 am.new_op1, am.new_op2);
796 set_am_attributes(new_node, &am);
797 /* we can't use source address mode anymore when using immediates */
798 if (!(flags & match_am_and_immediates) &&
799 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
800 set_ia32_am_support(new_node, ia32_am_none);
801 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
803 new_node = fix_mem_proj(new_node, &am);
810 n_ia32_l_binop_right,
811 n_ia32_l_binop_eflags
813 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
814 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
815 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
816 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
817 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
818 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
821 * Construct a binary operation which also consumes the eflags.
823 * @param node The node to transform
824 * @param func The node constructor function
825 * @param flags The match flags
826 * @return The constructor ia32 node
828 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
831 ir_node *src_block = get_nodes_block(node);
832 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
833 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
834 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
836 ir_node *block, *new_node, *new_eflags;
837 ia32_address_mode_t am;
838 ia32_address_t *addr = &am.addr;
840 match_arguments(&am, src_block, op1, op2, eflags, flags);
842 dbgi = get_irn_dbg_info(node);
843 block = be_transform_node(src_block);
844 new_eflags = be_transform_node(eflags);
845 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
846 addr->mem, am.new_op1, am.new_op2, new_eflags);
847 set_am_attributes(new_node, &am);
848 /* we can't use source address mode anymore when using immediates */
849 if (!(flags & match_am_and_immediates) &&
850 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
851 set_ia32_am_support(new_node, ia32_am_none);
852 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
854 new_node = fix_mem_proj(new_node, &am);
859 static ir_node *get_fpcw(void)
862 if (initial_fpcw != NULL)
865 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
866 &ia32_fp_cw_regs[REG_FPCW]);
867 initial_fpcw = be_transform_node(fpcw);
873 * Construct a standard binary operation, set AM and immediate if required.
875 * @param op1 The first operand
876 * @param op2 The second operand
877 * @param func The node constructor function
878 * @return The constructed ia32 node.
880 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
881 construct_binop_float_func *func,
884 ir_mode *mode = get_irn_mode(node);
886 ir_node *block, *new_block, *new_node;
887 ia32_address_mode_t am;
888 ia32_address_t *addr = &am.addr;
890 /* cannot use address mode with long double on x87 */
891 if (get_mode_size_bits(mode) > 64)
894 block = get_nodes_block(node);
895 match_arguments(&am, block, op1, op2, NULL, flags);
897 dbgi = get_irn_dbg_info(node);
898 new_block = be_transform_node(block);
899 new_node = func(dbgi, current_ir_graph, new_block,
900 addr->base, addr->index, addr->mem,
901 am.new_op1, am.new_op2, get_fpcw());
902 set_am_attributes(new_node, &am);
904 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
906 new_node = fix_mem_proj(new_node, &am);
912 * Construct a shift/rotate binary operation, sets AM and immediate if required.
914 * @param op1 The first operand
915 * @param op2 The second operand
916 * @param func The node constructor function
917 * @return The constructed ia32 node.
919 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
920 construct_shift_func *func,
924 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
926 assert(! mode_is_float(get_irn_mode(node)));
927 assert(flags & match_immediate);
928 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
930 if (flags & match_mode_neutral) {
931 op1 = ia32_skip_downconv(op1);
932 new_op1 = be_transform_node(op1);
933 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
934 new_op1 = create_upconv(op1, node);
936 new_op1 = be_transform_node(op1);
939 /* the shift amount can be any mode that is bigger than 5 bits, since all
940 * other bits are ignored anyway */
941 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
942 ir_node *const op = get_Conv_op(op2);
943 if (mode_is_float(get_irn_mode(op)))
946 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
948 new_op2 = create_immediate_or_transform(op2, 0);
950 dbgi = get_irn_dbg_info(node);
951 block = get_nodes_block(node);
952 new_block = be_transform_node(block);
953 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
954 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
956 /* lowered shift instruction may have a dependency operand, handle it here */
957 if (get_irn_arity(node) == 3) {
958 /* we have a dependency */
959 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
960 add_irn_dep(new_node, new_dep);
968 * Construct a standard unary operation, set AM and immediate if required.
970 * @param op The operand
971 * @param func The node constructor function
972 * @return The constructed ia32 node.
974 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
978 ir_node *block, *new_block, *new_op, *new_node;
980 assert(flags == 0 || flags == match_mode_neutral);
981 if (flags & match_mode_neutral) {
982 op = ia32_skip_downconv(op);
985 new_op = be_transform_node(op);
986 dbgi = get_irn_dbg_info(node);
987 block = get_nodes_block(node);
988 new_block = be_transform_node(block);
989 new_node = func(dbgi, current_ir_graph, new_block, new_op);
991 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
996 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
997 ia32_address_t *addr)
999 ir_node *base, *index, *res;
1003 base = ia32_new_NoReg_gp(env_cg);
1005 base = be_transform_node(base);
1008 index = addr->index;
1009 if (index == NULL) {
1010 index = ia32_new_NoReg_gp(env_cg);
1012 index = be_transform_node(index);
1015 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1016 set_address(res, addr);
1022 * Returns non-zero if a given address mode has a symbolic or
1023 * numerical offset != 0.
1025 static int am_has_immediates(const ia32_address_t *addr)
1027 return addr->offset != 0 || addr->symconst_ent != NULL
1028 || addr->frame_entity || addr->use_frame;
1032 * Creates an ia32 Add.
1034 * @return the created ia32 Add node
1036 static ir_node *gen_Add(ir_node *node) {
1037 ir_mode *mode = get_irn_mode(node);
1038 ir_node *op1 = get_Add_left(node);
1039 ir_node *op2 = get_Add_right(node);
1041 ir_node *block, *new_block, *new_node, *add_immediate_op;
1042 ia32_address_t addr;
1043 ia32_address_mode_t am;
1045 if (mode_is_float(mode)) {
1046 if (ia32_cg_config.use_sse2)
1047 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1048 match_commutative | match_am);
1050 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1051 match_commutative | match_am);
1054 ia32_mark_non_am(node);
1056 op2 = ia32_skip_downconv(op2);
1057 op1 = ia32_skip_downconv(op1);
1061 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1062 * 1. Add with immediate -> Lea
1063 * 2. Add with possible source address mode -> Add
1064 * 3. Otherwise -> Lea
1066 memset(&addr, 0, sizeof(addr));
1067 ia32_create_address_mode(&addr, node, /*force=*/1);
1068 add_immediate_op = NULL;
1070 dbgi = get_irn_dbg_info(node);
1071 block = get_nodes_block(node);
1072 new_block = be_transform_node(block);
1075 if(addr.base == NULL && addr.index == NULL) {
1076 ir_graph *irg = current_ir_graph;
1077 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1078 addr.symconst_sign, addr.offset);
1079 be_dep_on_frame(new_node);
1080 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1083 /* add with immediate? */
1084 if(addr.index == NULL) {
1085 add_immediate_op = addr.base;
1086 } else if(addr.base == NULL && addr.scale == 0) {
1087 add_immediate_op = addr.index;
1090 if(add_immediate_op != NULL) {
1091 if(!am_has_immediates(&addr)) {
1092 #ifdef DEBUG_libfirm
1093 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1096 return be_transform_node(add_immediate_op);
1099 new_node = create_lea_from_address(dbgi, new_block, &addr);
1100 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1104 /* test if we can use source address mode */
1105 match_arguments(&am, block, op1, op2, NULL, match_commutative
1106 | match_mode_neutral | match_am | match_immediate | match_try_am);
1108 /* construct an Add with source address mode */
1109 if (am.op_type == ia32_AddrModeS) {
1110 ir_graph *irg = current_ir_graph;
1111 ia32_address_t *am_addr = &am.addr;
1112 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1113 am_addr->index, am_addr->mem, am.new_op1,
1115 set_am_attributes(new_node, &am);
1116 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1118 new_node = fix_mem_proj(new_node, &am);
1123 /* otherwise construct a lea */
1124 new_node = create_lea_from_address(dbgi, new_block, &addr);
1125 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1130 * Creates an ia32 Mul.
1132 * @return the created ia32 Mul node
1134 static ir_node *gen_Mul(ir_node *node) {
1135 ir_node *op1 = get_Mul_left(node);
1136 ir_node *op2 = get_Mul_right(node);
1137 ir_mode *mode = get_irn_mode(node);
1139 if (mode_is_float(mode)) {
1140 if (ia32_cg_config.use_sse2)
1141 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1142 match_commutative | match_am);
1144 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1145 match_commutative | match_am);
1147 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1148 match_commutative | match_am | match_mode_neutral |
1149 match_immediate | match_am_and_immediates);
1153 * Creates an ia32 Mulh.
1154 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1155 * this result while Mul returns the lower 32 bit.
1157 * @return the created ia32 Mulh node
1159 static ir_node *gen_Mulh(ir_node *node) {
1160 ir_node *block = get_nodes_block(node);
1161 ir_node *new_block = be_transform_node(block);
1162 dbg_info *dbgi = get_irn_dbg_info(node);
1163 ir_node *op1 = get_Mulh_left(node);
1164 ir_node *op2 = get_Mulh_right(node);
1165 ir_mode *mode = get_irn_mode(node);
1167 ir_node *proj_res_high;
1169 if (mode_is_signed(mode)) {
1170 new_node = gen_binop(node, op1, op2, new_rd_ia32_IMul1OP, match_commutative | match_am);
1171 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1172 mode_Iu, pn_ia32_IMul1OP_res_high);
1174 new_node = gen_binop(node, op1, op2, new_rd_ia32_Mul, match_commutative | match_am);
1175 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1176 mode_Iu, pn_ia32_Mul_res_high);
1178 return proj_res_high;
1182 * Creates an ia32 And.
1184 * @return The created ia32 And node
1186 static ir_node *gen_And(ir_node *node) {
1187 ir_node *op1 = get_And_left(node);
1188 ir_node *op2 = get_And_right(node);
1189 assert(! mode_is_float(get_irn_mode(node)));
1191 /* is it a zero extension? */
1192 if (is_Const(op2)) {
1193 tarval *tv = get_Const_tarval(op2);
1194 long v = get_tarval_long(tv);
1196 if (v == 0xFF || v == 0xFFFF) {
1197 dbg_info *dbgi = get_irn_dbg_info(node);
1198 ir_node *block = get_nodes_block(node);
1205 assert(v == 0xFFFF);
1208 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1213 return gen_binop(node, op1, op2, new_rd_ia32_And,
1214 match_commutative | match_mode_neutral | match_am
1221 * Creates an ia32 Or.
1223 * @return The created ia32 Or node
1225 static ir_node *gen_Or(ir_node *node) {
1226 ir_node *op1 = get_Or_left(node);
1227 ir_node *op2 = get_Or_right(node);
1229 assert (! mode_is_float(get_irn_mode(node)));
1230 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1231 | match_mode_neutral | match_am | match_immediate);
1237 * Creates an ia32 Eor.
1239 * @return The created ia32 Eor node
1241 static ir_node *gen_Eor(ir_node *node) {
1242 ir_node *op1 = get_Eor_left(node);
1243 ir_node *op2 = get_Eor_right(node);
1245 assert(! mode_is_float(get_irn_mode(node)));
1246 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1247 | match_mode_neutral | match_am | match_immediate);
1252 * Creates an ia32 Sub.
1254 * @return The created ia32 Sub node
1256 static ir_node *gen_Sub(ir_node *node) {
1257 ir_node *op1 = get_Sub_left(node);
1258 ir_node *op2 = get_Sub_right(node);
1259 ir_mode *mode = get_irn_mode(node);
1261 if (mode_is_float(mode)) {
1262 if (ia32_cg_config.use_sse2)
1263 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1265 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1269 if (is_Const(op2)) {
1270 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1274 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1275 | match_am | match_immediate);
1278 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1279 ir_node *const src_val,
1280 ir_node *const src_mem,
1281 ir_node *const am_mem)
1283 if (is_NoMem(am_mem)) {
1284 return be_transform_node(src_mem);
1285 } else if (is_Proj(src_val) &&
1287 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1288 /* avoid memory loop */
1290 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1291 ir_node *const ptr_pred = get_Proj_pred(src_val);
1292 int const arity = get_Sync_n_preds(src_mem);
1297 NEW_ARR_A(ir_node*, ins, arity + 1);
1299 for (i = arity - 1; i >= 0; --i) {
1300 ir_node *const pred = get_Sync_pred(src_mem, i);
1302 /* avoid memory loop */
1303 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1306 ins[n++] = be_transform_node(pred);
1311 return new_r_Sync(irg, block, n, ins);
1315 ins[0] = be_transform_node(src_mem);
1317 return new_r_Sync(irg, block, 2, ins);
1322 * Generates an ia32 DivMod with additional infrastructure for the
1323 * register allocator if needed.
1325 static ir_node *create_Div(ir_node *node)
1327 ir_graph *irg = current_ir_graph;
1328 dbg_info *dbgi = get_irn_dbg_info(node);
1329 ir_node *block = get_nodes_block(node);
1330 ir_node *new_block = be_transform_node(block);
1337 ir_node *sign_extension;
1338 ia32_address_mode_t am;
1339 ia32_address_t *addr = &am.addr;
1341 /* the upper bits have random contents for smaller modes */
1342 switch (get_irn_opcode(node)) {
1344 op1 = get_Div_left(node);
1345 op2 = get_Div_right(node);
1346 mem = get_Div_mem(node);
1347 mode = get_Div_resmode(node);
1350 op1 = get_Mod_left(node);
1351 op2 = get_Mod_right(node);
1352 mem = get_Mod_mem(node);
1353 mode = get_Mod_resmode(node);
1356 op1 = get_DivMod_left(node);
1357 op2 = get_DivMod_right(node);
1358 mem = get_DivMod_mem(node);
1359 mode = get_DivMod_resmode(node);
1362 panic("invalid divmod node %+F", node);
1365 match_arguments(&am, block, op1, op2, NULL, match_am);
1367 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1368 is the memory of the consumed address. We can have only the second op as address
1369 in Div nodes, so check only op2. */
1370 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1372 if (mode_is_signed(mode)) {
1373 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1374 be_dep_on_frame(produceval);
1375 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1378 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1379 addr->index, new_mem, am.new_op2,
1380 am.new_op1, sign_extension);
1382 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1383 be_dep_on_frame(sign_extension);
1385 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1386 addr->index, new_mem, am.new_op2,
1387 am.new_op1, sign_extension);
1390 set_irn_pinned(new_node, get_irn_pinned(node));
1392 set_am_attributes(new_node, &am);
1393 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1395 new_node = fix_mem_proj(new_node, &am);
1401 static ir_node *gen_Mod(ir_node *node) {
1402 return create_Div(node);
1405 static ir_node *gen_Div(ir_node *node) {
1406 return create_Div(node);
1409 static ir_node *gen_DivMod(ir_node *node) {
1410 return create_Div(node);
1416 * Creates an ia32 floating Div.
1418 * @return The created ia32 xDiv node
1420 static ir_node *gen_Quot(ir_node *node)
1422 ir_node *op1 = get_Quot_left(node);
1423 ir_node *op2 = get_Quot_right(node);
1425 if (ia32_cg_config.use_sse2) {
1426 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1428 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1434 * Creates an ia32 Shl.
1436 * @return The created ia32 Shl node
1438 static ir_node *gen_Shl(ir_node *node) {
1439 ir_node *left = get_Shl_left(node);
1440 ir_node *right = get_Shl_right(node);
1442 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1443 match_mode_neutral | match_immediate);
1447 * Creates an ia32 Shr.
1449 * @return The created ia32 Shr node
1451 static ir_node *gen_Shr(ir_node *node) {
1452 ir_node *left = get_Shr_left(node);
1453 ir_node *right = get_Shr_right(node);
1455 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1461 * Creates an ia32 Sar.
1463 * @return The created ia32 Shrs node
1465 static ir_node *gen_Shrs(ir_node *node) {
1466 ir_node *left = get_Shrs_left(node);
1467 ir_node *right = get_Shrs_right(node);
1468 ir_mode *mode = get_irn_mode(node);
1470 if(is_Const(right) && mode == mode_Is) {
1471 tarval *tv = get_Const_tarval(right);
1472 long val = get_tarval_long(tv);
1474 /* this is a sign extension */
1475 ir_graph *irg = current_ir_graph;
1476 dbg_info *dbgi = get_irn_dbg_info(node);
1477 ir_node *block = be_transform_node(get_nodes_block(node));
1479 ir_node *new_op = be_transform_node(op);
1480 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1482 be_dep_on_frame(pval);
1483 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1487 /* 8 or 16 bit sign extension? */
1488 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1489 ir_node *shl_left = get_Shl_left(left);
1490 ir_node *shl_right = get_Shl_right(left);
1491 if(is_Const(shl_right)) {
1492 tarval *tv1 = get_Const_tarval(right);
1493 tarval *tv2 = get_Const_tarval(shl_right);
1494 if(tv1 == tv2 && tarval_is_long(tv1)) {
1495 long val = get_tarval_long(tv1);
1496 if(val == 16 || val == 24) {
1497 dbg_info *dbgi = get_irn_dbg_info(node);
1498 ir_node *block = get_nodes_block(node);
1508 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1517 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1523 * Creates an ia32 Rol.
1525 * @param op1 The first operator
1526 * @param op2 The second operator
1527 * @return The created ia32 RotL node
1529 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1530 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1536 * Creates an ia32 Ror.
1537 * NOTE: There is no RotR with immediate because this would always be a RotL
1538 * "imm-mode_size_bits" which can be pre-calculated.
1540 * @param op1 The first operator
1541 * @param op2 The second operator
1542 * @return The created ia32 RotR node
1544 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1545 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1551 * Creates an ia32 RotR or RotL (depending on the found pattern).
1553 * @return The created ia32 RotL or RotR node
1555 static ir_node *gen_Rotl(ir_node *node) {
1556 ir_node *rotate = NULL;
1557 ir_node *op1 = get_Rotl_left(node);
1558 ir_node *op2 = get_Rotl_right(node);
1560 /* Firm has only RotL, so we are looking for a right (op2)
1561 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1562 that means we can create a RotR instead of an Add and a RotL */
1566 ir_node *left = get_Add_left(add);
1567 ir_node *right = get_Add_right(add);
1568 if (is_Const(right)) {
1569 tarval *tv = get_Const_tarval(right);
1570 ir_mode *mode = get_irn_mode(node);
1571 long bits = get_mode_size_bits(mode);
1573 if (is_Minus(left) &&
1574 tarval_is_long(tv) &&
1575 get_tarval_long(tv) == bits &&
1578 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1579 rotate = gen_Ror(node, op1, get_Minus_op(left));
1584 if (rotate == NULL) {
1585 rotate = gen_Rol(node, op1, op2);
1594 * Transforms a Minus node.
1596 * @return The created ia32 Minus node
1598 static ir_node *gen_Minus(ir_node *node)
1600 ir_node *op = get_Minus_op(node);
1601 ir_node *block = be_transform_node(get_nodes_block(node));
1602 ir_graph *irg = current_ir_graph;
1603 dbg_info *dbgi = get_irn_dbg_info(node);
1604 ir_mode *mode = get_irn_mode(node);
1609 if (mode_is_float(mode)) {
1610 ir_node *new_op = be_transform_node(op);
1611 if (ia32_cg_config.use_sse2) {
1612 /* TODO: non-optimal... if we have many xXors, then we should
1613 * rather create a load for the const and use that instead of
1614 * several AM nodes... */
1615 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1616 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1617 ir_node *nomem = new_rd_NoMem(irg);
1619 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1620 nomem, new_op, noreg_xmm);
1622 size = get_mode_size_bits(mode);
1623 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1625 set_ia32_am_sc(new_node, ent);
1626 set_ia32_op_type(new_node, ia32_AddrModeS);
1627 set_ia32_ls_mode(new_node, mode);
1629 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1632 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1635 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1641 * Transforms a Not node.
1643 * @return The created ia32 Not node
1645 static ir_node *gen_Not(ir_node *node) {
1646 ir_node *op = get_Not_op(node);
1648 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1649 assert (! mode_is_float(get_irn_mode(node)));
1651 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1657 * Transforms an Abs node.
1659 * @return The created ia32 Abs node
1661 static ir_node *gen_Abs(ir_node *node)
1663 ir_node *block = get_nodes_block(node);
1664 ir_node *new_block = be_transform_node(block);
1665 ir_node *op = get_Abs_op(node);
1666 ir_graph *irg = current_ir_graph;
1667 dbg_info *dbgi = get_irn_dbg_info(node);
1668 ir_mode *mode = get_irn_mode(node);
1669 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1670 ir_node *nomem = new_NoMem();
1676 if (mode_is_float(mode)) {
1677 new_op = be_transform_node(op);
1679 if (ia32_cg_config.use_sse2) {
1680 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1681 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1682 nomem, new_op, noreg_fp);
1684 size = get_mode_size_bits(mode);
1685 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1687 set_ia32_am_sc(new_node, ent);
1689 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1691 set_ia32_op_type(new_node, ia32_AddrModeS);
1692 set_ia32_ls_mode(new_node, mode);
1694 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1695 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1698 ir_node *xor, *pval, *sign_extension;
1700 if (get_mode_size_bits(mode) == 32) {
1701 new_op = be_transform_node(op);
1703 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1706 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1707 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1710 be_dep_on_frame(pval);
1711 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1713 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1714 nomem, new_op, sign_extension);
1715 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1717 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1718 nomem, xor, sign_extension);
1719 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1726 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1728 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1729 dbg_info *dbgi = get_irn_dbg_info(cmp);
1730 ir_node *block = get_nodes_block(cmp);
1731 ir_node *new_block = be_transform_node(block);
1732 ir_node *op1 = be_transform_node(x);
1733 ir_node *op2 = be_transform_node(n);
1735 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1739 * Transform a node returning a "flag" result.
1741 * @param node the node to transform
1742 * @param pnc_out the compare mode to use
1744 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1753 /* we have a Cmp as input */
1754 if (is_Proj(node)) {
1755 ir_node *pred = get_Proj_pred(node);
1757 pn_Cmp pnc = get_Proj_proj(node);
1758 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1759 ir_node *l = get_Cmp_left(pred);
1760 ir_node *r = get_Cmp_right(pred);
1762 ir_node *la = get_And_left(l);
1763 ir_node *ra = get_And_right(l);
1765 ir_node *c = get_Shl_left(la);
1766 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1767 /* (1 << n) & ra) */
1768 ir_node *n = get_Shl_right(la);
1769 flags = gen_bt(pred, ra, n);
1770 /* we must generate a Jc/Jnc jump */
1771 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1774 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1779 ir_node *c = get_Shl_left(ra);
1780 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1781 /* la & (1 << n)) */
1782 ir_node *n = get_Shl_right(ra);
1783 flags = gen_bt(pred, la, n);
1784 /* we must generate a Jc/Jnc jump */
1785 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1788 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1794 flags = be_transform_node(pred);
1800 /* a mode_b value, we have to compare it against 0 */
1801 dbgi = get_irn_dbg_info(node);
1802 new_block = be_transform_node(get_nodes_block(node));
1803 new_op = be_transform_node(node);
1804 noreg = ia32_new_NoReg_gp(env_cg);
1805 nomem = new_NoMem();
1806 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1807 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1808 *pnc_out = pn_Cmp_Lg;
1813 * Transforms a Load.
1815 * @return the created ia32 Load node
1817 static ir_node *gen_Load(ir_node *node) {
1818 ir_node *old_block = get_nodes_block(node);
1819 ir_node *block = be_transform_node(old_block);
1820 ir_node *ptr = get_Load_ptr(node);
1821 ir_node *mem = get_Load_mem(node);
1822 ir_node *new_mem = be_transform_node(mem);
1825 ir_graph *irg = current_ir_graph;
1826 dbg_info *dbgi = get_irn_dbg_info(node);
1827 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1828 ir_mode *mode = get_Load_mode(node);
1831 ia32_address_t addr;
1833 /* construct load address */
1834 memset(&addr, 0, sizeof(addr));
1835 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1842 base = be_transform_node(base);
1848 index = be_transform_node(index);
1851 if (mode_is_float(mode)) {
1852 if (ia32_cg_config.use_sse2) {
1853 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1855 res_mode = mode_xmm;
1857 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1859 res_mode = mode_vfp;
1862 assert(mode != mode_b);
1864 /* create a conv node with address mode for smaller modes */
1865 if(get_mode_size_bits(mode) < 32) {
1866 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1867 new_mem, noreg, mode);
1869 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1874 set_irn_pinned(new_node, get_irn_pinned(node));
1875 set_ia32_op_type(new_node, ia32_AddrModeS);
1876 set_ia32_ls_mode(new_node, mode);
1877 set_address(new_node, &addr);
1879 if(get_irn_pinned(node) == op_pin_state_floats) {
1880 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1883 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1885 be_dep_on_frame(new_node);
1889 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1890 ir_node *ptr, ir_node *other)
1897 /* we only use address mode if we're the only user of the load */
1898 if (get_irn_n_edges(node) > 1)
1901 load = get_Proj_pred(node);
1904 if (get_nodes_block(load) != block)
1907 /* store should have the same pointer as the load */
1908 if (get_Load_ptr(load) != ptr)
1911 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1912 if (other != NULL &&
1913 get_nodes_block(other) == block &&
1914 heights_reachable_in_block(heights, other, load)) {
1921 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
1922 ir_node *const pred = get_Sync_pred(mem, i);
1924 if (is_Proj(pred) && get_Proj_pred(pred) == load)
1927 if (get_nodes_block(pred) == block &&
1928 heights_reachable_in_block(heights, pred, load)) {
1933 /* Store should be attached to the load */
1934 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
1941 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1942 ir_node *mem, ir_node *ptr, ir_mode *mode,
1943 construct_binop_dest_func *func,
1944 construct_binop_dest_func *func8bit,
1945 match_flags_t flags)
1947 ir_node *src_block = get_nodes_block(node);
1949 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1950 ir_graph *irg = current_ir_graph;
1957 ia32_address_mode_t am;
1958 ia32_address_t *addr = &am.addr;
1959 memset(&am, 0, sizeof(am));
1961 assert(flags & match_dest_am);
1962 assert(flags & match_immediate); /* there is no destam node without... */
1963 commutative = (flags & match_commutative) != 0;
1965 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
1966 build_address(&am, op1);
1967 new_op = create_immediate_or_transform(op2, 0);
1968 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1969 build_address(&am, op2);
1970 new_op = create_immediate_or_transform(op1, 0);
1975 if(addr->base == NULL)
1976 addr->base = noreg_gp;
1977 if(addr->index == NULL)
1978 addr->index = noreg_gp;
1979 if(addr->mem == NULL)
1980 addr->mem = new_NoMem();
1982 dbgi = get_irn_dbg_info(node);
1983 block = be_transform_node(src_block);
1984 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
1986 if(get_mode_size_bits(mode) == 8) {
1987 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
1990 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
1993 set_address(new_node, addr);
1994 set_ia32_op_type(new_node, ia32_AddrModeD);
1995 set_ia32_ls_mode(new_node, mode);
1996 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1998 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
1999 mem_proj = be_transform_node(am.mem_proj);
2000 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2005 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2006 ir_node *ptr, ir_mode *mode,
2007 construct_unop_dest_func *func)
2009 ir_graph *irg = current_ir_graph;
2010 ir_node *src_block = get_nodes_block(node);
2016 ia32_address_mode_t am;
2017 ia32_address_t *addr = &am.addr;
2018 memset(&am, 0, sizeof(am));
2020 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2023 build_address(&am, op);
2025 dbgi = get_irn_dbg_info(node);
2026 block = be_transform_node(src_block);
2027 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2028 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2029 set_address(new_node, addr);
2030 set_ia32_op_type(new_node, ia32_AddrModeD);
2031 set_ia32_ls_mode(new_node, mode);
2032 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2034 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2035 mem_proj = be_transform_node(am.mem_proj);
2036 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2041 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2042 ir_mode *mode = get_irn_mode(node);
2043 ir_node *mux_true = get_Mux_true(node);
2044 ir_node *mux_false = get_Mux_false(node);
2055 ia32_address_t addr;
2057 if(get_mode_size_bits(mode) != 8)
2060 if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2062 } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2068 build_address_ptr(&addr, ptr, mem);
2070 irg = current_ir_graph;
2071 dbgi = get_irn_dbg_info(node);
2072 block = get_nodes_block(node);
2073 new_block = be_transform_node(block);
2074 cond = get_Mux_sel(node);
2075 flags = get_flags_node(cond, &pnc);
2076 new_mem = be_transform_node(mem);
2077 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2078 addr.index, addr.mem, flags, pnc, negated);
2079 set_address(new_node, &addr);
2080 set_ia32_op_type(new_node, ia32_AddrModeD);
2081 set_ia32_ls_mode(new_node, mode);
2082 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2087 static ir_node *try_create_dest_am(ir_node *node) {
2088 ir_node *val = get_Store_value(node);
2089 ir_node *mem = get_Store_mem(node);
2090 ir_node *ptr = get_Store_ptr(node);
2091 ir_mode *mode = get_irn_mode(val);
2092 unsigned bits = get_mode_size_bits(mode);
2097 /* handle only GP modes for now... */
2098 if(!ia32_mode_needs_gp_reg(mode))
2102 /* store must be the only user of the val node */
2103 if(get_irn_n_edges(val) > 1)
2105 /* skip pointless convs */
2107 ir_node *conv_op = get_Conv_op(val);
2108 ir_mode *pred_mode = get_irn_mode(conv_op);
2109 if (!ia32_mode_needs_gp_reg(pred_mode))
2111 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2119 /* value must be in the same block */
2120 if(get_nodes_block(node) != get_nodes_block(val))
2123 switch (get_irn_opcode(val)) {
2125 op1 = get_Add_left(val);
2126 op2 = get_Add_right(val);
2127 if(is_Const_1(op2)) {
2128 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2129 new_rd_ia32_IncMem);
2131 } else if(is_Const_Minus_1(op2)) {
2132 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2133 new_rd_ia32_DecMem);
2136 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2137 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2138 match_dest_am | match_commutative |
2142 op1 = get_Sub_left(val);
2143 op2 = get_Sub_right(val);
2144 if (is_Const(op2)) {
2145 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2147 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2148 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2149 match_dest_am | match_immediate |
2153 op1 = get_And_left(val);
2154 op2 = get_And_right(val);
2155 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2156 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2157 match_dest_am | match_commutative |
2161 op1 = get_Or_left(val);
2162 op2 = get_Or_right(val);
2163 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2164 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2165 match_dest_am | match_commutative |
2169 op1 = get_Eor_left(val);
2170 op2 = get_Eor_right(val);
2171 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2172 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2173 match_dest_am | match_commutative |
2177 op1 = get_Shl_left(val);
2178 op2 = get_Shl_right(val);
2179 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2180 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2181 match_dest_am | match_immediate);
2184 op1 = get_Shr_left(val);
2185 op2 = get_Shr_right(val);
2186 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2187 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2188 match_dest_am | match_immediate);
2191 op1 = get_Shrs_left(val);
2192 op2 = get_Shrs_right(val);
2193 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2194 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2195 match_dest_am | match_immediate);
2198 op1 = get_Rotl_left(val);
2199 op2 = get_Rotl_right(val);
2200 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2201 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2202 match_dest_am | match_immediate);
2204 /* TODO: match ROR patterns... */
2206 new_node = try_create_SetMem(val, ptr, mem);
2209 op1 = get_Minus_op(val);
2210 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2213 /* should be lowered already */
2214 assert(mode != mode_b);
2215 op1 = get_Not_op(val);
2216 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2222 if(new_node != NULL) {
2223 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2224 get_irn_pinned(node) == op_pin_state_pinned) {
2225 set_irn_pinned(new_node, op_pin_state_pinned);
2232 static int is_float_to_int_conv(const ir_node *node)
2234 ir_mode *mode = get_irn_mode(node);
2238 if (mode != mode_Is && mode != mode_Hs)
2243 conv_op = get_Conv_op(node);
2244 conv_mode = get_irn_mode(conv_op);
2246 if(!mode_is_float(conv_mode))
2253 * Transform a Store(floatConst).
2255 * @return the created ia32 Store node
2257 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2259 ir_mode *mode = get_irn_mode(cns);
2260 unsigned size = get_mode_size_bytes(mode);
2261 tarval *tv = get_Const_tarval(cns);
2262 ir_node *block = get_nodes_block(node);
2263 ir_node *new_block = be_transform_node(block);
2264 ir_node *ptr = get_Store_ptr(node);
2265 ir_node *mem = get_Store_mem(node);
2266 ir_graph *irg = current_ir_graph;
2267 dbg_info *dbgi = get_irn_dbg_info(node);
2271 ia32_address_t addr;
2273 assert(size % 4 == 0);
2276 build_address_ptr(&addr, ptr, mem);
2280 get_tarval_sub_bits(tv, ofs) |
2281 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2282 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2283 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2284 ir_node *imm = create_Immediate(NULL, 0, val);
2286 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2287 addr.index, addr.mem, imm);
2289 set_irn_pinned(new_node, get_irn_pinned(node));
2290 set_ia32_op_type(new_node, ia32_AddrModeD);
2291 set_ia32_ls_mode(new_node, mode_Iu);
2292 set_address(new_node, &addr);
2293 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2295 ins[i++] = new_node;
2300 } while (size != 0);
2302 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2306 * Generate a vfist or vfisttp instruction.
2308 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2309 ir_node *mem, ir_node *val, ir_node **fist)
2313 if (ia32_cg_config.use_fisttp) {
2314 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2315 if other users exists */
2316 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2317 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2318 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2319 be_new_Keep(reg_class, irg, block, 1, &value);
2321 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2324 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2327 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2333 * Transforms a normal Store.
2335 * @return the created ia32 Store node
2337 static ir_node *gen_normal_Store(ir_node *node)
2339 ir_node *val = get_Store_value(node);
2340 ir_mode *mode = get_irn_mode(val);
2341 ir_node *block = get_nodes_block(node);
2342 ir_node *new_block = be_transform_node(block);
2343 ir_node *ptr = get_Store_ptr(node);
2344 ir_node *mem = get_Store_mem(node);
2345 ir_graph *irg = current_ir_graph;
2346 dbg_info *dbgi = get_irn_dbg_info(node);
2347 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2348 ir_node *new_val, *new_node, *store;
2349 ia32_address_t addr;
2351 /* check for destination address mode */
2352 new_node = try_create_dest_am(node);
2353 if (new_node != NULL)
2356 /* construct store address */
2357 memset(&addr, 0, sizeof(addr));
2358 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2360 if (addr.base == NULL) {
2363 addr.base = be_transform_node(addr.base);
2366 if (addr.index == NULL) {
2369 addr.index = be_transform_node(addr.index);
2371 addr.mem = be_transform_node(mem);
2373 if (mode_is_float(mode)) {
2374 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2376 while (is_Conv(val) && mode == get_irn_mode(val)) {
2377 ir_node *op = get_Conv_op(val);
2378 if (!mode_is_float(get_irn_mode(op)))
2382 new_val = be_transform_node(val);
2383 if (ia32_cg_config.use_sse2) {
2384 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2385 addr.index, addr.mem, new_val);
2387 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2388 addr.index, addr.mem, new_val, mode);
2391 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2392 val = get_Conv_op(val);
2394 /* TODO: is this optimisation still necessary at all (middleend)? */
2395 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2396 while (is_Conv(val)) {
2397 ir_node *op = get_Conv_op(val);
2398 if (!mode_is_float(get_irn_mode(op)))
2400 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2404 new_val = be_transform_node(val);
2405 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2407 new_val = create_immediate_or_transform(val, 0);
2408 assert(mode != mode_b);
2410 if (get_mode_size_bits(mode) == 8) {
2411 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2412 addr.index, addr.mem, new_val);
2414 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2415 addr.index, addr.mem, new_val);
2420 set_irn_pinned(store, get_irn_pinned(node));
2421 set_ia32_op_type(store, ia32_AddrModeD);
2422 set_ia32_ls_mode(store, mode);
2424 set_address(store, &addr);
2425 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2431 * Transforms a Store.
2433 * @return the created ia32 Store node
2435 static ir_node *gen_Store(ir_node *node)
2437 ir_node *val = get_Store_value(node);
2438 ir_mode *mode = get_irn_mode(val);
2440 if (mode_is_float(mode) && is_Const(val)) {
2443 /* we are storing a floating point constant */
2444 if (ia32_cg_config.use_sse2) {
2445 transform = !is_simple_sse_Const(val);
2447 transform = !is_simple_x87_Const(val);
2450 return gen_float_const_Store(node, val);
2452 return gen_normal_Store(node);
2456 * Transforms a Switch.
2458 * @return the created ia32 SwitchJmp node
2460 static ir_node *create_Switch(ir_node *node)
2462 ir_graph *irg = current_ir_graph;
2463 dbg_info *dbgi = get_irn_dbg_info(node);
2464 ir_node *block = be_transform_node(get_nodes_block(node));
2465 ir_node *sel = get_Cond_selector(node);
2466 ir_node *new_sel = be_transform_node(sel);
2467 int switch_min = INT_MAX;
2468 int switch_max = INT_MIN;
2469 long default_pn = get_Cond_defaultProj(node);
2471 const ir_edge_t *edge;
2473 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2475 /* determine the smallest switch case value */
2476 foreach_out_edge(node, edge) {
2477 ir_node *proj = get_edge_src_irn(edge);
2478 long pn = get_Proj_proj(proj);
2479 if(pn == default_pn)
2488 if((unsigned) (switch_max - switch_min) > 256000) {
2489 panic("Size of switch %+F bigger than 256000", node);
2492 if (switch_min != 0) {
2493 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2495 /* if smallest switch case is not 0 we need an additional sub */
2496 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2497 add_ia32_am_offs_int(new_sel, -switch_min);
2498 set_ia32_op_type(new_sel, ia32_AddrModeS);
2500 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2503 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2504 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2510 * Transform a Cond node.
2512 static ir_node *gen_Cond(ir_node *node) {
2513 ir_node *block = get_nodes_block(node);
2514 ir_node *new_block = be_transform_node(block);
2515 ir_graph *irg = current_ir_graph;
2516 dbg_info *dbgi = get_irn_dbg_info(node);
2517 ir_node *sel = get_Cond_selector(node);
2518 ir_mode *sel_mode = get_irn_mode(sel);
2519 ir_node *flags = NULL;
2523 if (sel_mode != mode_b) {
2524 return create_Switch(node);
2527 /* we get flags from a Cmp */
2528 flags = get_flags_node(sel, &pnc);
2530 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2531 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2536 static ir_node *gen_be_Copy(ir_node *node)
2538 ir_node *new_node = be_duplicate_node(node);
2539 ir_mode *mode = get_irn_mode(new_node);
2541 if (ia32_mode_needs_gp_reg(mode)) {
2542 set_irn_mode(new_node, mode_Iu);
2548 static ir_node *create_Fucom(ir_node *node)
2550 ir_graph *irg = current_ir_graph;
2551 dbg_info *dbgi = get_irn_dbg_info(node);
2552 ir_node *block = get_nodes_block(node);
2553 ir_node *new_block = be_transform_node(block);
2554 ir_node *left = get_Cmp_left(node);
2555 ir_node *new_left = be_transform_node(left);
2556 ir_node *right = get_Cmp_right(node);
2560 if(ia32_cg_config.use_fucomi) {
2561 new_right = be_transform_node(right);
2562 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2564 set_ia32_commutative(new_node);
2565 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2567 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2568 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2571 new_right = be_transform_node(right);
2572 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2576 set_ia32_commutative(new_node);
2578 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2580 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2581 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2587 static ir_node *create_Ucomi(ir_node *node)
2589 ir_graph *irg = current_ir_graph;
2590 dbg_info *dbgi = get_irn_dbg_info(node);
2591 ir_node *src_block = get_nodes_block(node);
2592 ir_node *new_block = be_transform_node(src_block);
2593 ir_node *left = get_Cmp_left(node);
2594 ir_node *right = get_Cmp_right(node);
2596 ia32_address_mode_t am;
2597 ia32_address_t *addr = &am.addr;
2599 match_arguments(&am, src_block, left, right, NULL,
2600 match_commutative | match_am);
2602 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2603 addr->mem, am.new_op1, am.new_op2,
2605 set_am_attributes(new_node, &am);
2607 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2609 new_node = fix_mem_proj(new_node, &am);
2615 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2616 * to fold an and into a test node
2618 static bool can_fold_test_and(ir_node *node)
2620 const ir_edge_t *edge;
2622 /** we can only have eq and lg projs */
2623 foreach_out_edge(node, edge) {
2624 ir_node *proj = get_edge_src_irn(edge);
2625 pn_Cmp pnc = get_Proj_proj(proj);
2626 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2634 * returns true if it is assured, that the upper bits of a node are "clean"
2635 * which means for a 16 or 8 bit value, that the upper bits in the register
2636 * are 0 for unsigned and a copy of the last significant bit for signed
2639 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2641 assert(ia32_mode_needs_gp_reg(mode));
2642 if (get_mode_size_bits(mode) >= 32)
2645 if (is_Proj(transformed_node))
2646 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2648 if (is_ia32_Conv_I2I(transformed_node)
2649 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2650 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2651 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2653 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2659 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2660 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2661 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2662 const ia32_immediate_attr_t *attr
2663 = get_ia32_immediate_attr_const(right);
2664 if (attr->symconst == 0
2665 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2669 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2672 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2673 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2674 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2675 const ia32_immediate_attr_t *attr
2676 = get_ia32_immediate_attr_const(right);
2677 if (attr->symconst == 0
2678 && (unsigned) attr->offset
2679 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2686 /* TODO recurse on Or, Xor, ... if appropriate? */
2688 if (is_ia32_Immediate(transformed_node)
2689 || is_ia32_Const(transformed_node)) {
2690 const ia32_immediate_attr_t *attr
2691 = get_ia32_immediate_attr_const(transformed_node);
2692 if (mode_is_signed(mode)) {
2693 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2694 if (shifted == 0 || shifted == -1)
2697 unsigned long shifted = (unsigned long) attr->offset;
2698 shifted >>= get_mode_size_bits(mode);
2708 * Generate code for a Cmp.
2710 static ir_node *gen_Cmp(ir_node *node)
2712 ir_graph *irg = current_ir_graph;
2713 dbg_info *dbgi = get_irn_dbg_info(node);
2714 ir_node *block = get_nodes_block(node);
2715 ir_node *new_block = be_transform_node(block);
2716 ir_node *left = get_Cmp_left(node);
2717 ir_node *right = get_Cmp_right(node);
2718 ir_mode *cmp_mode = get_irn_mode(left);
2720 ia32_address_mode_t am;
2721 ia32_address_t *addr = &am.addr;
2724 if(mode_is_float(cmp_mode)) {
2725 if (ia32_cg_config.use_sse2) {
2726 return create_Ucomi(node);
2728 return create_Fucom(node);
2732 assert(ia32_mode_needs_gp_reg(cmp_mode));
2734 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2735 cmp_unsigned = !mode_is_signed(cmp_mode);
2736 if (is_Const_0(right) &&
2738 get_irn_n_edges(left) == 1 &&
2739 can_fold_test_and(node)) {
2740 /* Test(and_left, and_right) */
2741 ir_node *and_left = get_And_left(left);
2742 ir_node *and_right = get_And_right(left);
2744 /* matze: code here used mode instead of cmd_mode, I think it is always
2745 * the same as cmp_mode, but I leave this here to see if this is really
2748 assert(get_irn_mode(and_left) == cmp_mode);
2750 match_arguments(&am, block, and_left, and_right, NULL,
2752 match_am | match_8bit_am | match_16bit_am |
2753 match_am_and_immediates | match_immediate |
2754 match_8bit | match_16bit);
2756 /* use 32bit compare mode if possible since the opcode is smaller */
2757 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2758 upper_bits_clean(am.new_op2, cmp_mode)) {
2759 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2762 if (get_mode_size_bits(cmp_mode) == 8) {
2763 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2764 addr->index, addr->mem, am.new_op1,
2765 am.new_op2, am.ins_permuted,
2768 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2769 addr->index, addr->mem, am.new_op1,
2770 am.new_op2, am.ins_permuted,
2774 /* Cmp(left, right) */
2775 match_arguments(&am, block, left, right, NULL,
2776 match_commutative | match_am | match_8bit_am |
2777 match_16bit_am | match_am_and_immediates |
2778 match_immediate | match_8bit | match_16bit);
2779 /* use 32bit compare mode if possible since the opcode is smaller */
2780 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2781 upper_bits_clean(am.new_op2, cmp_mode)) {
2782 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2785 if (get_mode_size_bits(cmp_mode) == 8) {
2786 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2787 addr->index, addr->mem, am.new_op1,
2788 am.new_op2, am.ins_permuted,
2791 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2792 addr->index, addr->mem, am.new_op1,
2793 am.new_op2, am.ins_permuted, cmp_unsigned);
2796 set_am_attributes(new_node, &am);
2797 set_ia32_ls_mode(new_node, cmp_mode);
2799 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2801 new_node = fix_mem_proj(new_node, &am);
2806 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2809 ir_graph *irg = current_ir_graph;
2810 dbg_info *dbgi = get_irn_dbg_info(node);
2811 ir_node *block = get_nodes_block(node);
2812 ir_node *new_block = be_transform_node(block);
2813 ir_node *val_true = get_Mux_true(node);
2814 ir_node *val_false = get_Mux_false(node);
2816 match_flags_t match_flags;
2817 ia32_address_mode_t am;
2818 ia32_address_t *addr;
2820 assert(ia32_cg_config.use_cmov);
2821 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2825 match_flags = match_commutative | match_am | match_16bit_am |
2828 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2830 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2831 addr->mem, am.new_op1, am.new_op2, new_flags,
2832 am.ins_permuted, pnc);
2833 set_am_attributes(new_node, &am);
2835 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2837 new_node = fix_mem_proj(new_node, &am);
2843 * Creates a ia32 Setcc instruction.
2845 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2846 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2849 ir_graph *irg = current_ir_graph;
2850 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2851 ir_node *nomem = new_NoMem();
2852 ir_mode *mode = get_irn_mode(orig_node);
2855 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2856 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2858 /* we might need to conv the result up */
2859 if (get_mode_size_bits(mode) > 8) {
2860 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2861 nomem, new_node, mode_Bu);
2862 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2869 * Create instruction for an unsigned Difference or Zero.
2871 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2872 ir_graph *irg = current_ir_graph;
2873 ir_mode *mode = get_irn_mode(psi);
2874 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2877 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2878 match_mode_neutral | match_am | match_immediate | match_two_users);
2880 block = get_nodes_block(new_node);
2882 if (is_Proj(new_node)) {
2883 sub = get_Proj_pred(new_node);
2884 assert(is_ia32_Sub(sub));
2887 set_irn_mode(sub, mode_T);
2888 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2890 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2892 dbgi = get_irn_dbg_info(psi);
2893 noreg = ia32_new_NoReg_gp(env_cg);
2894 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2895 nomem = new_NoMem();
2896 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2898 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2899 set_ia32_commutative(new_node);
2904 * Transforms a Mux node into CMov.
2906 * @return The transformed node.
2908 static ir_node *gen_Mux(ir_node *node)
2910 dbg_info *dbgi = get_irn_dbg_info(node);
2911 ir_node *block = get_nodes_block(node);
2912 ir_node *new_block = be_transform_node(block);
2913 ir_node *mux_true = get_Mux_true(node);
2914 ir_node *mux_false = get_Mux_false(node);
2915 ir_node *cond = get_Mux_sel(node);
2916 ir_mode *mode = get_irn_mode(node);
2919 assert(get_irn_mode(cond) == mode_b);
2921 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2922 if (mode_is_float(mode)) {
2923 ir_node *cmp = get_Proj_pred(cond);
2924 ir_node *cmp_left = get_Cmp_left(cmp);
2925 ir_node *cmp_right = get_Cmp_right(cmp);
2926 pn_Cmp pnc = get_Proj_proj(cond);
2928 if (ia32_cg_config.use_sse2) {
2929 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2930 if (cmp_left == mux_true && cmp_right == mux_false) {
2931 /* Mux(a <= b, a, b) => MIN */
2932 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2933 match_commutative | match_am | match_two_users);
2934 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2935 /* Mux(a <= b, b, a) => MAX */
2936 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2937 match_commutative | match_am | match_two_users);
2939 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2940 if (cmp_left == mux_true && cmp_right == mux_false) {
2941 /* Mux(a >= b, a, b) => MAX */
2942 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2943 match_commutative | match_am | match_two_users);
2944 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2945 /* Mux(a >= b, b, a) => MIN */
2946 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2947 match_commutative | match_am | match_two_users);
2951 panic("cannot transform floating point Mux");
2957 assert(ia32_mode_needs_gp_reg(mode));
2959 if (is_Proj(cond)) {
2960 ir_node *cmp = get_Proj_pred(cond);
2962 ir_node *cmp_left = get_Cmp_left(cmp);
2963 ir_node *cmp_right = get_Cmp_right(cmp);
2964 pn_Cmp pnc = get_Proj_proj(cond);
2966 /* check for unsigned Doz first */
2967 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2968 is_Const_0(mux_false) && is_Sub(mux_true) &&
2969 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2970 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2971 return create_Doz(node, cmp_left, cmp_right);
2972 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2973 is_Const_0(mux_true) && is_Sub(mux_false) &&
2974 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2975 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2976 return create_Doz(node, cmp_left, cmp_right);
2981 flags = get_flags_node(cond, &pnc);
2983 if (is_Const(mux_true) && is_Const(mux_false)) {
2984 /* both are const, good */
2985 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2986 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2987 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2988 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2990 /* Not that simple. */
2995 new_node = create_CMov(node, cond, flags, pnc);
3003 * Create a conversion from x87 state register to general purpose.
3005 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3006 ir_node *block = be_transform_node(get_nodes_block(node));
3007 ir_node *op = get_Conv_op(node);
3008 ir_node *new_op = be_transform_node(op);
3009 ia32_code_gen_t *cg = env_cg;
3010 ir_graph *irg = current_ir_graph;
3011 dbg_info *dbgi = get_irn_dbg_info(node);
3012 ir_node *noreg = ia32_new_NoReg_gp(cg);
3013 ir_mode *mode = get_irn_mode(node);
3014 ir_node *fist, *load, *mem;
3016 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3017 set_irn_pinned(fist, op_pin_state_floats);
3018 set_ia32_use_frame(fist);
3019 set_ia32_op_type(fist, ia32_AddrModeD);
3021 assert(get_mode_size_bits(mode) <= 32);
3022 /* exception we can only store signed 32 bit integers, so for unsigned
3023 we store a 64bit (signed) integer and load the lower bits */
3024 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3025 set_ia32_ls_mode(fist, mode_Ls);
3027 set_ia32_ls_mode(fist, mode_Is);
3029 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3032 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3034 set_irn_pinned(load, op_pin_state_floats);
3035 set_ia32_use_frame(load);
3036 set_ia32_op_type(load, ia32_AddrModeS);
3037 set_ia32_ls_mode(load, mode_Is);
3038 if(get_ia32_ls_mode(fist) == mode_Ls) {
3039 ia32_attr_t *attr = get_ia32_attr(load);
3040 attr->data.need_64bit_stackent = 1;
3042 ia32_attr_t *attr = get_ia32_attr(load);
3043 attr->data.need_32bit_stackent = 1;
3045 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3047 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3051 * Creates a x87 strict Conv by placing a Store and a Load
3053 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3055 ir_node *block = get_nodes_block(node);
3056 ir_graph *irg = current_ir_graph;
3057 dbg_info *dbgi = get_irn_dbg_info(node);
3058 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3059 ir_node *nomem = new_NoMem();
3060 ir_node *frame = get_irg_frame(irg);
3061 ir_node *store, *load;
3064 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3066 set_ia32_use_frame(store);
3067 set_ia32_op_type(store, ia32_AddrModeD);
3068 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3070 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3072 set_ia32_use_frame(load);
3073 set_ia32_op_type(load, ia32_AddrModeS);
3074 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3076 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3081 * Create a conversion from general purpose to x87 register
3083 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3084 ir_node *src_block = get_nodes_block(node);
3085 ir_node *block = be_transform_node(src_block);
3086 ir_graph *irg = current_ir_graph;
3087 dbg_info *dbgi = get_irn_dbg_info(node);
3088 ir_node *op = get_Conv_op(node);
3089 ir_node *new_op = NULL;
3093 ir_mode *store_mode;
3099 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3100 if (src_mode == mode_Is || src_mode == mode_Hs) {
3101 ia32_address_mode_t am;
3103 match_arguments(&am, src_block, NULL, op, NULL,
3104 match_am | match_try_am | match_16bit | match_16bit_am);
3105 if (am.op_type == ia32_AddrModeS) {
3106 ia32_address_t *addr = &am.addr;
3108 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3109 addr->index, addr->mem);
3110 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3113 set_am_attributes(fild, &am);
3114 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3116 fix_mem_proj(fild, &am);
3121 if(new_op == NULL) {
3122 new_op = be_transform_node(op);
3125 noreg = ia32_new_NoReg_gp(env_cg);
3126 nomem = new_NoMem();
3127 mode = get_irn_mode(op);
3129 /* first convert to 32 bit signed if necessary */
3130 src_bits = get_mode_size_bits(src_mode);
3131 if (src_bits == 8) {
3132 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3134 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3136 } else if (src_bits < 32) {
3137 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3139 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3143 assert(get_mode_size_bits(mode) == 32);
3146 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3149 set_ia32_use_frame(store);
3150 set_ia32_op_type(store, ia32_AddrModeD);
3151 set_ia32_ls_mode(store, mode_Iu);
3153 /* exception for 32bit unsigned, do a 64bit spill+load */
3154 if(!mode_is_signed(mode)) {
3157 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3159 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3160 get_irg_frame(irg), noreg, nomem,
3163 set_ia32_use_frame(zero_store);
3164 set_ia32_op_type(zero_store, ia32_AddrModeD);
3165 add_ia32_am_offs_int(zero_store, 4);
3166 set_ia32_ls_mode(zero_store, mode_Iu);
3171 store = new_rd_Sync(dbgi, irg, block, 2, in);
3172 store_mode = mode_Ls;
3174 store_mode = mode_Is;
3178 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3180 set_ia32_use_frame(fild);
3181 set_ia32_op_type(fild, ia32_AddrModeS);
3182 set_ia32_ls_mode(fild, store_mode);
3184 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3190 * Create a conversion from one integer mode into another one
3192 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3193 dbg_info *dbgi, ir_node *block, ir_node *op,
3196 ir_graph *irg = current_ir_graph;
3197 int src_bits = get_mode_size_bits(src_mode);
3198 int tgt_bits = get_mode_size_bits(tgt_mode);
3199 ir_node *new_block = be_transform_node(block);
3201 ir_mode *smaller_mode;
3203 ia32_address_mode_t am;
3204 ia32_address_t *addr = &am.addr;
3207 if (src_bits < tgt_bits) {
3208 smaller_mode = src_mode;
3209 smaller_bits = src_bits;
3211 smaller_mode = tgt_mode;
3212 smaller_bits = tgt_bits;
3215 #ifdef DEBUG_libfirm
3217 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3222 match_arguments(&am, block, NULL, op, NULL,
3223 match_8bit | match_16bit |
3224 match_am | match_8bit_am | match_16bit_am);
3226 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3227 /* unnecessary conv. in theory it shouldn't have been AM */
3228 assert(is_ia32_NoReg_GP(addr->base));
3229 assert(is_ia32_NoReg_GP(addr->index));
3230 assert(is_NoMem(addr->mem));
3231 assert(am.addr.offset == 0);
3232 assert(am.addr.symconst_ent == NULL);
3236 if (smaller_bits == 8) {
3237 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3238 addr->index, addr->mem, am.new_op2,
3241 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3242 addr->index, addr->mem, am.new_op2,
3245 set_am_attributes(new_node, &am);
3246 /* match_arguments assume that out-mode = in-mode, this isn't true here
3248 set_ia32_ls_mode(new_node, smaller_mode);
3249 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3250 new_node = fix_mem_proj(new_node, &am);
3255 * Transforms a Conv node.
3257 * @return The created ia32 Conv node
3259 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 ir_graph *irg = current_ir_graph;
3265 dbg_info *dbgi = get_irn_dbg_info(node);
3266 ir_mode *src_mode = get_irn_mode(op);
3267 ir_mode *tgt_mode = get_irn_mode(node);
3268 int src_bits = get_mode_size_bits(src_mode);
3269 int tgt_bits = get_mode_size_bits(tgt_mode);
3270 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3271 ir_node *nomem = new_rd_NoMem(irg);
3272 ir_node *res = NULL;
3274 if (src_mode == mode_b) {
3275 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3276 /* nothing to do, we already model bools as 0/1 ints */
3277 return be_transform_node(op);
3280 if (src_mode == tgt_mode) {
3281 if (get_Conv_strict(node)) {
3282 if (ia32_cg_config.use_sse2) {
3283 /* when we are in SSE mode, we can kill all strict no-op conversion */
3284 return be_transform_node(op);
3287 /* this should be optimized already, but who knows... */
3288 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3289 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3290 return be_transform_node(op);
3294 if (mode_is_float(src_mode)) {
3295 new_op = be_transform_node(op);
3296 /* we convert from float ... */
3297 if (mode_is_float(tgt_mode)) {
3298 if(src_mode == mode_E && tgt_mode == mode_D
3299 && !get_Conv_strict(node)) {
3300 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3305 if (ia32_cg_config.use_sse2) {
3306 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3307 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3309 set_ia32_ls_mode(res, tgt_mode);
3311 if(get_Conv_strict(node)) {
3312 res = gen_x87_strict_conv(tgt_mode, new_op);
3313 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3316 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3321 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3322 if (ia32_cg_config.use_sse2) {
3323 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3325 set_ia32_ls_mode(res, src_mode);
3327 return gen_x87_fp_to_gp(node);
3331 /* we convert from int ... */
3332 if (mode_is_float(tgt_mode)) {
3334 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3335 if (ia32_cg_config.use_sse2) {
3336 new_op = be_transform_node(op);
3337 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3339 set_ia32_ls_mode(res, tgt_mode);
3341 res = gen_x87_gp_to_fp(node, src_mode);
3342 if(get_Conv_strict(node)) {
3343 /* The strict-Conv is only necessary, if the int mode has more bits
3344 * than the float mantissa */
3345 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3346 size_t float_mantissa;
3347 /* FIXME There is no way to get the mantissa size of a mode */
3348 switch (get_mode_size_bits(tgt_mode)) {
3349 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3350 case 64: float_mantissa = 52 + 1; break;
3352 case 96: float_mantissa = 64; break;
3353 default: float_mantissa = 0; break;
3355 if (float_mantissa < int_mantissa) {
3356 res = gen_x87_strict_conv(tgt_mode, res);
3357 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3362 } else if(tgt_mode == mode_b) {
3363 /* mode_b lowering already took care that we only have 0/1 values */
3364 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3365 src_mode, tgt_mode));
3366 return be_transform_node(op);
3369 if (src_bits == tgt_bits) {
3370 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3371 src_mode, tgt_mode));
3372 return be_transform_node(op);
3375 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3383 static ir_node *create_immediate_or_transform(ir_node *node,
3384 char immediate_constraint_type)
3386 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3387 if (new_node == NULL) {
3388 new_node = be_transform_node(node);
3394 * Transforms a FrameAddr into an ia32 Add.
3396 static ir_node *gen_be_FrameAddr(ir_node *node) {
3397 ir_node *block = be_transform_node(get_nodes_block(node));
3398 ir_node *op = be_get_FrameAddr_frame(node);
3399 ir_node *new_op = be_transform_node(op);
3400 ir_graph *irg = current_ir_graph;
3401 dbg_info *dbgi = get_irn_dbg_info(node);
3402 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3405 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3406 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3407 set_ia32_use_frame(new_node);
3409 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3415 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3417 static ir_node *gen_be_Return(ir_node *node) {
3418 ir_graph *irg = current_ir_graph;
3419 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3420 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3421 ir_entity *ent = get_irg_entity(irg);
3422 ir_type *tp = get_entity_type(ent);
3427 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3428 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3431 int pn_ret_val, pn_ret_mem, arity, i;
3433 assert(ret_val != NULL);
3434 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3435 return be_duplicate_node(node);
3438 res_type = get_method_res_type(tp, 0);
3440 if (! is_Primitive_type(res_type)) {
3441 return be_duplicate_node(node);
3444 mode = get_type_mode(res_type);
3445 if (! mode_is_float(mode)) {
3446 return be_duplicate_node(node);
3449 assert(get_method_n_ress(tp) == 1);
3451 pn_ret_val = get_Proj_proj(ret_val);
3452 pn_ret_mem = get_Proj_proj(ret_mem);
3454 /* get the Barrier */
3455 barrier = get_Proj_pred(ret_val);
3457 /* get result input of the Barrier */
3458 ret_val = get_irn_n(barrier, pn_ret_val);
3459 new_ret_val = be_transform_node(ret_val);
3461 /* get memory input of the Barrier */
3462 ret_mem = get_irn_n(barrier, pn_ret_mem);
3463 new_ret_mem = be_transform_node(ret_mem);
3465 frame = get_irg_frame(irg);
3467 dbgi = get_irn_dbg_info(barrier);
3468 block = be_transform_node(get_nodes_block(barrier));
3470 noreg = ia32_new_NoReg_gp(env_cg);
3472 /* store xmm0 onto stack */
3473 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3474 new_ret_mem, new_ret_val);
3475 set_ia32_ls_mode(sse_store, mode);
3476 set_ia32_op_type(sse_store, ia32_AddrModeD);
3477 set_ia32_use_frame(sse_store);
3479 /* load into x87 register */
3480 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3481 set_ia32_op_type(fld, ia32_AddrModeS);
3482 set_ia32_use_frame(fld);
3484 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3485 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3487 /* create a new barrier */
3488 arity = get_irn_arity(barrier);
3489 in = alloca(arity * sizeof(in[0]));
3490 for (i = 0; i < arity; ++i) {
3493 if (i == pn_ret_val) {
3495 } else if (i == pn_ret_mem) {
3498 ir_node *in = get_irn_n(barrier, i);
3499 new_in = be_transform_node(in);
3504 new_barrier = new_ir_node(dbgi, irg, block,
3505 get_irn_op(barrier), get_irn_mode(barrier),
3507 copy_node_attr(barrier, new_barrier);
3508 be_duplicate_deps(barrier, new_barrier);
3509 be_set_transformed_node(barrier, new_barrier);
3511 /* transform normally */
3512 return be_duplicate_node(node);
3516 * Transform a be_AddSP into an ia32_SubSP.
3518 static ir_node *gen_be_AddSP(ir_node *node)
3520 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3521 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3523 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3524 match_am | match_immediate);
3528 * Transform a be_SubSP into an ia32_AddSP
3530 static ir_node *gen_be_SubSP(ir_node *node)
3532 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3533 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3535 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3536 match_am | match_immediate);
3540 * Change some phi modes
3542 static ir_node *gen_Phi(ir_node *node) {
3543 ir_node *block = be_transform_node(get_nodes_block(node));
3544 ir_graph *irg = current_ir_graph;
3545 dbg_info *dbgi = get_irn_dbg_info(node);
3546 ir_mode *mode = get_irn_mode(node);
3549 if(ia32_mode_needs_gp_reg(mode)) {
3550 /* we shouldn't have any 64bit stuff around anymore */
3551 assert(get_mode_size_bits(mode) <= 32);
3552 /* all integer operations are on 32bit registers now */
3554 } else if(mode_is_float(mode)) {
3555 if (ia32_cg_config.use_sse2) {
3562 /* phi nodes allow loops, so we use the old arguments for now
3563 * and fix this later */
3564 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3565 get_irn_in(node) + 1);
3566 copy_node_attr(node, phi);
3567 be_duplicate_deps(node, phi);
3569 be_enqueue_preds(node);
3577 static ir_node *gen_IJmp(ir_node *node)
3579 ir_node *block = get_nodes_block(node);
3580 ir_node *new_block = be_transform_node(block);
3581 dbg_info *dbgi = get_irn_dbg_info(node);
3582 ir_node *op = get_IJmp_target(node);
3584 ia32_address_mode_t am;
3585 ia32_address_t *addr = &am.addr;
3587 assert(get_irn_mode(op) == mode_P);
3589 match_arguments(&am, block, NULL, op, NULL,
3590 match_am | match_8bit_am | match_16bit_am |
3591 match_immediate | match_8bit | match_16bit);
3593 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3594 addr->base, addr->index, addr->mem,
3596 set_am_attributes(new_node, &am);
3597 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3599 new_node = fix_mem_proj(new_node, &am);
3605 * Transform a Bound node.
3607 static ir_node *gen_Bound(ir_node *node)
3610 ir_node *lower = get_Bound_lower(node);
3611 dbg_info *dbgi = get_irn_dbg_info(node);
3613 if (is_Const_0(lower)) {
3614 /* typical case for Java */
3615 ir_node *sub, *res, *flags, *block;
3616 ir_graph *irg = current_ir_graph;
3618 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3619 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3621 block = get_nodes_block(res);
3622 if (! is_Proj(res)) {
3624 set_irn_mode(sub, mode_T);
3625 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3627 sub = get_Proj_pred(res);
3629 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3630 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3631 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3633 panic("generic Bound not supported in ia32 Backend");
3639 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3641 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3642 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3644 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3645 match_immediate | match_mode_neutral);
3648 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3650 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3651 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3652 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3656 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3658 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3659 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3660 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3664 static ir_node *gen_ia32_l_Add(ir_node *node) {
3665 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3666 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3667 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3668 match_commutative | match_am | match_immediate |
3669 match_mode_neutral);
3671 if(is_Proj(lowered)) {
3672 lowered = get_Proj_pred(lowered);
3674 assert(is_ia32_Add(lowered));
3675 set_irn_mode(lowered, mode_T);
3681 static ir_node *gen_ia32_l_Adc(ir_node *node)
3683 return gen_binop_flags(node, new_rd_ia32_Adc,
3684 match_commutative | match_am | match_immediate |
3685 match_mode_neutral);
3689 * Transforms a l_MulS into a "real" MulS node.
3691 * @return the created ia32 Mul node
3693 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3694 ir_node *left = get_binop_left(node);
3695 ir_node *right = get_binop_right(node);
3697 return gen_binop(node, left, right, new_rd_ia32_Mul,
3698 match_commutative | match_am | match_mode_neutral);
3702 * Transforms a l_IMulS into a "real" IMul1OPS node.
3704 * @return the created ia32 IMul1OP node
3706 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3707 ir_node *left = get_binop_left(node);
3708 ir_node *right = get_binop_right(node);
3710 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3711 match_commutative | match_am | match_mode_neutral);
3714 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3715 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3716 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3717 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3718 match_am | match_immediate | match_mode_neutral);
3720 if(is_Proj(lowered)) {
3721 lowered = get_Proj_pred(lowered);
3723 assert(is_ia32_Sub(lowered));
3724 set_irn_mode(lowered, mode_T);
3730 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3731 return gen_binop_flags(node, new_rd_ia32_Sbb,
3732 match_am | match_immediate | match_mode_neutral);
3736 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3737 * op1 - target to be shifted
3738 * op2 - contains bits to be shifted into target
3740 * Only op3 can be an immediate.
3742 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3743 ir_node *low, ir_node *count)
3745 ir_node *block = get_nodes_block(node);
3746 ir_node *new_block = be_transform_node(block);
3747 ir_graph *irg = current_ir_graph;
3748 dbg_info *dbgi = get_irn_dbg_info(node);
3749 ir_node *new_high = be_transform_node(high);
3750 ir_node *new_low = be_transform_node(low);
3754 /* the shift amount can be any mode that is bigger than 5 bits, since all
3755 * other bits are ignored anyway */
3756 while (is_Conv(count) &&
3757 get_irn_n_edges(count) == 1 &&
3758 mode_is_int(get_irn_mode(count))) {
3759 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3760 count = get_Conv_op(count);
3762 new_count = create_immediate_or_transform(count, 0);
3764 if (is_ia32_l_ShlD(node)) {
3765 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3768 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3771 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3776 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3778 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3779 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3780 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3781 return gen_lowered_64bit_shifts(node, high, low, count);
3784 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3786 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3787 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3788 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3789 return gen_lowered_64bit_shifts(node, high, low, count);
3792 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3793 ir_node *src_block = get_nodes_block(node);
3794 ir_node *block = be_transform_node(src_block);
3795 ir_graph *irg = current_ir_graph;
3796 dbg_info *dbgi = get_irn_dbg_info(node);
3797 ir_node *frame = get_irg_frame(irg);
3798 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3799 ir_node *nomem = new_NoMem();
3800 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3801 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3802 ir_node *new_val_low = be_transform_node(val_low);
3803 ir_node *new_val_high = be_transform_node(val_high);
3808 ir_node *store_high;
3810 if(!mode_is_signed(get_irn_mode(val_high))) {
3811 panic("unsigned long long -> float not supported yet (%+F)", node);
3815 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3817 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3819 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3820 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3822 set_ia32_use_frame(store_low);
3823 set_ia32_use_frame(store_high);
3824 set_ia32_op_type(store_low, ia32_AddrModeD);
3825 set_ia32_op_type(store_high, ia32_AddrModeD);
3826 set_ia32_ls_mode(store_low, mode_Iu);
3827 set_ia32_ls_mode(store_high, mode_Is);
3828 add_ia32_am_offs_int(store_high, 4);
3832 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3835 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3837 set_ia32_use_frame(fild);
3838 set_ia32_op_type(fild, ia32_AddrModeS);
3839 set_ia32_ls_mode(fild, mode_Ls);
3841 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3843 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3846 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3847 ir_node *src_block = get_nodes_block(node);
3848 ir_node *block = be_transform_node(src_block);
3849 ir_graph *irg = current_ir_graph;
3850 dbg_info *dbgi = get_irn_dbg_info(node);
3851 ir_node *frame = get_irg_frame(irg);
3852 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3853 ir_node *nomem = new_NoMem();
3854 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3855 ir_node *new_val = be_transform_node(val);
3856 ir_node *fist, *mem;
3858 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3859 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3860 set_ia32_use_frame(fist);
3861 set_ia32_op_type(fist, ia32_AddrModeD);
3862 set_ia32_ls_mode(fist, mode_Ls);
3868 * the BAD transformer.
3870 static ir_node *bad_transform(ir_node *node) {
3871 panic("No transform function for %+F available.", node);
3875 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
3876 ir_graph *irg = current_ir_graph;
3877 ir_node *block = be_transform_node(get_nodes_block(node));
3878 ir_node *pred = get_Proj_pred(node);
3879 ir_node *new_pred = be_transform_node(pred);
3880 ir_node *frame = get_irg_frame(irg);
3881 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3882 dbg_info *dbgi = get_irn_dbg_info(node);
3883 long pn = get_Proj_proj(node);
3888 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3889 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3890 set_ia32_use_frame(load);
3891 set_ia32_op_type(load, ia32_AddrModeS);
3892 set_ia32_ls_mode(load, mode_Iu);
3893 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3894 * 32 bit from it with this particular load */
3895 attr = get_ia32_attr(load);
3896 attr->data.need_64bit_stackent = 1;
3898 if (pn == pn_ia32_l_FloattoLL_res_high) {
3899 add_ia32_am_offs_int(load, 4);
3901 assert(pn == pn_ia32_l_FloattoLL_res_low);
3904 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3910 * Transform the Projs of an AddSP.
3912 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
3913 ir_node *block = be_transform_node(get_nodes_block(node));
3914 ir_node *pred = get_Proj_pred(node);
3915 ir_node *new_pred = be_transform_node(pred);
3916 ir_graph *irg = current_ir_graph;
3917 dbg_info *dbgi = get_irn_dbg_info(node);
3918 long proj = get_Proj_proj(node);
3920 if (proj == pn_be_AddSP_sp) {
3921 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3922 pn_ia32_SubSP_stack);
3923 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3925 } else if(proj == pn_be_AddSP_res) {
3926 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3927 pn_ia32_SubSP_addr);
3928 } else if (proj == pn_be_AddSP_M) {
3929 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3932 panic("No idea how to transform proj->AddSP");
3936 * Transform the Projs of a SubSP.
3938 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
3939 ir_node *block = be_transform_node(get_nodes_block(node));
3940 ir_node *pred = get_Proj_pred(node);
3941 ir_node *new_pred = be_transform_node(pred);
3942 ir_graph *irg = current_ir_graph;
3943 dbg_info *dbgi = get_irn_dbg_info(node);
3944 long proj = get_Proj_proj(node);
3946 if (proj == pn_be_SubSP_sp) {
3947 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3948 pn_ia32_AddSP_stack);
3949 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3951 } else if (proj == pn_be_SubSP_M) {
3952 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3955 panic("No idea how to transform proj->SubSP");
3959 * Transform and renumber the Projs from a Load.
3961 static ir_node *gen_Proj_Load(ir_node *node) {
3963 ir_node *block = be_transform_node(get_nodes_block(node));
3964 ir_node *pred = get_Proj_pred(node);
3965 ir_graph *irg = current_ir_graph;
3966 dbg_info *dbgi = get_irn_dbg_info(node);
3967 long proj = get_Proj_proj(node);
3969 /* loads might be part of source address mode matches, so we don't
3970 * transform the ProjMs yet (with the exception of loads whose result is
3973 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
3976 /* this is needed, because sometimes we have loops that are only
3977 reachable through the ProjM */
3978 be_enqueue_preds(node);
3979 /* do it in 2 steps, to silence firm verifier */
3980 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
3981 set_Proj_proj(res, pn_ia32_mem);
3985 /* renumber the proj */
3986 new_pred = be_transform_node(pred);
3987 if (is_ia32_Load(new_pred)) {
3990 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
3992 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
3993 case pn_Load_X_regular:
3994 return new_rd_Jmp(dbgi, irg, block);
3995 case pn_Load_X_except:
3996 /* This Load might raise an exception. Mark it. */
3997 set_ia32_exc_label(new_pred, 1);
3998 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4002 } else if (is_ia32_Conv_I2I(new_pred) ||
4003 is_ia32_Conv_I2I8Bit(new_pred)) {
4004 set_irn_mode(new_pred, mode_T);
4005 if (proj == pn_Load_res) {
4006 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4007 } else if (proj == pn_Load_M) {
4008 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4010 } else if (is_ia32_xLoad(new_pred)) {
4013 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4015 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4016 case pn_Load_X_regular:
4017 return new_rd_Jmp(dbgi, irg, block);
4018 case pn_Load_X_except:
4019 /* This Load might raise an exception. Mark it. */
4020 set_ia32_exc_label(new_pred, 1);
4021 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4025 } else if (is_ia32_vfld(new_pred)) {
4028 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4030 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4031 case pn_Load_X_regular:
4032 return new_rd_Jmp(dbgi, irg, block);
4033 case pn_Load_X_except:
4034 /* This Load might raise an exception. Mark it. */
4035 set_ia32_exc_label(new_pred, 1);
4036 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4041 /* can happen for ProJMs when source address mode happened for the
4044 /* however it should not be the result proj, as that would mean the
4045 load had multiple users and should not have been used for
4047 if (proj != pn_Load_M) {
4048 panic("internal error: transformed node not a Load");
4050 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4053 panic("No idea how to transform proj");
4057 * Transform and renumber the Projs from a DivMod like instruction.
4059 static ir_node *gen_Proj_DivMod(ir_node *node) {
4060 ir_node *block = be_transform_node(get_nodes_block(node));
4061 ir_node *pred = get_Proj_pred(node);
4062 ir_node *new_pred = be_transform_node(pred);
4063 ir_graph *irg = current_ir_graph;
4064 dbg_info *dbgi = get_irn_dbg_info(node);
4065 long proj = get_Proj_proj(node);
4067 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4069 switch (get_irn_opcode(pred)) {
4073 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4075 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4076 case pn_Div_X_regular:
4077 return new_rd_Jmp(dbgi, irg, block);
4078 case pn_Div_X_except:
4079 set_ia32_exc_label(new_pred, 1);
4080 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4088 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4090 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4091 case pn_Mod_X_except:
4092 set_ia32_exc_label(new_pred, 1);
4093 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4101 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4102 case pn_DivMod_res_div:
4103 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4104 case pn_DivMod_res_mod:
4105 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4106 case pn_DivMod_X_regular:
4107 return new_rd_Jmp(dbgi, irg, block);
4108 case pn_DivMod_X_except:
4109 set_ia32_exc_label(new_pred, 1);
4110 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4119 panic("No idea how to transform proj->DivMod");
4123 * Transform and renumber the Projs from a CopyB.
4125 static ir_node *gen_Proj_CopyB(ir_node *node) {
4126 ir_node *block = be_transform_node(get_nodes_block(node));
4127 ir_node *pred = get_Proj_pred(node);
4128 ir_node *new_pred = be_transform_node(pred);
4129 ir_graph *irg = current_ir_graph;
4130 dbg_info *dbgi = get_irn_dbg_info(node);
4131 long proj = get_Proj_proj(node);
4134 case pn_CopyB_M_regular:
4135 if (is_ia32_CopyB_i(new_pred)) {
4136 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4137 } else if (is_ia32_CopyB(new_pred)) {
4138 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4145 panic("No idea how to transform proj->CopyB");
4149 * Transform and renumber the Projs from a Quot.
4151 static ir_node *gen_Proj_Quot(ir_node *node) {
4152 ir_node *block = be_transform_node(get_nodes_block(node));
4153 ir_node *pred = get_Proj_pred(node);
4154 ir_node *new_pred = be_transform_node(pred);
4155 ir_graph *irg = current_ir_graph;
4156 dbg_info *dbgi = get_irn_dbg_info(node);
4157 long proj = get_Proj_proj(node);
4161 if (is_ia32_xDiv(new_pred)) {
4162 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4163 } else if (is_ia32_vfdiv(new_pred)) {
4164 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4168 if (is_ia32_xDiv(new_pred)) {
4169 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4170 } else if (is_ia32_vfdiv(new_pred)) {
4171 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4174 case pn_Quot_X_regular:
4175 case pn_Quot_X_except:
4180 panic("No idea how to transform proj->Quot");
4183 static ir_node *gen_be_Call(ir_node *node)
4185 dbg_info *const dbgi = get_irn_dbg_info(node);
4186 ir_graph *const irg = current_ir_graph;
4187 ir_node *const src_block = get_nodes_block(node);
4188 ir_node *const block = be_transform_node(src_block);
4189 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4190 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4191 ir_node *const sp = be_transform_node(src_sp);
4192 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4193 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4194 ia32_address_mode_t am;
4195 ia32_address_t *const addr = &am.addr;
4200 ir_node * eax = noreg;
4201 ir_node * ecx = noreg;
4202 ir_node * edx = noreg;
4203 unsigned const pop = be_Call_get_pop(node);
4204 ir_type *const call_tp = be_Call_get_type(node);
4206 /* Run the x87 simulator if the call returns a float value */
4207 if (get_method_n_ress(call_tp) > 0) {
4208 ir_type *const res_type = get_method_res_type(call_tp, 0);
4209 ir_mode *const res_mode = get_type_mode(res_type);
4211 if (res_mode != NULL && mode_is_float(res_mode)) {
4212 env_cg->do_x87_sim = 1;
4216 /* We do not want be_Call direct calls */
4217 assert(be_Call_get_entity(node) == NULL);
4219 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4220 match_am | match_immediate);
4222 i = get_irn_arity(node) - 1;
4223 fpcw = be_transform_node(get_irn_n(node, i--));
4224 for (; i >= be_pos_Call_first_arg; --i) {
4225 arch_register_req_t const *const req =
4226 arch_get_register_req(env_cg->arch_env, node, i);
4227 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4229 assert(req->type == arch_register_req_type_limited);
4230 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4232 switch (*req->limited) {
4233 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4234 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4235 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4236 default: panic("Invalid GP register for register parameter");
4240 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4241 call = new_rd_ia32_Call(dbgi, irg, block, addr->base, addr->index, mem,
4242 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4243 set_am_attributes(call, &am);
4244 call = fix_mem_proj(call, &am);
4246 if (get_irn_pinned(node) == op_pin_state_pinned)
4247 set_irn_pinned(call, op_pin_state_pinned);
4249 SET_IA32_ORIG_NODE(call, ia32_get_old_node_name(env_cg, node));
4253 static ir_node *gen_be_IncSP(ir_node *node) {
4254 ir_node *res = be_duplicate_node(node);
4255 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4261 * Transform the Projs from a be_Call.
4263 static ir_node *gen_Proj_be_Call(ir_node *node)
4265 ir_node *block = be_transform_node(get_nodes_block(node));
4266 ir_node *call = get_Proj_pred(node);
4267 ir_node *new_call = be_transform_node(call);
4268 ir_graph *irg = current_ir_graph;
4269 dbg_info *dbgi = get_irn_dbg_info(node);
4270 ir_type *method_type = be_Call_get_type(call);
4271 int n_res = get_method_n_ress(method_type);
4272 long proj = get_Proj_proj(node);
4273 ir_mode *mode = get_irn_mode(node);
4275 const arch_register_class_t *cls;
4278 /* The following is kinda tricky: If we're using SSE, then we have to
4279 * move the result value of the call in floating point registers to an
4280 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4281 * after the call, we have to make sure to correctly make the
4282 * MemProj and the result Proj use these 2 nodes
4284 if (proj == pn_be_Call_M_regular) {
4285 // get new node for result, are we doing the sse load/store hack?
4286 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4287 ir_node *call_res_new;
4288 ir_node *call_res_pred = NULL;
4290 if (call_res != NULL) {
4291 call_res_new = be_transform_node(call_res);
4292 call_res_pred = get_Proj_pred(call_res_new);
4295 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4296 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4299 assert(is_ia32_xLoad(call_res_pred));
4300 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4304 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4305 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4307 ir_node *frame = get_irg_frame(irg);
4308 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4310 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4313 /* in case there is no memory output: create one to serialize the copy
4315 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4316 pn_be_Call_M_regular);
4317 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4318 pn_be_Call_first_res);
4320 /* store st(0) onto stack */
4321 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4323 set_ia32_op_type(fstp, ia32_AddrModeD);
4324 set_ia32_use_frame(fstp);
4326 /* load into SSE register */
4327 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4329 set_ia32_op_type(sse_load, ia32_AddrModeS);
4330 set_ia32_use_frame(sse_load);
4332 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4338 /* transform call modes */
4339 if (mode_is_data(mode)) {
4340 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4344 /* Map from be_Call to ia32_Call proj number */
4345 if (proj == pn_be_Call_sp) {
4346 proj = pn_ia32_Call_stack;
4347 } else if (proj == pn_be_Call_M_regular) {
4348 proj = pn_ia32_Call_M;
4350 arch_register_req_t const *const req = arch_get_register_req(env_cg->arch_env, node, BE_OUT_POS(proj));
4351 int const n_outs = get_ia32_n_res(new_call);
4354 assert(proj >= pn_be_Call_first_res);
4355 assert(req->type == arch_register_req_type_limited);
4357 for (i = 0; i < n_outs; ++i) {
4358 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4360 if (new_req->type != arch_register_req_type_limited ||
4361 new_req->cls != req->cls ||
4362 *new_req->limited != *req->limited)
4371 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4373 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4375 case pn_ia32_Call_stack:
4376 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4379 case pn_ia32_Call_fpcw:
4380 arch_set_irn_register(env_cg->arch_env, res, &ia32_fp_cw_regs[REG_FPCW]);
4388 * Transform the Projs from a Cmp.
4390 static ir_node *gen_Proj_Cmp(ir_node *node)
4392 /* this probably means not all mode_b nodes were lowered... */
4393 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4398 * Transform the Projs from a Bound.
4400 static ir_node *gen_Proj_Bound(ir_node *node)
4402 ir_node *new_node, *block;
4403 ir_node *pred = get_Proj_pred(node);
4405 switch (get_Proj_proj(node)) {
4407 return be_transform_node(get_Bound_mem(pred));
4408 case pn_Bound_X_regular:
4409 new_node = be_transform_node(pred);
4410 block = get_nodes_block(new_node);
4411 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4412 case pn_Bound_X_except:
4413 new_node = be_transform_node(pred);
4414 block = get_nodes_block(new_node);
4415 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4417 return be_transform_node(get_Bound_index(pred));
4419 panic("unsupported Proj from Bound");
4423 static ir_node *gen_Proj_ASM(ir_node *node)
4429 if (get_irn_mode(node) != mode_M)
4430 return be_duplicate_node(node);
4432 pred = get_Proj_pred(node);
4433 new_pred = be_transform_node(pred);
4434 block = get_nodes_block(new_pred);
4435 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4436 get_ia32_n_res(new_pred) + 1);
4440 * Transform and potentially renumber Proj nodes.
4442 static ir_node *gen_Proj(ir_node *node) {
4443 ir_node *pred = get_Proj_pred(node);
4446 switch (get_irn_opcode(pred)) {
4448 proj = get_Proj_proj(node);
4449 if (proj == pn_Store_M) {
4450 return be_transform_node(pred);
4452 panic("No idea how to transform proj->Store");
4455 return gen_Proj_Load(node);
4457 return gen_Proj_ASM(node);
4461 return gen_Proj_DivMod(node);
4463 return gen_Proj_CopyB(node);
4465 return gen_Proj_Quot(node);
4467 return gen_Proj_be_SubSP(node);
4469 return gen_Proj_be_AddSP(node);
4471 return gen_Proj_be_Call(node);
4473 return gen_Proj_Cmp(node);
4475 return gen_Proj_Bound(node);
4477 proj = get_Proj_proj(node);
4479 case pn_Start_X_initial_exec: {
4480 ir_node *block = get_nodes_block(pred);
4481 ir_node *new_block = be_transform_node(block);
4482 dbg_info *dbgi = get_irn_dbg_info(node);
4483 /* we exchange the ProjX with a jump */
4484 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4489 case pn_Start_P_tls:
4490 return gen_Proj_tls(node);
4495 if (is_ia32_l_FloattoLL(pred)) {
4496 return gen_Proj_l_FloattoLL(node);
4498 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4502 ir_mode *mode = get_irn_mode(node);
4503 if (ia32_mode_needs_gp_reg(mode)) {
4504 ir_node *new_pred = be_transform_node(pred);
4505 ir_node *block = be_transform_node(get_nodes_block(node));
4506 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4507 mode_Iu, get_Proj_proj(node));
4508 #ifdef DEBUG_libfirm
4509 new_proj->node_nr = node->node_nr;
4515 return be_duplicate_node(node);
4519 * Enters all transform functions into the generic pointer
4521 static void register_transformers(void)
4525 /* first clear the generic function pointer for all ops */
4526 clear_irp_opcodes_generic_func();
4528 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4529 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4567 /* transform ops from intrinsic lowering */
4579 GEN(ia32_l_LLtoFloat);
4580 GEN(ia32_l_FloattoLL);
4586 /* we should never see these nodes */
4601 /* handle generic backend nodes */
4610 op_Mulh = get_op_Mulh();
4619 * Pre-transform all unknown and noreg nodes.
4621 static void ia32_pretransform_node(void)
4623 ia32_code_gen_t *cg = env_cg;
4625 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4626 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4627 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4628 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4629 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4630 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4635 * Walker, checks if all ia32 nodes producing more than one result have their
4636 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4638 static void add_missing_keep_walker(ir_node *node, void *data)
4641 unsigned found_projs = 0;
4642 const ir_edge_t *edge;
4643 ir_mode *mode = get_irn_mode(node);
4648 if(!is_ia32_irn(node))
4651 n_outs = get_ia32_n_res(node);
4654 if(is_ia32_SwitchJmp(node))
4657 assert(n_outs < (int) sizeof(unsigned) * 8);
4658 foreach_out_edge(node, edge) {
4659 ir_node *proj = get_edge_src_irn(edge);
4662 /* The node could be kept */
4666 if (get_irn_mode(proj) == mode_M)
4669 pn = get_Proj_proj(proj);
4670 assert(pn < n_outs);
4671 found_projs |= 1 << pn;
4675 /* are keeps missing? */
4677 for(i = 0; i < n_outs; ++i) {
4680 const arch_register_req_t *req;
4681 const arch_register_class_t *cls;
4683 if(found_projs & (1 << i)) {
4687 req = get_ia32_out_req(node, i);
4692 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4696 block = get_nodes_block(node);
4697 in[0] = new_r_Proj(current_ir_graph, block, node,
4698 arch_register_class_mode(cls), i);
4699 if(last_keep != NULL) {
4700 be_Keep_add_node(last_keep, cls, in[0]);
4702 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4703 if(sched_is_scheduled(node)) {
4704 sched_add_after(node, last_keep);
4711 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4714 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4716 ir_graph *irg = be_get_birg_irg(cg->birg);
4717 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4720 /* do the transformation */
4721 void ia32_transform_graph(ia32_code_gen_t *cg)
4725 register_transformers();
4727 initial_fpcw = NULL;
4729 BE_TIMER_PUSH(t_heights);
4730 heights = heights_new(cg->irg);
4731 BE_TIMER_POP(t_heights);
4732 ia32_calculate_non_address_mode_nodes(cg->birg);
4734 /* the transform phase is not safe for CSE (yet) because several nodes get
4735 * attributes set after their creation */
4736 cse_last = get_opt_cse();
4739 be_transform_graph(cg->birg, ia32_pretransform_node);
4741 set_opt_cse(cse_last);
4743 ia32_free_non_address_mode_nodes();
4744 heights_free(heights);
4748 void ia32_init_transform(void)
4750 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");