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)
883 ir_mode *mode = get_irn_mode(node);
885 ir_node *block, *new_block, *new_node;
886 ia32_address_mode_t am;
887 ia32_address_t *addr = &am.addr;
888 ia32_x87_attr_t *attr;
889 /* All operations are considered commutative, because there are reverse
891 match_flags_t flags = match_commutative;
893 /* cannot use address mode with long double on x87 */
894 if (get_mode_size_bits(mode) <= 64)
897 block = get_nodes_block(node);
898 match_arguments(&am, block, op1, op2, NULL, flags);
900 dbgi = get_irn_dbg_info(node);
901 new_block = be_transform_node(block);
902 new_node = func(dbgi, current_ir_graph, new_block,
903 addr->base, addr->index, addr->mem,
904 am.new_op1, am.new_op2, get_fpcw());
905 set_am_attributes(new_node, &am);
907 attr = get_ia32_x87_attr(new_node);
908 attr->attr.data.ins_permuted = am.ins_permuted;
910 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
912 new_node = fix_mem_proj(new_node, &am);
918 * Construct a shift/rotate binary operation, sets AM and immediate if required.
920 * @param op1 The first operand
921 * @param op2 The second operand
922 * @param func The node constructor function
923 * @return The constructed ia32 node.
925 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
926 construct_shift_func *func,
930 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
932 assert(! mode_is_float(get_irn_mode(node)));
933 assert(flags & match_immediate);
934 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
936 if (flags & match_mode_neutral) {
937 op1 = ia32_skip_downconv(op1);
938 new_op1 = be_transform_node(op1);
939 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
940 new_op1 = create_upconv(op1, node);
942 new_op1 = be_transform_node(op1);
945 /* the shift amount can be any mode that is bigger than 5 bits, since all
946 * other bits are ignored anyway */
947 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
948 ir_node *const op = get_Conv_op(op2);
949 if (mode_is_float(get_irn_mode(op)))
952 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
954 new_op2 = create_immediate_or_transform(op2, 0);
956 dbgi = get_irn_dbg_info(node);
957 block = get_nodes_block(node);
958 new_block = be_transform_node(block);
959 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
960 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
962 /* lowered shift instruction may have a dependency operand, handle it here */
963 if (get_irn_arity(node) == 3) {
964 /* we have a dependency */
965 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
966 add_irn_dep(new_node, new_dep);
974 * Construct a standard unary operation, set AM and immediate if required.
976 * @param op The operand
977 * @param func The node constructor function
978 * @return The constructed ia32 node.
980 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
984 ir_node *block, *new_block, *new_op, *new_node;
986 assert(flags == 0 || flags == match_mode_neutral);
987 if (flags & match_mode_neutral) {
988 op = ia32_skip_downconv(op);
991 new_op = be_transform_node(op);
992 dbgi = get_irn_dbg_info(node);
993 block = get_nodes_block(node);
994 new_block = be_transform_node(block);
995 new_node = func(dbgi, current_ir_graph, new_block, new_op);
997 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1002 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1003 ia32_address_t *addr)
1005 ir_node *base, *index, *res;
1009 base = ia32_new_NoReg_gp(env_cg);
1011 base = be_transform_node(base);
1014 index = addr->index;
1015 if (index == NULL) {
1016 index = ia32_new_NoReg_gp(env_cg);
1018 index = be_transform_node(index);
1021 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1022 set_address(res, addr);
1028 * Returns non-zero if a given address mode has a symbolic or
1029 * numerical offset != 0.
1031 static int am_has_immediates(const ia32_address_t *addr)
1033 return addr->offset != 0 || addr->symconst_ent != NULL
1034 || addr->frame_entity || addr->use_frame;
1038 * Creates an ia32 Add.
1040 * @return the created ia32 Add node
1042 static ir_node *gen_Add(ir_node *node) {
1043 ir_mode *mode = get_irn_mode(node);
1044 ir_node *op1 = get_Add_left(node);
1045 ir_node *op2 = get_Add_right(node);
1047 ir_node *block, *new_block, *new_node, *add_immediate_op;
1048 ia32_address_t addr;
1049 ia32_address_mode_t am;
1051 if (mode_is_float(mode)) {
1052 if (ia32_cg_config.use_sse2)
1053 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1054 match_commutative | match_am);
1056 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd);
1059 ia32_mark_non_am(node);
1061 op2 = ia32_skip_downconv(op2);
1062 op1 = ia32_skip_downconv(op1);
1066 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1067 * 1. Add with immediate -> Lea
1068 * 2. Add with possible source address mode -> Add
1069 * 3. Otherwise -> Lea
1071 memset(&addr, 0, sizeof(addr));
1072 ia32_create_address_mode(&addr, node, /*force=*/1);
1073 add_immediate_op = NULL;
1075 dbgi = get_irn_dbg_info(node);
1076 block = get_nodes_block(node);
1077 new_block = be_transform_node(block);
1080 if(addr.base == NULL && addr.index == NULL) {
1081 ir_graph *irg = current_ir_graph;
1082 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1083 addr.symconst_sign, addr.offset);
1084 be_dep_on_frame(new_node);
1085 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1088 /* add with immediate? */
1089 if(addr.index == NULL) {
1090 add_immediate_op = addr.base;
1091 } else if(addr.base == NULL && addr.scale == 0) {
1092 add_immediate_op = addr.index;
1095 if(add_immediate_op != NULL) {
1096 if(!am_has_immediates(&addr)) {
1097 #ifdef DEBUG_libfirm
1098 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1101 return be_transform_node(add_immediate_op);
1104 new_node = create_lea_from_address(dbgi, new_block, &addr);
1105 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1109 /* test if we can use source address mode */
1110 match_arguments(&am, block, op1, op2, NULL, match_commutative
1111 | match_mode_neutral | match_am | match_immediate | match_try_am);
1113 /* construct an Add with source address mode */
1114 if (am.op_type == ia32_AddrModeS) {
1115 ir_graph *irg = current_ir_graph;
1116 ia32_address_t *am_addr = &am.addr;
1117 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1118 am_addr->index, am_addr->mem, am.new_op1,
1120 set_am_attributes(new_node, &am);
1121 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1123 new_node = fix_mem_proj(new_node, &am);
1128 /* otherwise construct a lea */
1129 new_node = create_lea_from_address(dbgi, new_block, &addr);
1130 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1135 * Creates an ia32 Mul.
1137 * @return the created ia32 Mul node
1139 static ir_node *gen_Mul(ir_node *node) {
1140 ir_node *op1 = get_Mul_left(node);
1141 ir_node *op2 = get_Mul_right(node);
1142 ir_mode *mode = get_irn_mode(node);
1144 if (mode_is_float(mode)) {
1145 if (ia32_cg_config.use_sse2)
1146 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1147 match_commutative | match_am);
1149 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul);
1151 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1152 match_commutative | match_am | match_mode_neutral |
1153 match_immediate | match_am_and_immediates);
1157 * Creates an ia32 Mulh.
1158 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1159 * this result while Mul returns the lower 32 bit.
1161 * @return the created ia32 Mulh node
1163 static ir_node *gen_Mulh(ir_node *node) {
1164 ir_node *block = get_nodes_block(node);
1165 ir_node *new_block = be_transform_node(block);
1166 dbg_info *dbgi = get_irn_dbg_info(node);
1167 ir_node *op1 = get_Mulh_left(node);
1168 ir_node *op2 = get_Mulh_right(node);
1169 ir_mode *mode = get_irn_mode(node);
1171 ir_node *proj_res_high;
1173 if (mode_is_signed(mode)) {
1174 new_node = gen_binop(node, op1, op2, new_rd_ia32_IMul1OP, match_commutative | match_am);
1175 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1176 mode_Iu, pn_ia32_IMul1OP_res_high);
1178 new_node = gen_binop(node, op1, op2, new_rd_ia32_Mul, match_commutative | match_am);
1179 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1180 mode_Iu, pn_ia32_Mul_res_high);
1182 return proj_res_high;
1186 * Creates an ia32 And.
1188 * @return The created ia32 And node
1190 static ir_node *gen_And(ir_node *node) {
1191 ir_node *op1 = get_And_left(node);
1192 ir_node *op2 = get_And_right(node);
1193 assert(! mode_is_float(get_irn_mode(node)));
1195 /* is it a zero extension? */
1196 if (is_Const(op2)) {
1197 tarval *tv = get_Const_tarval(op2);
1198 long v = get_tarval_long(tv);
1200 if (v == 0xFF || v == 0xFFFF) {
1201 dbg_info *dbgi = get_irn_dbg_info(node);
1202 ir_node *block = get_nodes_block(node);
1209 assert(v == 0xFFFF);
1212 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1217 return gen_binop(node, op1, op2, new_rd_ia32_And,
1218 match_commutative | match_mode_neutral | match_am
1225 * Creates an ia32 Or.
1227 * @return The created ia32 Or node
1229 static ir_node *gen_Or(ir_node *node) {
1230 ir_node *op1 = get_Or_left(node);
1231 ir_node *op2 = get_Or_right(node);
1233 assert (! mode_is_float(get_irn_mode(node)));
1234 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1235 | match_mode_neutral | match_am | match_immediate);
1241 * Creates an ia32 Eor.
1243 * @return The created ia32 Eor node
1245 static ir_node *gen_Eor(ir_node *node) {
1246 ir_node *op1 = get_Eor_left(node);
1247 ir_node *op2 = get_Eor_right(node);
1249 assert(! mode_is_float(get_irn_mode(node)));
1250 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1251 | match_mode_neutral | match_am | match_immediate);
1256 * Creates an ia32 Sub.
1258 * @return The created ia32 Sub node
1260 static ir_node *gen_Sub(ir_node *node) {
1261 ir_node *op1 = get_Sub_left(node);
1262 ir_node *op2 = get_Sub_right(node);
1263 ir_mode *mode = get_irn_mode(node);
1265 if (mode_is_float(mode)) {
1266 if (ia32_cg_config.use_sse2)
1267 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1269 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub);
1272 if (is_Const(op2)) {
1273 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1277 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1278 | match_am | match_immediate);
1281 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1282 ir_node *const src_val,
1283 ir_node *const src_mem,
1284 ir_node *const am_mem)
1286 if (is_NoMem(am_mem)) {
1287 return be_transform_node(src_mem);
1288 } else if (is_Proj(src_val) &&
1290 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1291 /* avoid memory loop */
1293 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1294 ir_node *const ptr_pred = get_Proj_pred(src_val);
1295 int const arity = get_Sync_n_preds(src_mem);
1300 NEW_ARR_A(ir_node*, ins, arity + 1);
1302 for (i = arity - 1; i >= 0; --i) {
1303 ir_node *const pred = get_Sync_pred(src_mem, i);
1305 /* avoid memory loop */
1306 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1309 ins[n++] = be_transform_node(pred);
1314 return new_r_Sync(irg, block, n, ins);
1318 ins[0] = be_transform_node(src_mem);
1320 return new_r_Sync(irg, block, 2, ins);
1325 * Generates an ia32 DivMod with additional infrastructure for the
1326 * register allocator if needed.
1328 static ir_node *create_Div(ir_node *node)
1330 ir_graph *irg = current_ir_graph;
1331 dbg_info *dbgi = get_irn_dbg_info(node);
1332 ir_node *block = get_nodes_block(node);
1333 ir_node *new_block = be_transform_node(block);
1340 ir_node *sign_extension;
1341 ia32_address_mode_t am;
1342 ia32_address_t *addr = &am.addr;
1344 /* the upper bits have random contents for smaller modes */
1345 switch (get_irn_opcode(node)) {
1347 op1 = get_Div_left(node);
1348 op2 = get_Div_right(node);
1349 mem = get_Div_mem(node);
1350 mode = get_Div_resmode(node);
1353 op1 = get_Mod_left(node);
1354 op2 = get_Mod_right(node);
1355 mem = get_Mod_mem(node);
1356 mode = get_Mod_resmode(node);
1359 op1 = get_DivMod_left(node);
1360 op2 = get_DivMod_right(node);
1361 mem = get_DivMod_mem(node);
1362 mode = get_DivMod_resmode(node);
1365 panic("invalid divmod node %+F", node);
1368 match_arguments(&am, block, op1, op2, NULL, match_am);
1370 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1371 is the memory of the consumed address. We can have only the second op as address
1372 in Div nodes, so check only op2. */
1373 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1375 if (mode_is_signed(mode)) {
1376 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1377 be_dep_on_frame(produceval);
1378 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1381 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1382 addr->index, new_mem, am.new_op2,
1383 am.new_op1, sign_extension);
1385 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1386 be_dep_on_frame(sign_extension);
1388 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1389 addr->index, new_mem, am.new_op2,
1390 am.new_op1, sign_extension);
1393 set_irn_pinned(new_node, get_irn_pinned(node));
1395 set_am_attributes(new_node, &am);
1396 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1398 new_node = fix_mem_proj(new_node, &am);
1404 static ir_node *gen_Mod(ir_node *node) {
1405 return create_Div(node);
1408 static ir_node *gen_Div(ir_node *node) {
1409 return create_Div(node);
1412 static ir_node *gen_DivMod(ir_node *node) {
1413 return create_Div(node);
1419 * Creates an ia32 floating Div.
1421 * @return The created ia32 xDiv node
1423 static ir_node *gen_Quot(ir_node *node)
1425 ir_node *op1 = get_Quot_left(node);
1426 ir_node *op2 = get_Quot_right(node);
1428 if (ia32_cg_config.use_sse2) {
1429 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1431 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv);
1437 * Creates an ia32 Shl.
1439 * @return The created ia32 Shl node
1441 static ir_node *gen_Shl(ir_node *node) {
1442 ir_node *left = get_Shl_left(node);
1443 ir_node *right = get_Shl_right(node);
1445 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1446 match_mode_neutral | match_immediate);
1450 * Creates an ia32 Shr.
1452 * @return The created ia32 Shr node
1454 static ir_node *gen_Shr(ir_node *node) {
1455 ir_node *left = get_Shr_left(node);
1456 ir_node *right = get_Shr_right(node);
1458 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1464 * Creates an ia32 Sar.
1466 * @return The created ia32 Shrs node
1468 static ir_node *gen_Shrs(ir_node *node) {
1469 ir_node *left = get_Shrs_left(node);
1470 ir_node *right = get_Shrs_right(node);
1471 ir_mode *mode = get_irn_mode(node);
1473 if(is_Const(right) && mode == mode_Is) {
1474 tarval *tv = get_Const_tarval(right);
1475 long val = get_tarval_long(tv);
1477 /* this is a sign extension */
1478 ir_graph *irg = current_ir_graph;
1479 dbg_info *dbgi = get_irn_dbg_info(node);
1480 ir_node *block = be_transform_node(get_nodes_block(node));
1482 ir_node *new_op = be_transform_node(op);
1483 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1485 be_dep_on_frame(pval);
1486 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1490 /* 8 or 16 bit sign extension? */
1491 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1492 ir_node *shl_left = get_Shl_left(left);
1493 ir_node *shl_right = get_Shl_right(left);
1494 if(is_Const(shl_right)) {
1495 tarval *tv1 = get_Const_tarval(right);
1496 tarval *tv2 = get_Const_tarval(shl_right);
1497 if(tv1 == tv2 && tarval_is_long(tv1)) {
1498 long val = get_tarval_long(tv1);
1499 if(val == 16 || val == 24) {
1500 dbg_info *dbgi = get_irn_dbg_info(node);
1501 ir_node *block = get_nodes_block(node);
1511 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1520 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1526 * Creates an ia32 Rol.
1528 * @param op1 The first operator
1529 * @param op2 The second operator
1530 * @return The created ia32 RotL node
1532 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1533 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1539 * Creates an ia32 Ror.
1540 * NOTE: There is no RotR with immediate because this would always be a RotL
1541 * "imm-mode_size_bits" which can be pre-calculated.
1543 * @param op1 The first operator
1544 * @param op2 The second operator
1545 * @return The created ia32 RotR node
1547 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1548 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1554 * Creates an ia32 RotR or RotL (depending on the found pattern).
1556 * @return The created ia32 RotL or RotR node
1558 static ir_node *gen_Rotl(ir_node *node) {
1559 ir_node *rotate = NULL;
1560 ir_node *op1 = get_Rotl_left(node);
1561 ir_node *op2 = get_Rotl_right(node);
1563 /* Firm has only RotL, so we are looking for a right (op2)
1564 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1565 that means we can create a RotR instead of an Add and a RotL */
1569 ir_node *left = get_Add_left(add);
1570 ir_node *right = get_Add_right(add);
1571 if (is_Const(right)) {
1572 tarval *tv = get_Const_tarval(right);
1573 ir_mode *mode = get_irn_mode(node);
1574 long bits = get_mode_size_bits(mode);
1576 if (is_Minus(left) &&
1577 tarval_is_long(tv) &&
1578 get_tarval_long(tv) == bits &&
1581 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1582 rotate = gen_Ror(node, op1, get_Minus_op(left));
1587 if (rotate == NULL) {
1588 rotate = gen_Rol(node, op1, op2);
1597 * Transforms a Minus node.
1599 * @return The created ia32 Minus node
1601 static ir_node *gen_Minus(ir_node *node)
1603 ir_node *op = get_Minus_op(node);
1604 ir_node *block = be_transform_node(get_nodes_block(node));
1605 ir_graph *irg = current_ir_graph;
1606 dbg_info *dbgi = get_irn_dbg_info(node);
1607 ir_mode *mode = get_irn_mode(node);
1612 if (mode_is_float(mode)) {
1613 ir_node *new_op = be_transform_node(op);
1614 if (ia32_cg_config.use_sse2) {
1615 /* TODO: non-optimal... if we have many xXors, then we should
1616 * rather create a load for the const and use that instead of
1617 * several AM nodes... */
1618 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1619 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1620 ir_node *nomem = new_rd_NoMem(irg);
1622 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1623 nomem, new_op, noreg_xmm);
1625 size = get_mode_size_bits(mode);
1626 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1628 set_ia32_am_sc(new_node, ent);
1629 set_ia32_op_type(new_node, ia32_AddrModeS);
1630 set_ia32_ls_mode(new_node, mode);
1632 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1635 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1638 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1644 * Transforms a Not node.
1646 * @return The created ia32 Not node
1648 static ir_node *gen_Not(ir_node *node) {
1649 ir_node *op = get_Not_op(node);
1651 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1652 assert (! mode_is_float(get_irn_mode(node)));
1654 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1660 * Transforms an Abs node.
1662 * @return The created ia32 Abs node
1664 static ir_node *gen_Abs(ir_node *node)
1666 ir_node *block = get_nodes_block(node);
1667 ir_node *new_block = be_transform_node(block);
1668 ir_node *op = get_Abs_op(node);
1669 ir_graph *irg = current_ir_graph;
1670 dbg_info *dbgi = get_irn_dbg_info(node);
1671 ir_mode *mode = get_irn_mode(node);
1672 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1673 ir_node *nomem = new_NoMem();
1679 if (mode_is_float(mode)) {
1680 new_op = be_transform_node(op);
1682 if (ia32_cg_config.use_sse2) {
1683 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1684 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1685 nomem, new_op, noreg_fp);
1687 size = get_mode_size_bits(mode);
1688 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1690 set_ia32_am_sc(new_node, ent);
1692 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1694 set_ia32_op_type(new_node, ia32_AddrModeS);
1695 set_ia32_ls_mode(new_node, mode);
1697 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1698 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1701 ir_node *xor, *pval, *sign_extension;
1703 if (get_mode_size_bits(mode) == 32) {
1704 new_op = be_transform_node(op);
1706 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1709 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1710 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1713 be_dep_on_frame(pval);
1714 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1716 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1717 nomem, new_op, sign_extension);
1718 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1720 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1721 nomem, xor, sign_extension);
1722 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1729 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1731 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1732 dbg_info *dbgi = get_irn_dbg_info(cmp);
1733 ir_node *block = get_nodes_block(cmp);
1734 ir_node *new_block = be_transform_node(block);
1735 ir_node *op1 = be_transform_node(x);
1736 ir_node *op2 = be_transform_node(n);
1738 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1742 * Transform a node returning a "flag" result.
1744 * @param node the node to transform
1745 * @param pnc_out the compare mode to use
1747 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1756 /* we have a Cmp as input */
1757 if (is_Proj(node)) {
1758 ir_node *pred = get_Proj_pred(node);
1760 pn_Cmp pnc = get_Proj_proj(node);
1761 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1762 ir_node *l = get_Cmp_left(pred);
1763 ir_node *r = get_Cmp_right(pred);
1765 ir_node *la = get_And_left(l);
1766 ir_node *ra = get_And_right(l);
1768 ir_node *c = get_Shl_left(la);
1769 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1770 /* (1 << n) & ra) */
1771 ir_node *n = get_Shl_right(la);
1772 flags = gen_bt(pred, ra, n);
1773 /* we must generate a Jc/Jnc jump */
1774 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1777 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1782 ir_node *c = get_Shl_left(ra);
1783 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1784 /* la & (1 << n)) */
1785 ir_node *n = get_Shl_right(ra);
1786 flags = gen_bt(pred, la, n);
1787 /* we must generate a Jc/Jnc jump */
1788 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1791 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1797 flags = be_transform_node(pred);
1803 /* a mode_b value, we have to compare it against 0 */
1804 dbgi = get_irn_dbg_info(node);
1805 new_block = be_transform_node(get_nodes_block(node));
1806 new_op = be_transform_node(node);
1807 noreg = ia32_new_NoReg_gp(env_cg);
1808 nomem = new_NoMem();
1809 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1810 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1811 *pnc_out = pn_Cmp_Lg;
1816 * Transforms a Load.
1818 * @return the created ia32 Load node
1820 static ir_node *gen_Load(ir_node *node) {
1821 ir_node *old_block = get_nodes_block(node);
1822 ir_node *block = be_transform_node(old_block);
1823 ir_node *ptr = get_Load_ptr(node);
1824 ir_node *mem = get_Load_mem(node);
1825 ir_node *new_mem = be_transform_node(mem);
1828 ir_graph *irg = current_ir_graph;
1829 dbg_info *dbgi = get_irn_dbg_info(node);
1830 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1831 ir_mode *mode = get_Load_mode(node);
1834 ia32_address_t addr;
1836 /* construct load address */
1837 memset(&addr, 0, sizeof(addr));
1838 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1845 base = be_transform_node(base);
1851 index = be_transform_node(index);
1854 if (mode_is_float(mode)) {
1855 if (ia32_cg_config.use_sse2) {
1856 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1858 res_mode = mode_xmm;
1860 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1862 res_mode = mode_vfp;
1865 assert(mode != mode_b);
1867 /* create a conv node with address mode for smaller modes */
1868 if(get_mode_size_bits(mode) < 32) {
1869 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1870 new_mem, noreg, mode);
1872 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1877 set_irn_pinned(new_node, get_irn_pinned(node));
1878 set_ia32_op_type(new_node, ia32_AddrModeS);
1879 set_ia32_ls_mode(new_node, mode);
1880 set_address(new_node, &addr);
1882 if(get_irn_pinned(node) == op_pin_state_floats) {
1883 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1886 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1888 be_dep_on_frame(new_node);
1892 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1893 ir_node *ptr, ir_node *other)
1900 /* we only use address mode if we're the only user of the load */
1901 if (get_irn_n_edges(node) > 1)
1904 load = get_Proj_pred(node);
1907 if (get_nodes_block(load) != block)
1910 /* store should have the same pointer as the load */
1911 if (get_Load_ptr(load) != ptr)
1914 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1915 if (other != NULL &&
1916 get_nodes_block(other) == block &&
1917 heights_reachable_in_block(heights, other, load)) {
1924 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
1925 ir_node *const pred = get_Sync_pred(mem, i);
1927 if (is_Proj(pred) && get_Proj_pred(pred) == load)
1930 if (get_nodes_block(pred) == block &&
1931 heights_reachable_in_block(heights, pred, load)) {
1936 /* Store should be attached to the load */
1937 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
1944 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1945 ir_node *mem, ir_node *ptr, ir_mode *mode,
1946 construct_binop_dest_func *func,
1947 construct_binop_dest_func *func8bit,
1948 match_flags_t flags)
1950 ir_node *src_block = get_nodes_block(node);
1952 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1953 ir_graph *irg = current_ir_graph;
1960 ia32_address_mode_t am;
1961 ia32_address_t *addr = &am.addr;
1962 memset(&am, 0, sizeof(am));
1964 assert(flags & match_dest_am);
1965 assert(flags & match_immediate); /* there is no destam node without... */
1966 commutative = (flags & match_commutative) != 0;
1968 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
1969 build_address(&am, op1);
1970 new_op = create_immediate_or_transform(op2, 0);
1971 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1972 build_address(&am, op2);
1973 new_op = create_immediate_or_transform(op1, 0);
1978 if(addr->base == NULL)
1979 addr->base = noreg_gp;
1980 if(addr->index == NULL)
1981 addr->index = noreg_gp;
1982 if(addr->mem == NULL)
1983 addr->mem = new_NoMem();
1985 dbgi = get_irn_dbg_info(node);
1986 block = be_transform_node(src_block);
1987 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
1989 if(get_mode_size_bits(mode) == 8) {
1990 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
1993 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
1996 set_address(new_node, addr);
1997 set_ia32_op_type(new_node, ia32_AddrModeD);
1998 set_ia32_ls_mode(new_node, mode);
1999 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2001 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2002 mem_proj = be_transform_node(am.mem_proj);
2003 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2008 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2009 ir_node *ptr, ir_mode *mode,
2010 construct_unop_dest_func *func)
2012 ir_graph *irg = current_ir_graph;
2013 ir_node *src_block = get_nodes_block(node);
2019 ia32_address_mode_t am;
2020 ia32_address_t *addr = &am.addr;
2021 memset(&am, 0, sizeof(am));
2023 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2026 build_address(&am, op);
2028 dbgi = get_irn_dbg_info(node);
2029 block = be_transform_node(src_block);
2030 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2031 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2032 set_address(new_node, addr);
2033 set_ia32_op_type(new_node, ia32_AddrModeD);
2034 set_ia32_ls_mode(new_node, mode);
2035 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2037 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2038 mem_proj = be_transform_node(am.mem_proj);
2039 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2044 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2045 ir_mode *mode = get_irn_mode(node);
2046 ir_node *mux_true = get_Mux_true(node);
2047 ir_node *mux_false = get_Mux_false(node);
2058 ia32_address_t addr;
2060 if(get_mode_size_bits(mode) != 8)
2063 if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2065 } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2071 build_address_ptr(&addr, ptr, mem);
2073 irg = current_ir_graph;
2074 dbgi = get_irn_dbg_info(node);
2075 block = get_nodes_block(node);
2076 new_block = be_transform_node(block);
2077 cond = get_Mux_sel(node);
2078 flags = get_flags_node(cond, &pnc);
2079 new_mem = be_transform_node(mem);
2080 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2081 addr.index, addr.mem, flags, pnc, negated);
2082 set_address(new_node, &addr);
2083 set_ia32_op_type(new_node, ia32_AddrModeD);
2084 set_ia32_ls_mode(new_node, mode);
2085 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2090 static ir_node *try_create_dest_am(ir_node *node) {
2091 ir_node *val = get_Store_value(node);
2092 ir_node *mem = get_Store_mem(node);
2093 ir_node *ptr = get_Store_ptr(node);
2094 ir_mode *mode = get_irn_mode(val);
2095 unsigned bits = get_mode_size_bits(mode);
2100 /* handle only GP modes for now... */
2101 if(!ia32_mode_needs_gp_reg(mode))
2105 /* store must be the only user of the val node */
2106 if(get_irn_n_edges(val) > 1)
2108 /* skip pointless convs */
2110 ir_node *conv_op = get_Conv_op(val);
2111 ir_mode *pred_mode = get_irn_mode(conv_op);
2112 if (!ia32_mode_needs_gp_reg(pred_mode))
2114 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2122 /* value must be in the same block */
2123 if(get_nodes_block(node) != get_nodes_block(val))
2126 switch (get_irn_opcode(val)) {
2128 op1 = get_Add_left(val);
2129 op2 = get_Add_right(val);
2130 if(is_Const_1(op2)) {
2131 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2132 new_rd_ia32_IncMem);
2134 } else if(is_Const_Minus_1(op2)) {
2135 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2136 new_rd_ia32_DecMem);
2139 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2140 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2141 match_dest_am | match_commutative |
2145 op1 = get_Sub_left(val);
2146 op2 = get_Sub_right(val);
2147 if (is_Const(op2)) {
2148 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2150 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2151 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2152 match_dest_am | match_immediate |
2156 op1 = get_And_left(val);
2157 op2 = get_And_right(val);
2158 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2159 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2160 match_dest_am | match_commutative |
2164 op1 = get_Or_left(val);
2165 op2 = get_Or_right(val);
2166 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2167 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2168 match_dest_am | match_commutative |
2172 op1 = get_Eor_left(val);
2173 op2 = get_Eor_right(val);
2174 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2175 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2176 match_dest_am | match_commutative |
2180 op1 = get_Shl_left(val);
2181 op2 = get_Shl_right(val);
2182 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2183 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2184 match_dest_am | match_immediate);
2187 op1 = get_Shr_left(val);
2188 op2 = get_Shr_right(val);
2189 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2190 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2191 match_dest_am | match_immediate);
2194 op1 = get_Shrs_left(val);
2195 op2 = get_Shrs_right(val);
2196 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2197 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2198 match_dest_am | match_immediate);
2201 op1 = get_Rotl_left(val);
2202 op2 = get_Rotl_right(val);
2203 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2204 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2205 match_dest_am | match_immediate);
2207 /* TODO: match ROR patterns... */
2209 new_node = try_create_SetMem(val, ptr, mem);
2212 op1 = get_Minus_op(val);
2213 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2216 /* should be lowered already */
2217 assert(mode != mode_b);
2218 op1 = get_Not_op(val);
2219 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2225 if(new_node != NULL) {
2226 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2227 get_irn_pinned(node) == op_pin_state_pinned) {
2228 set_irn_pinned(new_node, op_pin_state_pinned);
2235 static int is_float_to_int_conv(const ir_node *node)
2237 ir_mode *mode = get_irn_mode(node);
2241 if (mode != mode_Is && mode != mode_Hs)
2246 conv_op = get_Conv_op(node);
2247 conv_mode = get_irn_mode(conv_op);
2249 if(!mode_is_float(conv_mode))
2256 * Transform a Store(floatConst).
2258 * @return the created ia32 Store node
2260 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2262 ir_mode *mode = get_irn_mode(cns);
2263 unsigned size = get_mode_size_bytes(mode);
2264 tarval *tv = get_Const_tarval(cns);
2265 ir_node *block = get_nodes_block(node);
2266 ir_node *new_block = be_transform_node(block);
2267 ir_node *ptr = get_Store_ptr(node);
2268 ir_node *mem = get_Store_mem(node);
2269 ir_graph *irg = current_ir_graph;
2270 dbg_info *dbgi = get_irn_dbg_info(node);
2274 ia32_address_t addr;
2276 assert(size % 4 == 0);
2279 build_address_ptr(&addr, ptr, mem);
2283 get_tarval_sub_bits(tv, ofs) |
2284 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2285 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2286 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2287 ir_node *imm = create_Immediate(NULL, 0, val);
2289 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2290 addr.index, addr.mem, imm);
2292 set_irn_pinned(new_node, get_irn_pinned(node));
2293 set_ia32_op_type(new_node, ia32_AddrModeD);
2294 set_ia32_ls_mode(new_node, mode_Iu);
2295 set_address(new_node, &addr);
2296 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2298 ins[i++] = new_node;
2303 } while (size != 0);
2305 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2309 * Generate a vfist or vfisttp instruction.
2311 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2312 ir_node *mem, ir_node *val, ir_node **fist)
2316 if (ia32_cg_config.use_fisttp) {
2317 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2318 if other users exists */
2319 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2320 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2321 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2322 be_new_Keep(reg_class, irg, block, 1, &value);
2324 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2327 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2330 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2336 * Transforms a normal Store.
2338 * @return the created ia32 Store node
2340 static ir_node *gen_normal_Store(ir_node *node)
2342 ir_node *val = get_Store_value(node);
2343 ir_mode *mode = get_irn_mode(val);
2344 ir_node *block = get_nodes_block(node);
2345 ir_node *new_block = be_transform_node(block);
2346 ir_node *ptr = get_Store_ptr(node);
2347 ir_node *mem = get_Store_mem(node);
2348 ir_graph *irg = current_ir_graph;
2349 dbg_info *dbgi = get_irn_dbg_info(node);
2350 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2351 ir_node *new_val, *new_node, *store;
2352 ia32_address_t addr;
2354 /* check for destination address mode */
2355 new_node = try_create_dest_am(node);
2356 if (new_node != NULL)
2359 /* construct store address */
2360 memset(&addr, 0, sizeof(addr));
2361 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2363 if (addr.base == NULL) {
2366 addr.base = be_transform_node(addr.base);
2369 if (addr.index == NULL) {
2372 addr.index = be_transform_node(addr.index);
2374 addr.mem = be_transform_node(mem);
2376 if (mode_is_float(mode)) {
2377 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2379 while (is_Conv(val) && mode == get_irn_mode(val)) {
2380 ir_node *op = get_Conv_op(val);
2381 if (!mode_is_float(get_irn_mode(op)))
2385 new_val = be_transform_node(val);
2386 if (ia32_cg_config.use_sse2) {
2387 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2388 addr.index, addr.mem, new_val);
2390 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2391 addr.index, addr.mem, new_val, mode);
2394 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2395 val = get_Conv_op(val);
2397 /* TODO: is this optimisation still necessary at all (middleend)? */
2398 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2399 while (is_Conv(val)) {
2400 ir_node *op = get_Conv_op(val);
2401 if (!mode_is_float(get_irn_mode(op)))
2403 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2407 new_val = be_transform_node(val);
2408 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2410 new_val = create_immediate_or_transform(val, 0);
2411 assert(mode != mode_b);
2413 if (get_mode_size_bits(mode) == 8) {
2414 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2415 addr.index, addr.mem, new_val);
2417 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2418 addr.index, addr.mem, new_val);
2423 set_irn_pinned(store, get_irn_pinned(node));
2424 set_ia32_op_type(store, ia32_AddrModeD);
2425 set_ia32_ls_mode(store, mode);
2427 set_address(store, &addr);
2428 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2434 * Transforms a Store.
2436 * @return the created ia32 Store node
2438 static ir_node *gen_Store(ir_node *node)
2440 ir_node *val = get_Store_value(node);
2441 ir_mode *mode = get_irn_mode(val);
2443 if (mode_is_float(mode) && is_Const(val)) {
2446 /* we are storing a floating point constant */
2447 if (ia32_cg_config.use_sse2) {
2448 transform = !is_simple_sse_Const(val);
2450 transform = !is_simple_x87_Const(val);
2453 return gen_float_const_Store(node, val);
2455 return gen_normal_Store(node);
2459 * Transforms a Switch.
2461 * @return the created ia32 SwitchJmp node
2463 static ir_node *create_Switch(ir_node *node)
2465 ir_graph *irg = current_ir_graph;
2466 dbg_info *dbgi = get_irn_dbg_info(node);
2467 ir_node *block = be_transform_node(get_nodes_block(node));
2468 ir_node *sel = get_Cond_selector(node);
2469 ir_node *new_sel = be_transform_node(sel);
2470 int switch_min = INT_MAX;
2471 int switch_max = INT_MIN;
2472 long default_pn = get_Cond_defaultProj(node);
2474 const ir_edge_t *edge;
2476 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2478 /* determine the smallest switch case value */
2479 foreach_out_edge(node, edge) {
2480 ir_node *proj = get_edge_src_irn(edge);
2481 long pn = get_Proj_proj(proj);
2482 if(pn == default_pn)
2491 if((unsigned) (switch_max - switch_min) > 256000) {
2492 panic("Size of switch %+F bigger than 256000", node);
2495 if (switch_min != 0) {
2496 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2498 /* if smallest switch case is not 0 we need an additional sub */
2499 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2500 add_ia32_am_offs_int(new_sel, -switch_min);
2501 set_ia32_op_type(new_sel, ia32_AddrModeS);
2503 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2506 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2507 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2513 * Transform a Cond node.
2515 static ir_node *gen_Cond(ir_node *node) {
2516 ir_node *block = get_nodes_block(node);
2517 ir_node *new_block = be_transform_node(block);
2518 ir_graph *irg = current_ir_graph;
2519 dbg_info *dbgi = get_irn_dbg_info(node);
2520 ir_node *sel = get_Cond_selector(node);
2521 ir_mode *sel_mode = get_irn_mode(sel);
2522 ir_node *flags = NULL;
2526 if (sel_mode != mode_b) {
2527 return create_Switch(node);
2530 /* we get flags from a Cmp */
2531 flags = get_flags_node(sel, &pnc);
2533 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2534 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2539 static ir_node *gen_be_Copy(ir_node *node)
2541 ir_node *new_node = be_duplicate_node(node);
2542 ir_mode *mode = get_irn_mode(new_node);
2544 if (ia32_mode_needs_gp_reg(mode)) {
2545 set_irn_mode(new_node, mode_Iu);
2551 static ir_node *create_Fucom(ir_node *node)
2553 ir_graph *irg = current_ir_graph;
2554 dbg_info *dbgi = get_irn_dbg_info(node);
2555 ir_node *block = get_nodes_block(node);
2556 ir_node *new_block = be_transform_node(block);
2557 ir_node *left = get_Cmp_left(node);
2558 ir_node *new_left = be_transform_node(left);
2559 ir_node *right = get_Cmp_right(node);
2563 if(ia32_cg_config.use_fucomi) {
2564 new_right = be_transform_node(right);
2565 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2567 set_ia32_commutative(new_node);
2568 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2570 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2571 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2574 new_right = be_transform_node(right);
2575 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2579 set_ia32_commutative(new_node);
2581 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2583 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2584 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2590 static ir_node *create_Ucomi(ir_node *node)
2592 ir_graph *irg = current_ir_graph;
2593 dbg_info *dbgi = get_irn_dbg_info(node);
2594 ir_node *src_block = get_nodes_block(node);
2595 ir_node *new_block = be_transform_node(src_block);
2596 ir_node *left = get_Cmp_left(node);
2597 ir_node *right = get_Cmp_right(node);
2599 ia32_address_mode_t am;
2600 ia32_address_t *addr = &am.addr;
2602 match_arguments(&am, src_block, left, right, NULL,
2603 match_commutative | match_am);
2605 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2606 addr->mem, am.new_op1, am.new_op2,
2608 set_am_attributes(new_node, &am);
2610 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2612 new_node = fix_mem_proj(new_node, &am);
2618 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2619 * to fold an and into a test node
2621 static bool can_fold_test_and(ir_node *node)
2623 const ir_edge_t *edge;
2625 /** we can only have eq and lg projs */
2626 foreach_out_edge(node, edge) {
2627 ir_node *proj = get_edge_src_irn(edge);
2628 pn_Cmp pnc = get_Proj_proj(proj);
2629 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2637 * returns true if it is assured, that the upper bits of a node are "clean"
2638 * which means for a 16 or 8 bit value, that the upper bits in the register
2639 * are 0 for unsigned and a copy of the last significant bit for signed
2642 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2644 assert(ia32_mode_needs_gp_reg(mode));
2645 if (get_mode_size_bits(mode) >= 32)
2648 if (is_Proj(transformed_node))
2649 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2651 if (is_ia32_Conv_I2I(transformed_node)
2652 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2653 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2654 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2656 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2662 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2663 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2664 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2665 const ia32_immediate_attr_t *attr
2666 = get_ia32_immediate_attr_const(right);
2667 if (attr->symconst == 0
2668 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2672 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2675 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2676 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2677 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2678 const ia32_immediate_attr_t *attr
2679 = get_ia32_immediate_attr_const(right);
2680 if (attr->symconst == 0
2681 && (unsigned) attr->offset
2682 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2689 /* TODO recurse on Or, Xor, ... if appropriate? */
2691 if (is_ia32_Immediate(transformed_node)
2692 || is_ia32_Const(transformed_node)) {
2693 const ia32_immediate_attr_t *attr
2694 = get_ia32_immediate_attr_const(transformed_node);
2695 if (mode_is_signed(mode)) {
2696 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2697 if (shifted == 0 || shifted == -1)
2700 unsigned long shifted = (unsigned long) attr->offset;
2701 shifted >>= get_mode_size_bits(mode);
2711 * Generate code for a Cmp.
2713 static ir_node *gen_Cmp(ir_node *node)
2715 ir_graph *irg = current_ir_graph;
2716 dbg_info *dbgi = get_irn_dbg_info(node);
2717 ir_node *block = get_nodes_block(node);
2718 ir_node *new_block = be_transform_node(block);
2719 ir_node *left = get_Cmp_left(node);
2720 ir_node *right = get_Cmp_right(node);
2721 ir_mode *cmp_mode = get_irn_mode(left);
2723 ia32_address_mode_t am;
2724 ia32_address_t *addr = &am.addr;
2727 if(mode_is_float(cmp_mode)) {
2728 if (ia32_cg_config.use_sse2) {
2729 return create_Ucomi(node);
2731 return create_Fucom(node);
2735 assert(ia32_mode_needs_gp_reg(cmp_mode));
2737 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2738 cmp_unsigned = !mode_is_signed(cmp_mode);
2739 if (is_Const_0(right) &&
2741 get_irn_n_edges(left) == 1 &&
2742 can_fold_test_and(node)) {
2743 /* Test(and_left, and_right) */
2744 ir_node *and_left = get_And_left(left);
2745 ir_node *and_right = get_And_right(left);
2747 /* matze: code here used mode instead of cmd_mode, I think it is always
2748 * the same as cmp_mode, but I leave this here to see if this is really
2751 assert(get_irn_mode(and_left) == cmp_mode);
2753 match_arguments(&am, block, and_left, and_right, NULL,
2755 match_am | match_8bit_am | match_16bit_am |
2756 match_am_and_immediates | match_immediate |
2757 match_8bit | match_16bit);
2759 /* use 32bit compare mode if possible since the opcode is smaller */
2760 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2761 upper_bits_clean(am.new_op2, cmp_mode)) {
2762 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2765 if (get_mode_size_bits(cmp_mode) == 8) {
2766 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2767 addr->index, addr->mem, am.new_op1,
2768 am.new_op2, am.ins_permuted,
2771 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2772 addr->index, addr->mem, am.new_op1,
2773 am.new_op2, am.ins_permuted,
2777 /* Cmp(left, right) */
2778 match_arguments(&am, block, left, right, NULL,
2779 match_commutative | match_am | match_8bit_am |
2780 match_16bit_am | match_am_and_immediates |
2781 match_immediate | match_8bit | match_16bit);
2782 /* use 32bit compare mode if possible since the opcode is smaller */
2783 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2784 upper_bits_clean(am.new_op2, cmp_mode)) {
2785 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2788 if (get_mode_size_bits(cmp_mode) == 8) {
2789 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2790 addr->index, addr->mem, am.new_op1,
2791 am.new_op2, am.ins_permuted,
2794 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2795 addr->index, addr->mem, am.new_op1,
2796 am.new_op2, am.ins_permuted, cmp_unsigned);
2799 set_am_attributes(new_node, &am);
2800 set_ia32_ls_mode(new_node, cmp_mode);
2802 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2804 new_node = fix_mem_proj(new_node, &am);
2809 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2812 ir_graph *irg = current_ir_graph;
2813 dbg_info *dbgi = get_irn_dbg_info(node);
2814 ir_node *block = get_nodes_block(node);
2815 ir_node *new_block = be_transform_node(block);
2816 ir_node *val_true = get_Mux_true(node);
2817 ir_node *val_false = get_Mux_false(node);
2819 match_flags_t match_flags;
2820 ia32_address_mode_t am;
2821 ia32_address_t *addr;
2823 assert(ia32_cg_config.use_cmov);
2824 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2828 match_flags = match_commutative | match_am | match_16bit_am |
2831 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2833 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2834 addr->mem, am.new_op1, am.new_op2, new_flags,
2835 am.ins_permuted, pnc);
2836 set_am_attributes(new_node, &am);
2838 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2840 new_node = fix_mem_proj(new_node, &am);
2846 * Creates a ia32 Setcc instruction.
2848 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2849 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2852 ir_graph *irg = current_ir_graph;
2853 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2854 ir_node *nomem = new_NoMem();
2855 ir_mode *mode = get_irn_mode(orig_node);
2858 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2859 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2861 /* we might need to conv the result up */
2862 if (get_mode_size_bits(mode) > 8) {
2863 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2864 nomem, new_node, mode_Bu);
2865 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2872 * Create instruction for an unsigned Difference or Zero.
2874 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2875 ir_graph *irg = current_ir_graph;
2876 ir_mode *mode = get_irn_mode(psi);
2877 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2880 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2881 match_mode_neutral | match_am | match_immediate | match_two_users);
2883 block = get_nodes_block(new_node);
2885 if (is_Proj(new_node)) {
2886 sub = get_Proj_pred(new_node);
2887 assert(is_ia32_Sub(sub));
2890 set_irn_mode(sub, mode_T);
2891 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2893 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2895 dbgi = get_irn_dbg_info(psi);
2896 noreg = ia32_new_NoReg_gp(env_cg);
2897 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2898 nomem = new_NoMem();
2899 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2901 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2902 set_ia32_commutative(new_node);
2907 * Transforms a Mux node into CMov.
2909 * @return The transformed node.
2911 static ir_node *gen_Mux(ir_node *node)
2913 dbg_info *dbgi = get_irn_dbg_info(node);
2914 ir_node *block = get_nodes_block(node);
2915 ir_node *new_block = be_transform_node(block);
2916 ir_node *mux_true = get_Mux_true(node);
2917 ir_node *mux_false = get_Mux_false(node);
2918 ir_node *cond = get_Mux_sel(node);
2919 ir_mode *mode = get_irn_mode(node);
2922 assert(get_irn_mode(cond) == mode_b);
2924 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2925 if (mode_is_float(mode)) {
2926 ir_node *cmp = get_Proj_pred(cond);
2927 ir_node *cmp_left = get_Cmp_left(cmp);
2928 ir_node *cmp_right = get_Cmp_right(cmp);
2929 pn_Cmp pnc = get_Proj_proj(cond);
2931 if (ia32_cg_config.use_sse2) {
2932 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2933 if (cmp_left == mux_true && cmp_right == mux_false) {
2934 /* Mux(a <= b, a, b) => MIN */
2935 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2936 match_commutative | match_am | match_two_users);
2937 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2938 /* Mux(a <= b, b, a) => MAX */
2939 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2940 match_commutative | match_am | match_two_users);
2942 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2943 if (cmp_left == mux_true && cmp_right == mux_false) {
2944 /* Mux(a >= b, a, b) => MAX */
2945 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2946 match_commutative | match_am | match_two_users);
2947 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2948 /* Mux(a >= b, b, a) => MIN */
2949 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2950 match_commutative | match_am | match_two_users);
2954 panic("cannot transform floating point Mux");
2960 assert(ia32_mode_needs_gp_reg(mode));
2962 if (is_Proj(cond)) {
2963 ir_node *cmp = get_Proj_pred(cond);
2965 ir_node *cmp_left = get_Cmp_left(cmp);
2966 ir_node *cmp_right = get_Cmp_right(cmp);
2967 pn_Cmp pnc = get_Proj_proj(cond);
2969 /* check for unsigned Doz first */
2970 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2971 is_Const_0(mux_false) && is_Sub(mux_true) &&
2972 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2973 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2974 return create_Doz(node, cmp_left, cmp_right);
2975 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2976 is_Const_0(mux_true) && is_Sub(mux_false) &&
2977 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2978 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2979 return create_Doz(node, cmp_left, cmp_right);
2984 flags = get_flags_node(cond, &pnc);
2986 if (is_Const(mux_true) && is_Const(mux_false)) {
2987 /* both are const, good */
2988 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2989 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2990 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2991 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2993 /* Not that simple. */
2998 new_node = create_CMov(node, cond, flags, pnc);
3006 * Create a conversion from x87 state register to general purpose.
3008 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3009 ir_node *block = be_transform_node(get_nodes_block(node));
3010 ir_node *op = get_Conv_op(node);
3011 ir_node *new_op = be_transform_node(op);
3012 ia32_code_gen_t *cg = env_cg;
3013 ir_graph *irg = current_ir_graph;
3014 dbg_info *dbgi = get_irn_dbg_info(node);
3015 ir_node *noreg = ia32_new_NoReg_gp(cg);
3016 ir_mode *mode = get_irn_mode(node);
3017 ir_node *fist, *load, *mem;
3019 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3020 set_irn_pinned(fist, op_pin_state_floats);
3021 set_ia32_use_frame(fist);
3022 set_ia32_op_type(fist, ia32_AddrModeD);
3024 assert(get_mode_size_bits(mode) <= 32);
3025 /* exception we can only store signed 32 bit integers, so for unsigned
3026 we store a 64bit (signed) integer and load the lower bits */
3027 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3028 set_ia32_ls_mode(fist, mode_Ls);
3030 set_ia32_ls_mode(fist, mode_Is);
3032 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3035 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3037 set_irn_pinned(load, op_pin_state_floats);
3038 set_ia32_use_frame(load);
3039 set_ia32_op_type(load, ia32_AddrModeS);
3040 set_ia32_ls_mode(load, mode_Is);
3041 if(get_ia32_ls_mode(fist) == mode_Ls) {
3042 ia32_attr_t *attr = get_ia32_attr(load);
3043 attr->data.need_64bit_stackent = 1;
3045 ia32_attr_t *attr = get_ia32_attr(load);
3046 attr->data.need_32bit_stackent = 1;
3048 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3050 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3054 * Creates a x87 strict Conv by placing a Store and a Load
3056 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3058 ir_node *block = get_nodes_block(node);
3059 ir_graph *irg = current_ir_graph;
3060 dbg_info *dbgi = get_irn_dbg_info(node);
3061 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3062 ir_node *nomem = new_NoMem();
3063 ir_node *frame = get_irg_frame(irg);
3064 ir_node *store, *load;
3067 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3069 set_ia32_use_frame(store);
3070 set_ia32_op_type(store, ia32_AddrModeD);
3071 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3073 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3075 set_ia32_use_frame(load);
3076 set_ia32_op_type(load, ia32_AddrModeS);
3077 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3079 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3084 * Create a conversion from general purpose to x87 register
3086 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3087 ir_node *src_block = get_nodes_block(node);
3088 ir_node *block = be_transform_node(src_block);
3089 ir_graph *irg = current_ir_graph;
3090 dbg_info *dbgi = get_irn_dbg_info(node);
3091 ir_node *op = get_Conv_op(node);
3092 ir_node *new_op = NULL;
3096 ir_mode *store_mode;
3102 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3103 if (src_mode == mode_Is || src_mode == mode_Hs) {
3104 ia32_address_mode_t am;
3106 match_arguments(&am, src_block, NULL, op, NULL,
3107 match_am | match_try_am | match_16bit | match_16bit_am);
3108 if (am.op_type == ia32_AddrModeS) {
3109 ia32_address_t *addr = &am.addr;
3111 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3112 addr->index, addr->mem);
3113 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3116 set_am_attributes(fild, &am);
3117 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3119 fix_mem_proj(fild, &am);
3124 if(new_op == NULL) {
3125 new_op = be_transform_node(op);
3128 noreg = ia32_new_NoReg_gp(env_cg);
3129 nomem = new_NoMem();
3130 mode = get_irn_mode(op);
3132 /* first convert to 32 bit signed if necessary */
3133 src_bits = get_mode_size_bits(src_mode);
3134 if (src_bits == 8) {
3135 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3137 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3139 } else if (src_bits < 32) {
3140 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3142 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3146 assert(get_mode_size_bits(mode) == 32);
3149 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3152 set_ia32_use_frame(store);
3153 set_ia32_op_type(store, ia32_AddrModeD);
3154 set_ia32_ls_mode(store, mode_Iu);
3156 /* exception for 32bit unsigned, do a 64bit spill+load */
3157 if(!mode_is_signed(mode)) {
3160 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3162 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3163 get_irg_frame(irg), noreg, nomem,
3166 set_ia32_use_frame(zero_store);
3167 set_ia32_op_type(zero_store, ia32_AddrModeD);
3168 add_ia32_am_offs_int(zero_store, 4);
3169 set_ia32_ls_mode(zero_store, mode_Iu);
3174 store = new_rd_Sync(dbgi, irg, block, 2, in);
3175 store_mode = mode_Ls;
3177 store_mode = mode_Is;
3181 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3183 set_ia32_use_frame(fild);
3184 set_ia32_op_type(fild, ia32_AddrModeS);
3185 set_ia32_ls_mode(fild, store_mode);
3187 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3193 * Create a conversion from one integer mode into another one
3195 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3196 dbg_info *dbgi, ir_node *block, ir_node *op,
3199 ir_graph *irg = current_ir_graph;
3200 int src_bits = get_mode_size_bits(src_mode);
3201 int tgt_bits = get_mode_size_bits(tgt_mode);
3202 ir_node *new_block = be_transform_node(block);
3204 ir_mode *smaller_mode;
3206 ia32_address_mode_t am;
3207 ia32_address_t *addr = &am.addr;
3210 if (src_bits < tgt_bits) {
3211 smaller_mode = src_mode;
3212 smaller_bits = src_bits;
3214 smaller_mode = tgt_mode;
3215 smaller_bits = tgt_bits;
3218 #ifdef DEBUG_libfirm
3220 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3225 match_arguments(&am, block, NULL, op, NULL,
3226 match_8bit | match_16bit |
3227 match_am | match_8bit_am | match_16bit_am);
3229 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3230 /* unnecessary conv. in theory it shouldn't have been AM */
3231 assert(is_ia32_NoReg_GP(addr->base));
3232 assert(is_ia32_NoReg_GP(addr->index));
3233 assert(is_NoMem(addr->mem));
3234 assert(am.addr.offset == 0);
3235 assert(am.addr.symconst_ent == NULL);
3239 if (smaller_bits == 8) {
3240 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3241 addr->index, addr->mem, am.new_op2,
3244 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3245 addr->index, addr->mem, am.new_op2,
3248 set_am_attributes(new_node, &am);
3249 /* match_arguments assume that out-mode = in-mode, this isn't true here
3251 set_ia32_ls_mode(new_node, smaller_mode);
3252 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3253 new_node = fix_mem_proj(new_node, &am);
3258 * Transforms a Conv node.
3260 * @return The created ia32 Conv node
3262 static ir_node *gen_Conv(ir_node *node) {
3263 ir_node *block = get_nodes_block(node);
3264 ir_node *new_block = be_transform_node(block);
3265 ir_node *op = get_Conv_op(node);
3266 ir_node *new_op = NULL;
3267 ir_graph *irg = current_ir_graph;
3268 dbg_info *dbgi = get_irn_dbg_info(node);
3269 ir_mode *src_mode = get_irn_mode(op);
3270 ir_mode *tgt_mode = get_irn_mode(node);
3271 int src_bits = get_mode_size_bits(src_mode);
3272 int tgt_bits = get_mode_size_bits(tgt_mode);
3273 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3274 ir_node *nomem = new_rd_NoMem(irg);
3275 ir_node *res = NULL;
3277 if (src_mode == mode_b) {
3278 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3279 /* nothing to do, we already model bools as 0/1 ints */
3280 return be_transform_node(op);
3283 if (src_mode == tgt_mode) {
3284 if (get_Conv_strict(node)) {
3285 if (ia32_cg_config.use_sse2) {
3286 /* when we are in SSE mode, we can kill all strict no-op conversion */
3287 return be_transform_node(op);
3290 /* this should be optimized already, but who knows... */
3291 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3292 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3293 return be_transform_node(op);
3297 if (mode_is_float(src_mode)) {
3298 new_op = be_transform_node(op);
3299 /* we convert from float ... */
3300 if (mode_is_float(tgt_mode)) {
3301 if(src_mode == mode_E && tgt_mode == mode_D
3302 && !get_Conv_strict(node)) {
3303 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3308 if (ia32_cg_config.use_sse2) {
3309 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3310 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3312 set_ia32_ls_mode(res, tgt_mode);
3314 if(get_Conv_strict(node)) {
3315 res = gen_x87_strict_conv(tgt_mode, new_op);
3316 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3319 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3324 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3325 if (ia32_cg_config.use_sse2) {
3326 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3328 set_ia32_ls_mode(res, src_mode);
3330 return gen_x87_fp_to_gp(node);
3334 /* we convert from int ... */
3335 if (mode_is_float(tgt_mode)) {
3337 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3338 if (ia32_cg_config.use_sse2) {
3339 new_op = be_transform_node(op);
3340 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3342 set_ia32_ls_mode(res, tgt_mode);
3344 res = gen_x87_gp_to_fp(node, src_mode);
3345 if(get_Conv_strict(node)) {
3346 /* The strict-Conv is only necessary, if the int mode has more bits
3347 * than the float mantissa */
3348 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3349 size_t float_mantissa;
3350 /* FIXME There is no way to get the mantissa size of a mode */
3351 switch (get_mode_size_bits(tgt_mode)) {
3352 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3353 case 64: float_mantissa = 52 + 1; break;
3355 case 96: float_mantissa = 64; break;
3356 default: float_mantissa = 0; break;
3358 if (float_mantissa < int_mantissa) {
3359 res = gen_x87_strict_conv(tgt_mode, res);
3360 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3365 } else if(tgt_mode == mode_b) {
3366 /* mode_b lowering already took care that we only have 0/1 values */
3367 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3368 src_mode, tgt_mode));
3369 return be_transform_node(op);
3372 if (src_bits == tgt_bits) {
3373 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3374 src_mode, tgt_mode));
3375 return be_transform_node(op);
3378 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3386 static ir_node *create_immediate_or_transform(ir_node *node,
3387 char immediate_constraint_type)
3389 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3390 if (new_node == NULL) {
3391 new_node = be_transform_node(node);
3397 * Transforms a FrameAddr into an ia32 Add.
3399 static ir_node *gen_be_FrameAddr(ir_node *node) {
3400 ir_node *block = be_transform_node(get_nodes_block(node));
3401 ir_node *op = be_get_FrameAddr_frame(node);
3402 ir_node *new_op = be_transform_node(op);
3403 ir_graph *irg = current_ir_graph;
3404 dbg_info *dbgi = get_irn_dbg_info(node);
3405 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3408 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3409 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3410 set_ia32_use_frame(new_node);
3412 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3418 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3420 static ir_node *gen_be_Return(ir_node *node) {
3421 ir_graph *irg = current_ir_graph;
3422 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3423 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3424 ir_entity *ent = get_irg_entity(irg);
3425 ir_type *tp = get_entity_type(ent);
3430 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3431 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3434 int pn_ret_val, pn_ret_mem, arity, i;
3436 assert(ret_val != NULL);
3437 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3438 return be_duplicate_node(node);
3441 res_type = get_method_res_type(tp, 0);
3443 if (! is_Primitive_type(res_type)) {
3444 return be_duplicate_node(node);
3447 mode = get_type_mode(res_type);
3448 if (! mode_is_float(mode)) {
3449 return be_duplicate_node(node);
3452 assert(get_method_n_ress(tp) == 1);
3454 pn_ret_val = get_Proj_proj(ret_val);
3455 pn_ret_mem = get_Proj_proj(ret_mem);
3457 /* get the Barrier */
3458 barrier = get_Proj_pred(ret_val);
3460 /* get result input of the Barrier */
3461 ret_val = get_irn_n(barrier, pn_ret_val);
3462 new_ret_val = be_transform_node(ret_val);
3464 /* get memory input of the Barrier */
3465 ret_mem = get_irn_n(barrier, pn_ret_mem);
3466 new_ret_mem = be_transform_node(ret_mem);
3468 frame = get_irg_frame(irg);
3470 dbgi = get_irn_dbg_info(barrier);
3471 block = be_transform_node(get_nodes_block(barrier));
3473 noreg = ia32_new_NoReg_gp(env_cg);
3475 /* store xmm0 onto stack */
3476 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3477 new_ret_mem, new_ret_val);
3478 set_ia32_ls_mode(sse_store, mode);
3479 set_ia32_op_type(sse_store, ia32_AddrModeD);
3480 set_ia32_use_frame(sse_store);
3482 /* load into x87 register */
3483 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3484 set_ia32_op_type(fld, ia32_AddrModeS);
3485 set_ia32_use_frame(fld);
3487 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3488 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3490 /* create a new barrier */
3491 arity = get_irn_arity(barrier);
3492 in = alloca(arity * sizeof(in[0]));
3493 for (i = 0; i < arity; ++i) {
3496 if (i == pn_ret_val) {
3498 } else if (i == pn_ret_mem) {
3501 ir_node *in = get_irn_n(barrier, i);
3502 new_in = be_transform_node(in);
3507 new_barrier = new_ir_node(dbgi, irg, block,
3508 get_irn_op(barrier), get_irn_mode(barrier),
3510 copy_node_attr(barrier, new_barrier);
3511 be_duplicate_deps(barrier, new_barrier);
3512 be_set_transformed_node(barrier, new_barrier);
3514 /* transform normally */
3515 return be_duplicate_node(node);
3519 * Transform a be_AddSP into an ia32_SubSP.
3521 static ir_node *gen_be_AddSP(ir_node *node)
3523 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3524 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3526 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3527 match_am | match_immediate);
3531 * Transform a be_SubSP into an ia32_AddSP
3533 static ir_node *gen_be_SubSP(ir_node *node)
3535 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3536 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3538 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3539 match_am | match_immediate);
3543 * Change some phi modes
3545 static ir_node *gen_Phi(ir_node *node) {
3546 ir_node *block = be_transform_node(get_nodes_block(node));
3547 ir_graph *irg = current_ir_graph;
3548 dbg_info *dbgi = get_irn_dbg_info(node);
3549 ir_mode *mode = get_irn_mode(node);
3552 if(ia32_mode_needs_gp_reg(mode)) {
3553 /* we shouldn't have any 64bit stuff around anymore */
3554 assert(get_mode_size_bits(mode) <= 32);
3555 /* all integer operations are on 32bit registers now */
3557 } else if(mode_is_float(mode)) {
3558 if (ia32_cg_config.use_sse2) {
3565 /* phi nodes allow loops, so we use the old arguments for now
3566 * and fix this later */
3567 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3568 get_irn_in(node) + 1);
3569 copy_node_attr(node, phi);
3570 be_duplicate_deps(node, phi);
3572 be_enqueue_preds(node);
3580 static ir_node *gen_IJmp(ir_node *node)
3582 ir_node *block = get_nodes_block(node);
3583 ir_node *new_block = be_transform_node(block);
3584 dbg_info *dbgi = get_irn_dbg_info(node);
3585 ir_node *op = get_IJmp_target(node);
3587 ia32_address_mode_t am;
3588 ia32_address_t *addr = &am.addr;
3590 assert(get_irn_mode(op) == mode_P);
3592 match_arguments(&am, block, NULL, op, NULL,
3593 match_am | match_8bit_am | match_16bit_am |
3594 match_immediate | match_8bit | match_16bit);
3596 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3597 addr->base, addr->index, addr->mem,
3599 set_am_attributes(new_node, &am);
3600 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3602 new_node = fix_mem_proj(new_node, &am);
3608 * Transform a Bound node.
3610 static ir_node *gen_Bound(ir_node *node)
3613 ir_node *lower = get_Bound_lower(node);
3614 dbg_info *dbgi = get_irn_dbg_info(node);
3616 if (is_Const_0(lower)) {
3617 /* typical case for Java */
3618 ir_node *sub, *res, *flags, *block;
3619 ir_graph *irg = current_ir_graph;
3621 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3622 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3624 block = get_nodes_block(res);
3625 if (! is_Proj(res)) {
3627 set_irn_mode(sub, mode_T);
3628 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3630 sub = get_Proj_pred(res);
3632 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3633 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3634 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3636 panic("generic Bound not supported in ia32 Backend");
3642 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3644 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3645 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3647 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3648 match_immediate | match_mode_neutral);
3651 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3653 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3654 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3655 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3659 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3661 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3662 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3663 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3667 static ir_node *gen_ia32_l_Add(ir_node *node) {
3668 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3669 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3670 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3671 match_commutative | match_am | match_immediate |
3672 match_mode_neutral);
3674 if(is_Proj(lowered)) {
3675 lowered = get_Proj_pred(lowered);
3677 assert(is_ia32_Add(lowered));
3678 set_irn_mode(lowered, mode_T);
3684 static ir_node *gen_ia32_l_Adc(ir_node *node)
3686 return gen_binop_flags(node, new_rd_ia32_Adc,
3687 match_commutative | match_am | match_immediate |
3688 match_mode_neutral);
3692 * Transforms a l_MulS into a "real" MulS node.
3694 * @return the created ia32 Mul node
3696 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3697 ir_node *left = get_binop_left(node);
3698 ir_node *right = get_binop_right(node);
3700 return gen_binop(node, left, right, new_rd_ia32_Mul,
3701 match_commutative | match_am | match_mode_neutral);
3705 * Transforms a l_IMulS into a "real" IMul1OPS node.
3707 * @return the created ia32 IMul1OP node
3709 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3710 ir_node *left = get_binop_left(node);
3711 ir_node *right = get_binop_right(node);
3713 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3714 match_commutative | match_am | match_mode_neutral);
3717 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3718 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3719 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3720 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3721 match_am | match_immediate | match_mode_neutral);
3723 if(is_Proj(lowered)) {
3724 lowered = get_Proj_pred(lowered);
3726 assert(is_ia32_Sub(lowered));
3727 set_irn_mode(lowered, mode_T);
3733 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3734 return gen_binop_flags(node, new_rd_ia32_Sbb,
3735 match_am | match_immediate | match_mode_neutral);
3739 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3740 * op1 - target to be shifted
3741 * op2 - contains bits to be shifted into target
3743 * Only op3 can be an immediate.
3745 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3746 ir_node *low, ir_node *count)
3748 ir_node *block = get_nodes_block(node);
3749 ir_node *new_block = be_transform_node(block);
3750 ir_graph *irg = current_ir_graph;
3751 dbg_info *dbgi = get_irn_dbg_info(node);
3752 ir_node *new_high = be_transform_node(high);
3753 ir_node *new_low = be_transform_node(low);
3757 /* the shift amount can be any mode that is bigger than 5 bits, since all
3758 * other bits are ignored anyway */
3759 while (is_Conv(count) &&
3760 get_irn_n_edges(count) == 1 &&
3761 mode_is_int(get_irn_mode(count))) {
3762 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3763 count = get_Conv_op(count);
3765 new_count = create_immediate_or_transform(count, 0);
3767 if (is_ia32_l_ShlD(node)) {
3768 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3771 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3774 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3779 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3781 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3782 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3783 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3784 return gen_lowered_64bit_shifts(node, high, low, count);
3787 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3789 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3790 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3791 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3792 return gen_lowered_64bit_shifts(node, high, low, count);
3795 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3796 ir_node *src_block = get_nodes_block(node);
3797 ir_node *block = be_transform_node(src_block);
3798 ir_graph *irg = current_ir_graph;
3799 dbg_info *dbgi = get_irn_dbg_info(node);
3800 ir_node *frame = get_irg_frame(irg);
3801 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3802 ir_node *nomem = new_NoMem();
3803 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3804 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3805 ir_node *new_val_low = be_transform_node(val_low);
3806 ir_node *new_val_high = be_transform_node(val_high);
3811 ir_node *store_high;
3813 if(!mode_is_signed(get_irn_mode(val_high))) {
3814 panic("unsigned long long -> float not supported yet (%+F)", node);
3818 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3820 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3822 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3823 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3825 set_ia32_use_frame(store_low);
3826 set_ia32_use_frame(store_high);
3827 set_ia32_op_type(store_low, ia32_AddrModeD);
3828 set_ia32_op_type(store_high, ia32_AddrModeD);
3829 set_ia32_ls_mode(store_low, mode_Iu);
3830 set_ia32_ls_mode(store_high, mode_Is);
3831 add_ia32_am_offs_int(store_high, 4);
3835 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3838 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3840 set_ia32_use_frame(fild);
3841 set_ia32_op_type(fild, ia32_AddrModeS);
3842 set_ia32_ls_mode(fild, mode_Ls);
3844 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3846 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3849 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3850 ir_node *src_block = get_nodes_block(node);
3851 ir_node *block = be_transform_node(src_block);
3852 ir_graph *irg = current_ir_graph;
3853 dbg_info *dbgi = get_irn_dbg_info(node);
3854 ir_node *frame = get_irg_frame(irg);
3855 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3856 ir_node *nomem = new_NoMem();
3857 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3858 ir_node *new_val = be_transform_node(val);
3859 ir_node *fist, *mem;
3861 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3862 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3863 set_ia32_use_frame(fist);
3864 set_ia32_op_type(fist, ia32_AddrModeD);
3865 set_ia32_ls_mode(fist, mode_Ls);
3871 * the BAD transformer.
3873 static ir_node *bad_transform(ir_node *node) {
3874 panic("No transform function for %+F available.", node);
3878 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
3879 ir_graph *irg = current_ir_graph;
3880 ir_node *block = be_transform_node(get_nodes_block(node));
3881 ir_node *pred = get_Proj_pred(node);
3882 ir_node *new_pred = be_transform_node(pred);
3883 ir_node *frame = get_irg_frame(irg);
3884 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3885 dbg_info *dbgi = get_irn_dbg_info(node);
3886 long pn = get_Proj_proj(node);
3891 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3892 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3893 set_ia32_use_frame(load);
3894 set_ia32_op_type(load, ia32_AddrModeS);
3895 set_ia32_ls_mode(load, mode_Iu);
3896 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3897 * 32 bit from it with this particular load */
3898 attr = get_ia32_attr(load);
3899 attr->data.need_64bit_stackent = 1;
3901 if (pn == pn_ia32_l_FloattoLL_res_high) {
3902 add_ia32_am_offs_int(load, 4);
3904 assert(pn == pn_ia32_l_FloattoLL_res_low);
3907 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3913 * Transform the Projs of an AddSP.
3915 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
3916 ir_node *block = be_transform_node(get_nodes_block(node));
3917 ir_node *pred = get_Proj_pred(node);
3918 ir_node *new_pred = be_transform_node(pred);
3919 ir_graph *irg = current_ir_graph;
3920 dbg_info *dbgi = get_irn_dbg_info(node);
3921 long proj = get_Proj_proj(node);
3923 if (proj == pn_be_AddSP_sp) {
3924 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3925 pn_ia32_SubSP_stack);
3926 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3928 } else if(proj == pn_be_AddSP_res) {
3929 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3930 pn_ia32_SubSP_addr);
3931 } else if (proj == pn_be_AddSP_M) {
3932 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3935 panic("No idea how to transform proj->AddSP");
3939 * Transform the Projs of a SubSP.
3941 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
3942 ir_node *block = be_transform_node(get_nodes_block(node));
3943 ir_node *pred = get_Proj_pred(node);
3944 ir_node *new_pred = be_transform_node(pred);
3945 ir_graph *irg = current_ir_graph;
3946 dbg_info *dbgi = get_irn_dbg_info(node);
3947 long proj = get_Proj_proj(node);
3949 if (proj == pn_be_SubSP_sp) {
3950 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3951 pn_ia32_AddSP_stack);
3952 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
3954 } else if (proj == pn_be_SubSP_M) {
3955 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3958 panic("No idea how to transform proj->SubSP");
3962 * Transform and renumber the Projs from a Load.
3964 static ir_node *gen_Proj_Load(ir_node *node) {
3966 ir_node *block = be_transform_node(get_nodes_block(node));
3967 ir_node *pred = get_Proj_pred(node);
3968 ir_graph *irg = current_ir_graph;
3969 dbg_info *dbgi = get_irn_dbg_info(node);
3970 long proj = get_Proj_proj(node);
3972 /* loads might be part of source address mode matches, so we don't
3973 * transform the ProjMs yet (with the exception of loads whose result is
3976 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
3979 /* this is needed, because sometimes we have loops that are only
3980 reachable through the ProjM */
3981 be_enqueue_preds(node);
3982 /* do it in 2 steps, to silence firm verifier */
3983 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
3984 set_Proj_proj(res, pn_ia32_mem);
3988 /* renumber the proj */
3989 new_pred = be_transform_node(pred);
3990 if (is_ia32_Load(new_pred)) {
3993 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
3995 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
3996 case pn_Load_X_regular:
3997 return new_rd_Jmp(dbgi, irg, block);
3998 case pn_Load_X_except:
3999 /* This Load might raise an exception. Mark it. */
4000 set_ia32_exc_label(new_pred, 1);
4001 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4005 } else if (is_ia32_Conv_I2I(new_pred) ||
4006 is_ia32_Conv_I2I8Bit(new_pred)) {
4007 set_irn_mode(new_pred, mode_T);
4008 if (proj == pn_Load_res) {
4009 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4010 } else if (proj == pn_Load_M) {
4011 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4013 } else if (is_ia32_xLoad(new_pred)) {
4016 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4018 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4019 case pn_Load_X_regular:
4020 return new_rd_Jmp(dbgi, irg, block);
4021 case pn_Load_X_except:
4022 /* This Load might raise an exception. Mark it. */
4023 set_ia32_exc_label(new_pred, 1);
4024 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4028 } else if (is_ia32_vfld(new_pred)) {
4031 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4033 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4034 case pn_Load_X_regular:
4035 return new_rd_Jmp(dbgi, irg, block);
4036 case pn_Load_X_except:
4037 /* This Load might raise an exception. Mark it. */
4038 set_ia32_exc_label(new_pred, 1);
4039 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4044 /* can happen for ProJMs when source address mode happened for the
4047 /* however it should not be the result proj, as that would mean the
4048 load had multiple users and should not have been used for
4050 if (proj != pn_Load_M) {
4051 panic("internal error: transformed node not a Load");
4053 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4056 panic("No idea how to transform proj");
4060 * Transform and renumber the Projs from a DivMod like instruction.
4062 static ir_node *gen_Proj_DivMod(ir_node *node) {
4063 ir_node *block = be_transform_node(get_nodes_block(node));
4064 ir_node *pred = get_Proj_pred(node);
4065 ir_node *new_pred = be_transform_node(pred);
4066 ir_graph *irg = current_ir_graph;
4067 dbg_info *dbgi = get_irn_dbg_info(node);
4068 long proj = get_Proj_proj(node);
4070 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4072 switch (get_irn_opcode(pred)) {
4076 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4078 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4079 case pn_Div_X_regular:
4080 return new_rd_Jmp(dbgi, irg, block);
4081 case pn_Div_X_except:
4082 set_ia32_exc_label(new_pred, 1);
4083 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4091 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4093 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4094 case pn_Mod_X_except:
4095 set_ia32_exc_label(new_pred, 1);
4096 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4104 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4105 case pn_DivMod_res_div:
4106 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4107 case pn_DivMod_res_mod:
4108 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4109 case pn_DivMod_X_regular:
4110 return new_rd_Jmp(dbgi, irg, block);
4111 case pn_DivMod_X_except:
4112 set_ia32_exc_label(new_pred, 1);
4113 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4122 panic("No idea how to transform proj->DivMod");
4126 * Transform and renumber the Projs from a CopyB.
4128 static ir_node *gen_Proj_CopyB(ir_node *node) {
4129 ir_node *block = be_transform_node(get_nodes_block(node));
4130 ir_node *pred = get_Proj_pred(node);
4131 ir_node *new_pred = be_transform_node(pred);
4132 ir_graph *irg = current_ir_graph;
4133 dbg_info *dbgi = get_irn_dbg_info(node);
4134 long proj = get_Proj_proj(node);
4137 case pn_CopyB_M_regular:
4138 if (is_ia32_CopyB_i(new_pred)) {
4139 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4140 } else if (is_ia32_CopyB(new_pred)) {
4141 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4148 panic("No idea how to transform proj->CopyB");
4152 * Transform and renumber the Projs from a Quot.
4154 static ir_node *gen_Proj_Quot(ir_node *node) {
4155 ir_node *block = be_transform_node(get_nodes_block(node));
4156 ir_node *pred = get_Proj_pred(node);
4157 ir_node *new_pred = be_transform_node(pred);
4158 ir_graph *irg = current_ir_graph;
4159 dbg_info *dbgi = get_irn_dbg_info(node);
4160 long proj = get_Proj_proj(node);
4164 if (is_ia32_xDiv(new_pred)) {
4165 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4166 } else if (is_ia32_vfdiv(new_pred)) {
4167 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4171 if (is_ia32_xDiv(new_pred)) {
4172 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4173 } else if (is_ia32_vfdiv(new_pred)) {
4174 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4177 case pn_Quot_X_regular:
4178 case pn_Quot_X_except:
4183 panic("No idea how to transform proj->Quot");
4186 static ir_node *gen_be_Call(ir_node *node)
4188 dbg_info *const dbgi = get_irn_dbg_info(node);
4189 ir_graph *const irg = current_ir_graph;
4190 ir_node *const src_block = get_nodes_block(node);
4191 ir_node *const block = be_transform_node(src_block);
4192 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4193 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4194 ir_node *const sp = be_transform_node(src_sp);
4195 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4196 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4197 ia32_address_mode_t am;
4198 ia32_address_t *const addr = &am.addr;
4203 ir_node * eax = noreg;
4204 ir_node * ecx = noreg;
4205 ir_node * edx = noreg;
4206 unsigned const pop = be_Call_get_pop(node);
4207 ir_type *const call_tp = be_Call_get_type(node);
4209 /* Run the x87 simulator if the call returns a float value */
4210 if (get_method_n_ress(call_tp) > 0) {
4211 ir_type *const res_type = get_method_res_type(call_tp, 0);
4212 ir_mode *const res_mode = get_type_mode(res_type);
4214 if (res_mode != NULL && mode_is_float(res_mode)) {
4215 env_cg->do_x87_sim = 1;
4219 /* We do not want be_Call direct calls */
4220 assert(be_Call_get_entity(node) == NULL);
4222 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4223 match_am | match_immediate);
4225 i = get_irn_arity(node) - 1;
4226 fpcw = be_transform_node(get_irn_n(node, i--));
4227 for (; i >= be_pos_Call_first_arg; --i) {
4228 arch_register_req_t const *const req =
4229 arch_get_register_req(env_cg->arch_env, node, i);
4230 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4232 assert(req->type == arch_register_req_type_limited);
4233 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4235 switch (*req->limited) {
4236 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4237 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4238 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4239 default: panic("Invalid GP register for register parameter");
4243 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4244 call = new_rd_ia32_Call(dbgi, irg, block, addr->base, addr->index, mem,
4245 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4246 set_am_attributes(call, &am);
4247 call = fix_mem_proj(call, &am);
4249 if (get_irn_pinned(node) == op_pin_state_pinned)
4250 set_irn_pinned(call, op_pin_state_pinned);
4252 SET_IA32_ORIG_NODE(call, ia32_get_old_node_name(env_cg, node));
4256 static ir_node *gen_be_IncSP(ir_node *node) {
4257 ir_node *res = be_duplicate_node(node);
4258 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4264 * Transform the Projs from a be_Call.
4266 static ir_node *gen_Proj_be_Call(ir_node *node)
4268 ir_node *block = be_transform_node(get_nodes_block(node));
4269 ir_node *call = get_Proj_pred(node);
4270 ir_node *new_call = be_transform_node(call);
4271 ir_graph *irg = current_ir_graph;
4272 dbg_info *dbgi = get_irn_dbg_info(node);
4273 ir_type *method_type = be_Call_get_type(call);
4274 int n_res = get_method_n_ress(method_type);
4275 long proj = get_Proj_proj(node);
4276 ir_mode *mode = get_irn_mode(node);
4278 const arch_register_class_t *cls;
4281 /* The following is kinda tricky: If we're using SSE, then we have to
4282 * move the result value of the call in floating point registers to an
4283 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4284 * after the call, we have to make sure to correctly make the
4285 * MemProj and the result Proj use these 2 nodes
4287 if (proj == pn_be_Call_M_regular) {
4288 // get new node for result, are we doing the sse load/store hack?
4289 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4290 ir_node *call_res_new;
4291 ir_node *call_res_pred = NULL;
4293 if (call_res != NULL) {
4294 call_res_new = be_transform_node(call_res);
4295 call_res_pred = get_Proj_pred(call_res_new);
4298 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4299 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4302 assert(is_ia32_xLoad(call_res_pred));
4303 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4307 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4308 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4310 ir_node *frame = get_irg_frame(irg);
4311 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4313 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4316 /* in case there is no memory output: create one to serialize the copy
4318 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4319 pn_be_Call_M_regular);
4320 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4321 pn_be_Call_first_res);
4323 /* store st(0) onto stack */
4324 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4326 set_ia32_op_type(fstp, ia32_AddrModeD);
4327 set_ia32_use_frame(fstp);
4329 /* load into SSE register */
4330 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4332 set_ia32_op_type(sse_load, ia32_AddrModeS);
4333 set_ia32_use_frame(sse_load);
4335 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4341 /* transform call modes */
4342 if (mode_is_data(mode)) {
4343 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4347 /* Map from be_Call to ia32_Call proj number */
4348 if (proj == pn_be_Call_sp) {
4349 proj = pn_ia32_Call_stack;
4350 } else if (proj == pn_be_Call_M_regular) {
4351 proj = pn_ia32_Call_M;
4353 arch_register_req_t const *const req = arch_get_register_req(env_cg->arch_env, node, BE_OUT_POS(proj));
4354 int const n_outs = get_ia32_n_res(new_call);
4357 assert(proj >= pn_be_Call_first_res);
4358 assert(req->type == arch_register_req_type_limited);
4360 for (i = 0; i < n_outs; ++i) {
4361 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4363 if (new_req->type != arch_register_req_type_limited ||
4364 new_req->cls != req->cls ||
4365 *new_req->limited != *req->limited)
4374 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4376 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4378 case pn_ia32_Call_stack:
4379 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4382 case pn_ia32_Call_fpcw:
4383 arch_set_irn_register(env_cg->arch_env, res, &ia32_fp_cw_regs[REG_FPCW]);
4391 * Transform the Projs from a Cmp.
4393 static ir_node *gen_Proj_Cmp(ir_node *node)
4395 /* this probably means not all mode_b nodes were lowered... */
4396 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4401 * Transform the Projs from a Bound.
4403 static ir_node *gen_Proj_Bound(ir_node *node)
4405 ir_node *new_node, *block;
4406 ir_node *pred = get_Proj_pred(node);
4408 switch (get_Proj_proj(node)) {
4410 return be_transform_node(get_Bound_mem(pred));
4411 case pn_Bound_X_regular:
4412 new_node = be_transform_node(pred);
4413 block = get_nodes_block(new_node);
4414 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4415 case pn_Bound_X_except:
4416 new_node = be_transform_node(pred);
4417 block = get_nodes_block(new_node);
4418 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4420 return be_transform_node(get_Bound_index(pred));
4422 panic("unsupported Proj from Bound");
4426 static ir_node *gen_Proj_ASM(ir_node *node)
4432 if (get_irn_mode(node) != mode_M)
4433 return be_duplicate_node(node);
4435 pred = get_Proj_pred(node);
4436 new_pred = be_transform_node(pred);
4437 block = get_nodes_block(new_pred);
4438 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4439 get_ia32_n_res(new_pred) + 1);
4443 * Transform and potentially renumber Proj nodes.
4445 static ir_node *gen_Proj(ir_node *node) {
4446 ir_node *pred = get_Proj_pred(node);
4449 switch (get_irn_opcode(pred)) {
4451 proj = get_Proj_proj(node);
4452 if (proj == pn_Store_M) {
4453 return be_transform_node(pred);
4455 panic("No idea how to transform proj->Store");
4458 return gen_Proj_Load(node);
4460 return gen_Proj_ASM(node);
4464 return gen_Proj_DivMod(node);
4466 return gen_Proj_CopyB(node);
4468 return gen_Proj_Quot(node);
4470 return gen_Proj_be_SubSP(node);
4472 return gen_Proj_be_AddSP(node);
4474 return gen_Proj_be_Call(node);
4476 return gen_Proj_Cmp(node);
4478 return gen_Proj_Bound(node);
4480 proj = get_Proj_proj(node);
4482 case pn_Start_X_initial_exec: {
4483 ir_node *block = get_nodes_block(pred);
4484 ir_node *new_block = be_transform_node(block);
4485 dbg_info *dbgi = get_irn_dbg_info(node);
4486 /* we exchange the ProjX with a jump */
4487 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4492 case pn_Start_P_tls:
4493 return gen_Proj_tls(node);
4498 if (is_ia32_l_FloattoLL(pred)) {
4499 return gen_Proj_l_FloattoLL(node);
4501 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4505 ir_mode *mode = get_irn_mode(node);
4506 if (ia32_mode_needs_gp_reg(mode)) {
4507 ir_node *new_pred = be_transform_node(pred);
4508 ir_node *block = be_transform_node(get_nodes_block(node));
4509 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4510 mode_Iu, get_Proj_proj(node));
4511 #ifdef DEBUG_libfirm
4512 new_proj->node_nr = node->node_nr;
4518 return be_duplicate_node(node);
4522 * Enters all transform functions into the generic pointer
4524 static void register_transformers(void)
4528 /* first clear the generic function pointer for all ops */
4529 clear_irp_opcodes_generic_func();
4531 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4532 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4570 /* transform ops from intrinsic lowering */
4582 GEN(ia32_l_LLtoFloat);
4583 GEN(ia32_l_FloattoLL);
4589 /* we should never see these nodes */
4604 /* handle generic backend nodes */
4613 op_Mulh = get_op_Mulh();
4622 * Pre-transform all unknown and noreg nodes.
4624 static void ia32_pretransform_node(void)
4626 ia32_code_gen_t *cg = env_cg;
4628 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4629 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4630 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4631 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4632 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4633 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4638 * Walker, checks if all ia32 nodes producing more than one result have their
4639 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4641 static void add_missing_keep_walker(ir_node *node, void *data)
4644 unsigned found_projs = 0;
4645 const ir_edge_t *edge;
4646 ir_mode *mode = get_irn_mode(node);
4651 if(!is_ia32_irn(node))
4654 n_outs = get_ia32_n_res(node);
4657 if(is_ia32_SwitchJmp(node))
4660 assert(n_outs < (int) sizeof(unsigned) * 8);
4661 foreach_out_edge(node, edge) {
4662 ir_node *proj = get_edge_src_irn(edge);
4665 /* The node could be kept */
4669 if (get_irn_mode(proj) == mode_M)
4672 pn = get_Proj_proj(proj);
4673 assert(pn < n_outs);
4674 found_projs |= 1 << pn;
4678 /* are keeps missing? */
4680 for(i = 0; i < n_outs; ++i) {
4683 const arch_register_req_t *req;
4684 const arch_register_class_t *cls;
4686 if(found_projs & (1 << i)) {
4690 req = get_ia32_out_req(node, i);
4695 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4699 block = get_nodes_block(node);
4700 in[0] = new_r_Proj(current_ir_graph, block, node,
4701 arch_register_class_mode(cls), i);
4702 if(last_keep != NULL) {
4703 be_Keep_add_node(last_keep, cls, in[0]);
4705 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4706 if(sched_is_scheduled(node)) {
4707 sched_add_after(node, last_keep);
4714 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4717 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4719 ir_graph *irg = be_get_birg_irg(cg->birg);
4720 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4723 /* do the transformation */
4724 void ia32_transform_graph(ia32_code_gen_t *cg)
4728 register_transformers();
4730 initial_fpcw = NULL;
4732 BE_TIMER_PUSH(t_heights);
4733 heights = heights_new(cg->irg);
4734 BE_TIMER_POP(t_heights);
4735 ia32_calculate_non_address_mode_nodes(cg->birg);
4737 /* the transform phase is not safe for CSE (yet) because several nodes get
4738 * attributes set after their creation */
4739 cse_last = get_opt_cse();
4742 be_transform_graph(cg->birg, ia32_pretransform_node);
4744 set_opt_cse(cse_last);
4746 ia32_free_non_address_mode_nodes();
4747 heights_free(heights);
4751 void ia32_init_transform(void)
4753 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");