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)
138 return is_Const(node) && is_Const_null(node);
141 /** Return non-zero is a node represents the 1 constant. */
142 static bool is_Const_1(ir_node *node)
144 return is_Const(node) && is_Const_one(node);
147 /** Return non-zero is a node represents the -1 constant. */
148 static bool is_Const_Minus_1(ir_node *node)
150 return is_Const(node) && is_Const_all_one(node);
154 * returns true if constant can be created with a simple float command
156 static bool is_simple_x87_Const(ir_node *node)
158 tarval *tv = get_Const_tarval(node);
159 if (tarval_is_null(tv) || tarval_is_one(tv))
162 /* TODO: match all the other float constants */
167 * returns true if constant can be created with a simple float command
169 static bool is_simple_sse_Const(ir_node *node)
171 tarval *tv = get_Const_tarval(node);
172 ir_mode *mode = get_tarval_mode(tv);
177 if (tarval_is_null(tv) || tarval_is_one(tv))
180 if (mode == mode_D) {
181 unsigned val = get_tarval_sub_bits(tv, 0) |
182 (get_tarval_sub_bits(tv, 1) << 8) |
183 (get_tarval_sub_bits(tv, 2) << 16) |
184 (get_tarval_sub_bits(tv, 3) << 24);
186 /* lower 32bit are zero, really a 32bit constant */
190 /* TODO: match all the other float constants */
195 * Transforms a Const.
197 static ir_node *gen_Const(ir_node *node)
199 ir_graph *irg = current_ir_graph;
200 ir_node *old_block = get_nodes_block(node);
201 ir_node *block = be_transform_node(old_block);
202 dbg_info *dbgi = get_irn_dbg_info(node);
203 ir_mode *mode = get_irn_mode(node);
205 assert(is_Const(node));
207 if (mode_is_float(mode)) {
209 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
210 ir_node *nomem = new_NoMem();
214 if (ia32_cg_config.use_sse2) {
215 tarval *tv = get_Const_tarval(node);
216 if (tarval_is_null(tv)) {
217 load = new_rd_ia32_xZero(dbgi, irg, block);
218 set_ia32_ls_mode(load, mode);
220 } else if (tarval_is_one(tv)) {
221 int cnst = mode == mode_F ? 26 : 55;
222 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
223 ir_node *imm2 = create_Immediate(NULL, 0, 2);
224 ir_node *pslld, *psrld;
226 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
227 set_ia32_ls_mode(load, mode);
228 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
229 set_ia32_ls_mode(pslld, mode);
230 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
231 set_ia32_ls_mode(psrld, mode);
233 } else if (mode == mode_F) {
234 /* we can place any 32bit constant by using a movd gp, sse */
235 unsigned val = get_tarval_sub_bits(tv, 0) |
236 (get_tarval_sub_bits(tv, 1) << 8) |
237 (get_tarval_sub_bits(tv, 2) << 16) |
238 (get_tarval_sub_bits(tv, 3) << 24);
239 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
240 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
241 set_ia32_ls_mode(load, mode);
244 if (mode == mode_D) {
245 unsigned val = get_tarval_sub_bits(tv, 0) |
246 (get_tarval_sub_bits(tv, 1) << 8) |
247 (get_tarval_sub_bits(tv, 2) << 16) |
248 (get_tarval_sub_bits(tv, 3) << 24);
250 ir_node *imm32 = create_Immediate(NULL, 0, 32);
251 ir_node *cnst, *psllq;
253 /* fine, lower 32bit are zero, produce 32bit value */
254 val = get_tarval_sub_bits(tv, 4) |
255 (get_tarval_sub_bits(tv, 5) << 8) |
256 (get_tarval_sub_bits(tv, 6) << 16) |
257 (get_tarval_sub_bits(tv, 7) << 24);
258 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
259 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
260 set_ia32_ls_mode(load, mode);
261 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
262 set_ia32_ls_mode(psllq, mode);
267 floatent = create_float_const_entity(node);
269 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
271 set_ia32_op_type(load, ia32_AddrModeS);
272 set_ia32_am_sc(load, floatent);
273 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
274 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
277 if (is_Const_null(node)) {
278 load = new_rd_ia32_vfldz(dbgi, irg, block);
280 set_ia32_ls_mode(load, mode);
281 } else if (is_Const_one(node)) {
282 load = new_rd_ia32_vfld1(dbgi, irg, block);
284 set_ia32_ls_mode(load, mode);
286 floatent = create_float_const_entity(node);
288 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
289 set_ia32_op_type(load, ia32_AddrModeS);
290 set_ia32_am_sc(load, floatent);
291 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
292 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
293 /* take the mode from the entity */
294 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
298 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
300 be_dep_on_frame(load);
302 } else { /* non-float mode */
304 tarval *tv = get_Const_tarval(node);
307 tv = tarval_convert_to(tv, mode_Iu);
309 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
311 panic("couldn't convert constant tarval (%+F)", node);
313 val = get_tarval_long(tv);
315 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
316 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
318 be_dep_on_frame(cnst);
324 * Transforms a SymConst.
326 static ir_node *gen_SymConst(ir_node *node)
328 ir_graph *irg = current_ir_graph;
329 ir_node *old_block = get_nodes_block(node);
330 ir_node *block = be_transform_node(old_block);
331 dbg_info *dbgi = get_irn_dbg_info(node);
332 ir_mode *mode = get_irn_mode(node);
335 if (mode_is_float(mode)) {
336 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
337 ir_node *nomem = new_NoMem();
339 if (ia32_cg_config.use_sse2)
340 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
342 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
343 set_ia32_am_sc(cnst, get_SymConst_entity(node));
344 set_ia32_use_frame(cnst);
348 if (get_SymConst_kind(node) != symconst_addr_ent) {
349 panic("backend only support symconst_addr_ent (at %+F)", node);
351 entity = get_SymConst_entity(node);
352 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
355 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
357 be_dep_on_frame(cnst);
361 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
362 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
364 static const struct {
366 const char *ent_name;
367 const char *cnst_str;
370 } names [ia32_known_const_max] = {
371 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
372 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
373 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
374 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
375 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
377 static ir_entity *ent_cache[ia32_known_const_max];
379 const char *tp_name, *ent_name, *cnst_str;
387 ent_name = names[kct].ent_name;
388 if (! ent_cache[kct]) {
389 tp_name = names[kct].tp_name;
390 cnst_str = names[kct].cnst_str;
392 switch (names[kct].mode) {
393 case 0: mode = mode_Iu; break;
394 case 1: mode = mode_Lu; break;
395 default: mode = mode_F; break;
397 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
398 tp = new_type_primitive(new_id_from_str(tp_name), mode);
399 /* set the specified alignment */
400 set_type_alignment_bytes(tp, names[kct].align);
402 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
404 set_entity_ld_ident(ent, get_entity_ident(ent));
405 set_entity_visibility(ent, visibility_local);
406 set_entity_variability(ent, variability_constant);
407 set_entity_allocation(ent, allocation_static);
409 /* we create a new entity here: It's initialization must resist on the
411 rem = current_ir_graph;
412 current_ir_graph = get_const_code_irg();
413 cnst = new_Const(mode, tv);
414 current_ir_graph = rem;
416 set_atomic_ent_value(ent, cnst);
418 /* cache the entry */
419 ent_cache[kct] = ent;
422 return ent_cache[kct];
426 * return true if the node is a Proj(Load) and could be used in source address
427 * mode for another node. Will return only true if the @p other node is not
428 * dependent on the memory of the Load (for binary operations use the other
429 * input here, for unary operations use NULL).
431 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
432 ir_node *other, ir_node *other2, match_flags_t flags)
437 /* float constants are always available */
438 if (is_Const(node)) {
439 ir_mode *mode = get_irn_mode(node);
440 if (mode_is_float(mode)) {
441 if (ia32_cg_config.use_sse2) {
442 if (is_simple_sse_Const(node))
445 if (is_simple_x87_Const(node))
448 if (get_irn_n_edges(node) > 1)
456 load = get_Proj_pred(node);
457 pn = get_Proj_proj(node);
458 if (!is_Load(load) || pn != pn_Load_res)
460 if (get_nodes_block(load) != block)
462 /* we only use address mode if we're the only user of the load */
463 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
465 /* in some edge cases with address mode we might reach the load normally
466 * and through some AM sequence, if it is already materialized then we
467 * can't create an AM node from it */
468 if (be_is_transformed(node))
471 /* don't do AM if other node inputs depend on the load (via mem-proj) */
472 if (other != NULL && prevents_AM(block, load, other))
475 if (other2 != NULL && prevents_AM(block, load, other2))
481 typedef struct ia32_address_mode_t ia32_address_mode_t;
482 struct ia32_address_mode_t {
487 ia32_op_type_t op_type;
491 unsigned commutative : 1;
492 unsigned ins_permuted : 1;
495 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
499 /* construct load address */
500 memset(addr, 0, sizeof(addr[0]));
501 ia32_create_address_mode(addr, ptr, /*force=*/0);
503 noreg_gp = ia32_new_NoReg_gp(env_cg);
504 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
505 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
506 addr->mem = be_transform_node(mem);
509 static void build_address(ia32_address_mode_t *am, ir_node *node)
511 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
512 ia32_address_t *addr = &am->addr;
518 if (is_Const(node)) {
519 ir_entity *entity = create_float_const_entity(node);
520 addr->base = noreg_gp;
521 addr->index = noreg_gp;
522 addr->mem = new_NoMem();
523 addr->symconst_ent = entity;
525 am->ls_mode = get_type_mode(get_entity_type(entity));
526 am->pinned = op_pin_state_floats;
530 load = get_Proj_pred(node);
531 ptr = get_Load_ptr(load);
532 mem = get_Load_mem(load);
533 new_mem = be_transform_node(mem);
534 am->pinned = get_irn_pinned(load);
535 am->ls_mode = get_Load_mode(load);
536 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
539 /* construct load address */
540 ia32_create_address_mode(addr, ptr, /*force=*/0);
542 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
543 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
547 static void set_address(ir_node *node, const ia32_address_t *addr)
549 set_ia32_am_scale(node, addr->scale);
550 set_ia32_am_sc(node, addr->symconst_ent);
551 set_ia32_am_offs_int(node, addr->offset);
552 if (addr->symconst_sign)
553 set_ia32_am_sc_sign(node);
555 set_ia32_use_frame(node);
556 set_ia32_frame_ent(node, addr->frame_entity);
560 * Apply attributes of a given address mode to a node.
562 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
564 set_address(node, &am->addr);
566 set_ia32_op_type(node, am->op_type);
567 set_ia32_ls_mode(node, am->ls_mode);
568 if (am->pinned == op_pin_state_pinned) {
569 /* beware: some nodes are already pinned and did not allow to change the state */
570 if (get_irn_pinned(node) != op_pin_state_pinned)
571 set_irn_pinned(node, op_pin_state_pinned);
574 set_ia32_commutative(node);
578 * Check, if a given node is a Down-Conv, ie. a integer Conv
579 * from a mode with a mode with more bits to a mode with lesser bits.
580 * Moreover, we return only true if the node has not more than 1 user.
582 * @param node the node
583 * @return non-zero if node is a Down-Conv
585 static int is_downconv(const ir_node *node)
593 /* we only want to skip the conv when we're the only user
594 * (not optimal but for now...)
596 if (get_irn_n_edges(node) > 1)
599 src_mode = get_irn_mode(get_Conv_op(node));
600 dest_mode = get_irn_mode(node);
601 return ia32_mode_needs_gp_reg(src_mode)
602 && ia32_mode_needs_gp_reg(dest_mode)
603 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
606 /* Skip all Down-Conv's on a given node and return the resulting node. */
607 ir_node *ia32_skip_downconv(ir_node *node)
609 while (is_downconv(node))
610 node = get_Conv_op(node);
615 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
617 ir_mode *mode = get_irn_mode(node);
622 if (mode_is_signed(mode)) {
627 block = get_nodes_block(node);
628 dbgi = get_irn_dbg_info(node);
630 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
634 * matches operands of a node into ia32 addressing/operand modes. This covers
635 * usage of source address mode, immediates, operations with non 32-bit modes,
637 * The resulting data is filled into the @p am struct. block is the block
638 * of the node whose arguments are matched. op1, op2 are the first and second
639 * input that are matched (op1 may be NULL). other_op is another unrelated
640 * input that is not matched! but which is needed sometimes to check if AM
641 * for op1/op2 is legal.
642 * @p flags describes the supported modes of the operation in detail.
644 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
645 ir_node *op1, ir_node *op2, ir_node *other_op,
648 ia32_address_t *addr = &am->addr;
649 ir_mode *mode = get_irn_mode(op2);
650 int mode_bits = get_mode_size_bits(mode);
651 ir_node *noreg_gp, *new_op1, *new_op2;
653 unsigned commutative;
654 int use_am_and_immediates;
657 memset(am, 0, sizeof(am[0]));
659 commutative = (flags & match_commutative) != 0;
660 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
661 use_am = (flags & match_am) != 0;
662 use_immediate = (flags & match_immediate) != 0;
663 assert(!use_am_and_immediates || use_immediate);
666 assert(!commutative || op1 != NULL);
667 assert(use_am || !(flags & match_8bit_am));
668 assert(use_am || !(flags & match_16bit_am));
670 if (mode_bits == 8) {
671 if (!(flags & match_8bit_am))
673 /* we don't automatically add upconvs yet */
674 assert((flags & match_mode_neutral) || (flags & match_8bit));
675 } else if (mode_bits == 16) {
676 if (!(flags & match_16bit_am))
678 /* we don't automatically add upconvs yet */
679 assert((flags & match_mode_neutral) || (flags & match_16bit));
682 /* we can simply skip downconvs for mode neutral nodes: the upper bits
683 * can be random for these operations */
684 if (flags & match_mode_neutral) {
685 op2 = ia32_skip_downconv(op2);
687 op1 = ia32_skip_downconv(op1);
691 /* match immediates. firm nodes are normalized: constants are always on the
694 if (!(flags & match_try_am) && use_immediate) {
695 new_op2 = try_create_Immediate(op2, 0);
698 noreg_gp = ia32_new_NoReg_gp(env_cg);
699 if (new_op2 == NULL &&
700 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
701 build_address(am, op2);
702 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
703 if (mode_is_float(mode)) {
704 new_op2 = ia32_new_NoReg_vfp(env_cg);
708 am->op_type = ia32_AddrModeS;
709 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
711 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
713 build_address(am, op1);
715 if (mode_is_float(mode)) {
716 noreg = ia32_new_NoReg_vfp(env_cg);
721 if (new_op2 != NULL) {
724 new_op1 = be_transform_node(op2);
726 am->ins_permuted = 1;
728 am->op_type = ia32_AddrModeS;
730 am->op_type = ia32_Normal;
732 if (flags & match_try_am) {
738 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
740 new_op2 = be_transform_node(op2);
742 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
744 if (addr->base == NULL)
745 addr->base = noreg_gp;
746 if (addr->index == NULL)
747 addr->index = noreg_gp;
748 if (addr->mem == NULL)
749 addr->mem = new_NoMem();
751 am->new_op1 = new_op1;
752 am->new_op2 = new_op2;
753 am->commutative = commutative;
756 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
761 if (am->mem_proj == NULL)
764 /* we have to create a mode_T so the old MemProj can attach to us */
765 mode = get_irn_mode(node);
766 load = get_Proj_pred(am->mem_proj);
768 be_set_transformed_node(load, node);
770 if (mode != mode_T) {
771 set_irn_mode(node, mode_T);
772 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
779 * Construct a standard binary operation, set AM and immediate if required.
781 * @param node The original node for which the binop is created
782 * @param op1 The first operand
783 * @param op2 The second operand
784 * @param func The node constructor function
785 * @return The constructed ia32 node.
787 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
788 construct_binop_func *func, match_flags_t flags)
791 ir_node *block, *new_block, *new_node;
792 ia32_address_mode_t am;
793 ia32_address_t *addr = &am.addr;
795 block = get_nodes_block(node);
796 match_arguments(&am, block, op1, op2, NULL, flags);
798 dbgi = get_irn_dbg_info(node);
799 new_block = be_transform_node(block);
800 new_node = func(dbgi, current_ir_graph, new_block,
801 addr->base, addr->index, addr->mem,
802 am.new_op1, am.new_op2);
803 set_am_attributes(new_node, &am);
804 /* we can't use source address mode anymore when using immediates */
805 if (!(flags & match_am_and_immediates) &&
806 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
807 set_ia32_am_support(new_node, ia32_am_none);
808 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
810 new_node = fix_mem_proj(new_node, &am);
817 n_ia32_l_binop_right,
818 n_ia32_l_binop_eflags
820 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
821 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
822 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
823 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
824 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
825 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
828 * Construct a binary operation which also consumes the eflags.
830 * @param node The node to transform
831 * @param func The node constructor function
832 * @param flags The match flags
833 * @return The constructor ia32 node
835 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
838 ir_node *src_block = get_nodes_block(node);
839 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
840 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
841 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
843 ir_node *block, *new_node, *new_eflags;
844 ia32_address_mode_t am;
845 ia32_address_t *addr = &am.addr;
847 match_arguments(&am, src_block, op1, op2, eflags, flags);
849 dbgi = get_irn_dbg_info(node);
850 block = be_transform_node(src_block);
851 new_eflags = be_transform_node(eflags);
852 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
853 addr->mem, am.new_op1, am.new_op2, new_eflags);
854 set_am_attributes(new_node, &am);
855 /* we can't use source address mode anymore when using immediates */
856 if (!(flags & match_am_and_immediates) &&
857 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
858 set_ia32_am_support(new_node, ia32_am_none);
859 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
861 new_node = fix_mem_proj(new_node, &am);
866 static ir_node *get_fpcw(void)
869 if (initial_fpcw != NULL)
872 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
873 &ia32_fp_cw_regs[REG_FPCW]);
874 initial_fpcw = be_transform_node(fpcw);
880 * Construct a standard binary operation, set AM and immediate if required.
882 * @param op1 The first operand
883 * @param op2 The second operand
884 * @param func The node constructor function
885 * @return The constructed ia32 node.
887 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
888 construct_binop_float_func *func)
890 ir_mode *mode = get_irn_mode(node);
892 ir_node *block, *new_block, *new_node;
893 ia32_address_mode_t am;
894 ia32_address_t *addr = &am.addr;
895 ia32_x87_attr_t *attr;
896 /* All operations are considered commutative, because there are reverse
898 match_flags_t flags = match_commutative;
900 /* cannot use address mode with long double on x87 */
901 if (get_mode_size_bits(mode) <= 64)
904 block = get_nodes_block(node);
905 match_arguments(&am, block, op1, op2, NULL, flags);
907 dbgi = get_irn_dbg_info(node);
908 new_block = be_transform_node(block);
909 new_node = func(dbgi, current_ir_graph, new_block,
910 addr->base, addr->index, addr->mem,
911 am.new_op1, am.new_op2, get_fpcw());
912 set_am_attributes(new_node, &am);
914 attr = get_ia32_x87_attr(new_node);
915 attr->attr.data.ins_permuted = am.ins_permuted;
917 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
919 new_node = fix_mem_proj(new_node, &am);
925 * Construct a shift/rotate binary operation, sets AM and immediate if required.
927 * @param op1 The first operand
928 * @param op2 The second operand
929 * @param func The node constructor function
930 * @return The constructed ia32 node.
932 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
933 construct_shift_func *func,
937 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
939 assert(! mode_is_float(get_irn_mode(node)));
940 assert(flags & match_immediate);
941 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
943 if (flags & match_mode_neutral) {
944 op1 = ia32_skip_downconv(op1);
945 new_op1 = be_transform_node(op1);
946 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
947 new_op1 = create_upconv(op1, node);
949 new_op1 = be_transform_node(op1);
952 /* the shift amount can be any mode that is bigger than 5 bits, since all
953 * other bits are ignored anyway */
954 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
955 ir_node *const op = get_Conv_op(op2);
956 if (mode_is_float(get_irn_mode(op)))
959 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
961 new_op2 = create_immediate_or_transform(op2, 0);
963 dbgi = get_irn_dbg_info(node);
964 block = get_nodes_block(node);
965 new_block = be_transform_node(block);
966 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
967 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
969 /* lowered shift instruction may have a dependency operand, handle it here */
970 if (get_irn_arity(node) == 3) {
971 /* we have a dependency */
972 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
973 add_irn_dep(new_node, new_dep);
981 * Construct a standard unary operation, set AM and immediate if required.
983 * @param op The operand
984 * @param func The node constructor function
985 * @return The constructed ia32 node.
987 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
991 ir_node *block, *new_block, *new_op, *new_node;
993 assert(flags == 0 || flags == match_mode_neutral);
994 if (flags & match_mode_neutral) {
995 op = ia32_skip_downconv(op);
998 new_op = be_transform_node(op);
999 dbgi = get_irn_dbg_info(node);
1000 block = get_nodes_block(node);
1001 new_block = be_transform_node(block);
1002 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1004 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1009 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1010 ia32_address_t *addr)
1012 ir_node *base, *index, *res;
1016 base = ia32_new_NoReg_gp(env_cg);
1018 base = be_transform_node(base);
1021 index = addr->index;
1022 if (index == NULL) {
1023 index = ia32_new_NoReg_gp(env_cg);
1025 index = be_transform_node(index);
1028 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1029 set_address(res, addr);
1035 * Returns non-zero if a given address mode has a symbolic or
1036 * numerical offset != 0.
1038 static int am_has_immediates(const ia32_address_t *addr)
1040 return addr->offset != 0 || addr->symconst_ent != NULL
1041 || addr->frame_entity || addr->use_frame;
1045 * Creates an ia32 Add.
1047 * @return the created ia32 Add node
1049 static ir_node *gen_Add(ir_node *node)
1051 ir_mode *mode = get_irn_mode(node);
1052 ir_node *op1 = get_Add_left(node);
1053 ir_node *op2 = get_Add_right(node);
1055 ir_node *block, *new_block, *new_node, *add_immediate_op;
1056 ia32_address_t addr;
1057 ia32_address_mode_t am;
1059 if (mode_is_float(mode)) {
1060 if (ia32_cg_config.use_sse2)
1061 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1062 match_commutative | match_am);
1064 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd);
1067 ia32_mark_non_am(node);
1069 op2 = ia32_skip_downconv(op2);
1070 op1 = ia32_skip_downconv(op1);
1074 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1075 * 1. Add with immediate -> Lea
1076 * 2. Add with possible source address mode -> Add
1077 * 3. Otherwise -> Lea
1079 memset(&addr, 0, sizeof(addr));
1080 ia32_create_address_mode(&addr, node, /*force=*/1);
1081 add_immediate_op = NULL;
1083 dbgi = get_irn_dbg_info(node);
1084 block = get_nodes_block(node);
1085 new_block = be_transform_node(block);
1088 if (addr.base == NULL && addr.index == NULL) {
1089 ir_graph *irg = current_ir_graph;
1090 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1091 addr.symconst_sign, addr.offset);
1092 be_dep_on_frame(new_node);
1093 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1096 /* add with immediate? */
1097 if (addr.index == NULL) {
1098 add_immediate_op = addr.base;
1099 } else if (addr.base == NULL && addr.scale == 0) {
1100 add_immediate_op = addr.index;
1103 if (add_immediate_op != NULL) {
1104 if (!am_has_immediates(&addr)) {
1105 #ifdef DEBUG_libfirm
1106 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1109 return be_transform_node(add_immediate_op);
1112 new_node = create_lea_from_address(dbgi, new_block, &addr);
1113 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1117 /* test if we can use source address mode */
1118 match_arguments(&am, block, op1, op2, NULL, match_commutative
1119 | match_mode_neutral | match_am | match_immediate | match_try_am);
1121 /* construct an Add with source address mode */
1122 if (am.op_type == ia32_AddrModeS) {
1123 ir_graph *irg = current_ir_graph;
1124 ia32_address_t *am_addr = &am.addr;
1125 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1126 am_addr->index, am_addr->mem, am.new_op1,
1128 set_am_attributes(new_node, &am);
1129 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1131 new_node = fix_mem_proj(new_node, &am);
1136 /* otherwise construct a lea */
1137 new_node = create_lea_from_address(dbgi, new_block, &addr);
1138 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1143 * Creates an ia32 Mul.
1145 * @return the created ia32 Mul node
1147 static ir_node *gen_Mul(ir_node *node)
1149 ir_node *op1 = get_Mul_left(node);
1150 ir_node *op2 = get_Mul_right(node);
1151 ir_mode *mode = get_irn_mode(node);
1153 if (mode_is_float(mode)) {
1154 if (ia32_cg_config.use_sse2)
1155 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1156 match_commutative | match_am);
1158 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul);
1160 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1161 match_commutative | match_am | match_mode_neutral |
1162 match_immediate | match_am_and_immediates);
1166 * Creates an ia32 Mulh.
1167 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1168 * this result while Mul returns the lower 32 bit.
1170 * @return the created ia32 Mulh node
1172 static ir_node *gen_Mulh(ir_node *node)
1174 ir_node *block = get_nodes_block(node);
1175 ir_node *new_block = be_transform_node(block);
1176 dbg_info *dbgi = get_irn_dbg_info(node);
1177 ir_node *op1 = get_Mulh_left(node);
1178 ir_node *op2 = get_Mulh_right(node);
1179 ir_mode *mode = get_irn_mode(node);
1181 ir_node *proj_res_high;
1183 if (mode_is_signed(mode)) {
1184 new_node = gen_binop(node, op1, op2, new_rd_ia32_IMul1OP, match_commutative | match_am);
1185 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1186 mode_Iu, pn_ia32_IMul1OP_res_high);
1188 new_node = gen_binop(node, op1, op2, new_rd_ia32_Mul, match_commutative | match_am);
1189 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1190 mode_Iu, pn_ia32_Mul_res_high);
1192 return proj_res_high;
1196 * Creates an ia32 And.
1198 * @return The created ia32 And node
1200 static ir_node *gen_And(ir_node *node)
1202 ir_node *op1 = get_And_left(node);
1203 ir_node *op2 = get_And_right(node);
1204 assert(! mode_is_float(get_irn_mode(node)));
1206 /* is it a zero extension? */
1207 if (is_Const(op2)) {
1208 tarval *tv = get_Const_tarval(op2);
1209 long v = get_tarval_long(tv);
1211 if (v == 0xFF || v == 0xFFFF) {
1212 dbg_info *dbgi = get_irn_dbg_info(node);
1213 ir_node *block = get_nodes_block(node);
1220 assert(v == 0xFFFF);
1223 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1228 return gen_binop(node, op1, op2, new_rd_ia32_And,
1229 match_commutative | match_mode_neutral | match_am
1236 * Creates an ia32 Or.
1238 * @return The created ia32 Or node
1240 static ir_node *gen_Or(ir_node *node)
1242 ir_node *op1 = get_Or_left(node);
1243 ir_node *op2 = get_Or_right(node);
1245 assert (! mode_is_float(get_irn_mode(node)));
1246 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1247 | match_mode_neutral | match_am | match_immediate);
1253 * Creates an ia32 Eor.
1255 * @return The created ia32 Eor node
1257 static ir_node *gen_Eor(ir_node *node)
1259 ir_node *op1 = get_Eor_left(node);
1260 ir_node *op2 = get_Eor_right(node);
1262 assert(! mode_is_float(get_irn_mode(node)));
1263 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1264 | match_mode_neutral | match_am | match_immediate);
1269 * Creates an ia32 Sub.
1271 * @return The created ia32 Sub node
1273 static ir_node *gen_Sub(ir_node *node)
1275 ir_node *op1 = get_Sub_left(node);
1276 ir_node *op2 = get_Sub_right(node);
1277 ir_mode *mode = get_irn_mode(node);
1279 if (mode_is_float(mode)) {
1280 if (ia32_cg_config.use_sse2)
1281 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1283 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub);
1286 if (is_Const(op2)) {
1287 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1291 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1292 | match_am | match_immediate);
1295 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1296 ir_node *const src_val,
1297 ir_node *const src_mem,
1298 ir_node *const am_mem)
1300 if (is_NoMem(am_mem)) {
1301 return be_transform_node(src_mem);
1302 } else if (is_Proj(src_val) &&
1304 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1305 /* avoid memory loop */
1307 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1308 ir_node *const ptr_pred = get_Proj_pred(src_val);
1309 int const arity = get_Sync_n_preds(src_mem);
1314 NEW_ARR_A(ir_node*, ins, arity + 1);
1316 for (i = arity - 1; i >= 0; --i) {
1317 ir_node *const pred = get_Sync_pred(src_mem, i);
1319 /* avoid memory loop */
1320 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1323 ins[n++] = be_transform_node(pred);
1328 return new_r_Sync(irg, block, n, ins);
1332 ins[0] = be_transform_node(src_mem);
1334 return new_r_Sync(irg, block, 2, ins);
1339 * Generates an ia32 DivMod with additional infrastructure for the
1340 * register allocator if needed.
1342 static ir_node *create_Div(ir_node *node)
1344 ir_graph *irg = current_ir_graph;
1345 dbg_info *dbgi = get_irn_dbg_info(node);
1346 ir_node *block = get_nodes_block(node);
1347 ir_node *new_block = be_transform_node(block);
1354 ir_node *sign_extension;
1355 ia32_address_mode_t am;
1356 ia32_address_t *addr = &am.addr;
1358 /* the upper bits have random contents for smaller modes */
1359 switch (get_irn_opcode(node)) {
1361 op1 = get_Div_left(node);
1362 op2 = get_Div_right(node);
1363 mem = get_Div_mem(node);
1364 mode = get_Div_resmode(node);
1367 op1 = get_Mod_left(node);
1368 op2 = get_Mod_right(node);
1369 mem = get_Mod_mem(node);
1370 mode = get_Mod_resmode(node);
1373 op1 = get_DivMod_left(node);
1374 op2 = get_DivMod_right(node);
1375 mem = get_DivMod_mem(node);
1376 mode = get_DivMod_resmode(node);
1379 panic("invalid divmod node %+F", node);
1382 match_arguments(&am, block, op1, op2, NULL, match_am);
1384 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1385 is the memory of the consumed address. We can have only the second op as address
1386 in Div nodes, so check only op2. */
1387 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1389 if (mode_is_signed(mode)) {
1390 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1391 be_dep_on_frame(produceval);
1392 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1395 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1396 addr->index, new_mem, am.new_op2,
1397 am.new_op1, sign_extension);
1399 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1400 be_dep_on_frame(sign_extension);
1402 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1403 addr->index, new_mem, am.new_op2,
1404 am.new_op1, sign_extension);
1407 set_irn_pinned(new_node, get_irn_pinned(node));
1409 set_am_attributes(new_node, &am);
1410 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1412 new_node = fix_mem_proj(new_node, &am);
1418 static ir_node *gen_Mod(ir_node *node)
1420 return create_Div(node);
1423 static ir_node *gen_Div(ir_node *node)
1425 return create_Div(node);
1428 static ir_node *gen_DivMod(ir_node *node)
1430 return create_Div(node);
1436 * Creates an ia32 floating Div.
1438 * @return The created ia32 xDiv node
1440 static ir_node *gen_Quot(ir_node *node)
1442 ir_node *op1 = get_Quot_left(node);
1443 ir_node *op2 = get_Quot_right(node);
1445 if (ia32_cg_config.use_sse2) {
1446 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1448 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv);
1454 * Creates an ia32 Shl.
1456 * @return The created ia32 Shl node
1458 static ir_node *gen_Shl(ir_node *node)
1460 ir_node *left = get_Shl_left(node);
1461 ir_node *right = get_Shl_right(node);
1463 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1464 match_mode_neutral | match_immediate);
1468 * Creates an ia32 Shr.
1470 * @return The created ia32 Shr node
1472 static ir_node *gen_Shr(ir_node *node)
1474 ir_node *left = get_Shr_left(node);
1475 ir_node *right = get_Shr_right(node);
1477 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1483 * Creates an ia32 Sar.
1485 * @return The created ia32 Shrs node
1487 static ir_node *gen_Shrs(ir_node *node)
1489 ir_node *left = get_Shrs_left(node);
1490 ir_node *right = get_Shrs_right(node);
1491 ir_mode *mode = get_irn_mode(node);
1493 if (is_Const(right) && mode == mode_Is) {
1494 tarval *tv = get_Const_tarval(right);
1495 long val = get_tarval_long(tv);
1497 /* this is a sign extension */
1498 ir_graph *irg = current_ir_graph;
1499 dbg_info *dbgi = get_irn_dbg_info(node);
1500 ir_node *block = be_transform_node(get_nodes_block(node));
1502 ir_node *new_op = be_transform_node(op);
1503 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1505 be_dep_on_frame(pval);
1506 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1510 /* 8 or 16 bit sign extension? */
1511 if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1512 ir_node *shl_left = get_Shl_left(left);
1513 ir_node *shl_right = get_Shl_right(left);
1514 if (is_Const(shl_right)) {
1515 tarval *tv1 = get_Const_tarval(right);
1516 tarval *tv2 = get_Const_tarval(shl_right);
1517 if (tv1 == tv2 && tarval_is_long(tv1)) {
1518 long val = get_tarval_long(tv1);
1519 if (val == 16 || val == 24) {
1520 dbg_info *dbgi = get_irn_dbg_info(node);
1521 ir_node *block = get_nodes_block(node);
1531 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1540 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1546 * Creates an ia32 Rol.
1548 * @param op1 The first operator
1549 * @param op2 The second operator
1550 * @return The created ia32 RotL node
1552 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1554 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1560 * Creates an ia32 Ror.
1561 * NOTE: There is no RotR with immediate because this would always be a RotL
1562 * "imm-mode_size_bits" which can be pre-calculated.
1564 * @param op1 The first operator
1565 * @param op2 The second operator
1566 * @return The created ia32 RotR node
1568 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1570 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1576 * Creates an ia32 RotR or RotL (depending on the found pattern).
1578 * @return The created ia32 RotL or RotR node
1580 static ir_node *gen_Rotl(ir_node *node)
1582 ir_node *rotate = NULL;
1583 ir_node *op1 = get_Rotl_left(node);
1584 ir_node *op2 = get_Rotl_right(node);
1586 /* Firm has only RotL, so we are looking for a right (op2)
1587 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1588 that means we can create a RotR instead of an Add and a RotL */
1592 ir_node *left = get_Add_left(add);
1593 ir_node *right = get_Add_right(add);
1594 if (is_Const(right)) {
1595 tarval *tv = get_Const_tarval(right);
1596 ir_mode *mode = get_irn_mode(node);
1597 long bits = get_mode_size_bits(mode);
1599 if (is_Minus(left) &&
1600 tarval_is_long(tv) &&
1601 get_tarval_long(tv) == bits &&
1604 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1605 rotate = gen_Ror(node, op1, get_Minus_op(left));
1610 if (rotate == NULL) {
1611 rotate = gen_Rol(node, op1, op2);
1620 * Transforms a Minus node.
1622 * @return The created ia32 Minus node
1624 static ir_node *gen_Minus(ir_node *node)
1626 ir_node *op = get_Minus_op(node);
1627 ir_node *block = be_transform_node(get_nodes_block(node));
1628 ir_graph *irg = current_ir_graph;
1629 dbg_info *dbgi = get_irn_dbg_info(node);
1630 ir_mode *mode = get_irn_mode(node);
1635 if (mode_is_float(mode)) {
1636 ir_node *new_op = be_transform_node(op);
1637 if (ia32_cg_config.use_sse2) {
1638 /* TODO: non-optimal... if we have many xXors, then we should
1639 * rather create a load for the const and use that instead of
1640 * several AM nodes... */
1641 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1642 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1643 ir_node *nomem = new_rd_NoMem(irg);
1645 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1646 nomem, new_op, noreg_xmm);
1648 size = get_mode_size_bits(mode);
1649 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1651 set_ia32_am_sc(new_node, ent);
1652 set_ia32_op_type(new_node, ia32_AddrModeS);
1653 set_ia32_ls_mode(new_node, mode);
1655 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1658 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1661 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1667 * Transforms a Not node.
1669 * @return The created ia32 Not node
1671 static ir_node *gen_Not(ir_node *node)
1673 ir_node *op = get_Not_op(node);
1675 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1676 assert (! mode_is_float(get_irn_mode(node)));
1678 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1684 * Transforms an Abs node.
1686 * @return The created ia32 Abs node
1688 static ir_node *gen_Abs(ir_node *node)
1690 ir_node *block = get_nodes_block(node);
1691 ir_node *new_block = be_transform_node(block);
1692 ir_node *op = get_Abs_op(node);
1693 ir_graph *irg = current_ir_graph;
1694 dbg_info *dbgi = get_irn_dbg_info(node);
1695 ir_mode *mode = get_irn_mode(node);
1696 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1697 ir_node *nomem = new_NoMem();
1703 if (mode_is_float(mode)) {
1704 new_op = be_transform_node(op);
1706 if (ia32_cg_config.use_sse2) {
1707 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1708 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1709 nomem, new_op, noreg_fp);
1711 size = get_mode_size_bits(mode);
1712 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1714 set_ia32_am_sc(new_node, ent);
1716 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1718 set_ia32_op_type(new_node, ia32_AddrModeS);
1719 set_ia32_ls_mode(new_node, mode);
1721 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1722 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1725 ir_node *xor, *pval, *sign_extension;
1727 if (get_mode_size_bits(mode) == 32) {
1728 new_op = be_transform_node(op);
1730 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1733 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1734 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1737 be_dep_on_frame(pval);
1738 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1740 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1741 nomem, new_op, sign_extension);
1742 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1744 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1745 nomem, xor, sign_extension);
1746 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1753 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1755 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1757 dbg_info *dbgi = get_irn_dbg_info(cmp);
1758 ir_node *block = get_nodes_block(cmp);
1759 ir_node *new_block = be_transform_node(block);
1760 ir_node *op1 = be_transform_node(x);
1761 ir_node *op2 = be_transform_node(n);
1763 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1767 * Transform a node returning a "flag" result.
1769 * @param node the node to transform
1770 * @param pnc_out the compare mode to use
1772 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1781 /* we have a Cmp as input */
1782 if (is_Proj(node)) {
1783 ir_node *pred = get_Proj_pred(node);
1785 pn_Cmp pnc = get_Proj_proj(node);
1786 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1787 ir_node *l = get_Cmp_left(pred);
1788 ir_node *r = get_Cmp_right(pred);
1790 ir_node *la = get_And_left(l);
1791 ir_node *ra = get_And_right(l);
1793 ir_node *c = get_Shl_left(la);
1794 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1795 /* (1 << n) & ra) */
1796 ir_node *n = get_Shl_right(la);
1797 flags = gen_bt(pred, ra, n);
1798 /* we must generate a Jc/Jnc jump */
1799 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1802 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1807 ir_node *c = get_Shl_left(ra);
1808 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1809 /* la & (1 << n)) */
1810 ir_node *n = get_Shl_right(ra);
1811 flags = gen_bt(pred, la, n);
1812 /* we must generate a Jc/Jnc jump */
1813 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1816 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1822 flags = be_transform_node(pred);
1828 /* a mode_b value, we have to compare it against 0 */
1829 dbgi = get_irn_dbg_info(node);
1830 new_block = be_transform_node(get_nodes_block(node));
1831 new_op = be_transform_node(node);
1832 noreg = ia32_new_NoReg_gp(env_cg);
1833 nomem = new_NoMem();
1834 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1835 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1836 *pnc_out = pn_Cmp_Lg;
1841 * Transforms a Load.
1843 * @return the created ia32 Load node
1845 static ir_node *gen_Load(ir_node *node)
1847 ir_node *old_block = get_nodes_block(node);
1848 ir_node *block = be_transform_node(old_block);
1849 ir_node *ptr = get_Load_ptr(node);
1850 ir_node *mem = get_Load_mem(node);
1851 ir_node *new_mem = be_transform_node(mem);
1854 ir_graph *irg = current_ir_graph;
1855 dbg_info *dbgi = get_irn_dbg_info(node);
1856 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1857 ir_mode *mode = get_Load_mode(node);
1860 ia32_address_t addr;
1862 /* construct load address */
1863 memset(&addr, 0, sizeof(addr));
1864 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1871 base = be_transform_node(base);
1874 if (index == NULL) {
1877 index = be_transform_node(index);
1880 if (mode_is_float(mode)) {
1881 if (ia32_cg_config.use_sse2) {
1882 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1884 res_mode = mode_xmm;
1886 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1888 res_mode = mode_vfp;
1891 assert(mode != mode_b);
1893 /* create a conv node with address mode for smaller modes */
1894 if (get_mode_size_bits(mode) < 32) {
1895 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1896 new_mem, noreg, mode);
1898 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1903 set_irn_pinned(new_node, get_irn_pinned(node));
1904 set_ia32_op_type(new_node, ia32_AddrModeS);
1905 set_ia32_ls_mode(new_node, mode);
1906 set_address(new_node, &addr);
1908 if (get_irn_pinned(node) == op_pin_state_floats) {
1909 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1912 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1914 be_dep_on_frame(new_node);
1918 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1919 ir_node *ptr, ir_node *other)
1926 /* we only use address mode if we're the only user of the load */
1927 if (get_irn_n_edges(node) > 1)
1930 load = get_Proj_pred(node);
1933 if (get_nodes_block(load) != block)
1936 /* store should have the same pointer as the load */
1937 if (get_Load_ptr(load) != ptr)
1940 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1941 if (other != NULL &&
1942 get_nodes_block(other) == block &&
1943 heights_reachable_in_block(heights, other, load)) {
1950 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
1951 ir_node *const pred = get_Sync_pred(mem, i);
1953 if (is_Proj(pred) && get_Proj_pred(pred) == load)
1956 if (get_nodes_block(pred) == block &&
1957 heights_reachable_in_block(heights, pred, load)) {
1962 /* Store should be attached to the load */
1963 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
1970 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1971 ir_node *mem, ir_node *ptr, ir_mode *mode,
1972 construct_binop_dest_func *func,
1973 construct_binop_dest_func *func8bit,
1974 match_flags_t flags)
1976 ir_node *src_block = get_nodes_block(node);
1978 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1979 ir_graph *irg = current_ir_graph;
1986 ia32_address_mode_t am;
1987 ia32_address_t *addr = &am.addr;
1988 memset(&am, 0, sizeof(am));
1990 assert(flags & match_dest_am);
1991 assert(flags & match_immediate); /* there is no destam node without... */
1992 commutative = (flags & match_commutative) != 0;
1994 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1995 build_address(&am, op1);
1996 new_op = create_immediate_or_transform(op2, 0);
1997 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1998 build_address(&am, op2);
1999 new_op = create_immediate_or_transform(op1, 0);
2004 if (addr->base == NULL)
2005 addr->base = noreg_gp;
2006 if (addr->index == NULL)
2007 addr->index = noreg_gp;
2008 if (addr->mem == NULL)
2009 addr->mem = new_NoMem();
2011 dbgi = get_irn_dbg_info(node);
2012 block = be_transform_node(src_block);
2013 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2015 if (get_mode_size_bits(mode) == 8) {
2016 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2019 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
2022 set_address(new_node, addr);
2023 set_ia32_op_type(new_node, ia32_AddrModeD);
2024 set_ia32_ls_mode(new_node, mode);
2025 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2027 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2028 mem_proj = be_transform_node(am.mem_proj);
2029 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2034 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2035 ir_node *ptr, ir_mode *mode,
2036 construct_unop_dest_func *func)
2038 ir_graph *irg = current_ir_graph;
2039 ir_node *src_block = get_nodes_block(node);
2045 ia32_address_mode_t am;
2046 ia32_address_t *addr = &am.addr;
2047 memset(&am, 0, sizeof(am));
2049 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2052 build_address(&am, op);
2054 dbgi = get_irn_dbg_info(node);
2055 block = be_transform_node(src_block);
2056 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2057 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2058 set_address(new_node, addr);
2059 set_ia32_op_type(new_node, ia32_AddrModeD);
2060 set_ia32_ls_mode(new_node, mode);
2061 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2063 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2064 mem_proj = be_transform_node(am.mem_proj);
2065 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2070 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2072 ir_mode *mode = get_irn_mode(node);
2073 ir_node *mux_true = get_Mux_true(node);
2074 ir_node *mux_false = get_Mux_false(node);
2085 ia32_address_t addr;
2087 if (get_mode_size_bits(mode) != 8)
2090 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2092 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2098 build_address_ptr(&addr, ptr, mem);
2100 irg = current_ir_graph;
2101 dbgi = get_irn_dbg_info(node);
2102 block = get_nodes_block(node);
2103 new_block = be_transform_node(block);
2104 cond = get_Mux_sel(node);
2105 flags = get_flags_node(cond, &pnc);
2106 new_mem = be_transform_node(mem);
2107 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2108 addr.index, addr.mem, flags, pnc, negated);
2109 set_address(new_node, &addr);
2110 set_ia32_op_type(new_node, ia32_AddrModeD);
2111 set_ia32_ls_mode(new_node, mode);
2112 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2117 static ir_node *try_create_dest_am(ir_node *node)
2119 ir_node *val = get_Store_value(node);
2120 ir_node *mem = get_Store_mem(node);
2121 ir_node *ptr = get_Store_ptr(node);
2122 ir_mode *mode = get_irn_mode(val);
2123 unsigned bits = get_mode_size_bits(mode);
2128 /* handle only GP modes for now... */
2129 if (!ia32_mode_needs_gp_reg(mode))
2133 /* store must be the only user of the val node */
2134 if (get_irn_n_edges(val) > 1)
2136 /* skip pointless convs */
2138 ir_node *conv_op = get_Conv_op(val);
2139 ir_mode *pred_mode = get_irn_mode(conv_op);
2140 if (!ia32_mode_needs_gp_reg(pred_mode))
2142 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2150 /* value must be in the same block */
2151 if (get_nodes_block(node) != get_nodes_block(val))
2154 switch (get_irn_opcode(val)) {
2156 op1 = get_Add_left(val);
2157 op2 = get_Add_right(val);
2158 if (is_Const_1(op2)) {
2159 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2160 new_rd_ia32_IncMem);
2162 } else if (is_Const_Minus_1(op2)) {
2163 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2164 new_rd_ia32_DecMem);
2167 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2168 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2169 match_dest_am | match_commutative |
2173 op1 = get_Sub_left(val);
2174 op2 = get_Sub_right(val);
2175 if (is_Const(op2)) {
2176 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2178 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2179 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2180 match_dest_am | match_immediate |
2184 op1 = get_And_left(val);
2185 op2 = get_And_right(val);
2186 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2187 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2188 match_dest_am | match_commutative |
2192 op1 = get_Or_left(val);
2193 op2 = get_Or_right(val);
2194 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2195 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2196 match_dest_am | match_commutative |
2200 op1 = get_Eor_left(val);
2201 op2 = get_Eor_right(val);
2202 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2203 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2204 match_dest_am | match_commutative |
2208 op1 = get_Shl_left(val);
2209 op2 = get_Shl_right(val);
2210 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2211 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2212 match_dest_am | match_immediate);
2215 op1 = get_Shr_left(val);
2216 op2 = get_Shr_right(val);
2217 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2218 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2219 match_dest_am | match_immediate);
2222 op1 = get_Shrs_left(val);
2223 op2 = get_Shrs_right(val);
2224 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2225 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2226 match_dest_am | match_immediate);
2229 op1 = get_Rotl_left(val);
2230 op2 = get_Rotl_right(val);
2231 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2232 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2233 match_dest_am | match_immediate);
2235 /* TODO: match ROR patterns... */
2237 new_node = try_create_SetMem(val, ptr, mem);
2240 op1 = get_Minus_op(val);
2241 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2244 /* should be lowered already */
2245 assert(mode != mode_b);
2246 op1 = get_Not_op(val);
2247 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2253 if (new_node != NULL) {
2254 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2255 get_irn_pinned(node) == op_pin_state_pinned) {
2256 set_irn_pinned(new_node, op_pin_state_pinned);
2263 static int is_float_to_int_conv(const ir_node *node)
2265 ir_mode *mode = get_irn_mode(node);
2269 if (mode != mode_Is && mode != mode_Hs)
2274 conv_op = get_Conv_op(node);
2275 conv_mode = get_irn_mode(conv_op);
2277 if (!mode_is_float(conv_mode))
2284 * Transform a Store(floatConst).
2286 * @return the created ia32 Store node
2288 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2290 ir_mode *mode = get_irn_mode(cns);
2291 unsigned size = get_mode_size_bytes(mode);
2292 tarval *tv = get_Const_tarval(cns);
2293 ir_node *block = get_nodes_block(node);
2294 ir_node *new_block = be_transform_node(block);
2295 ir_node *ptr = get_Store_ptr(node);
2296 ir_node *mem = get_Store_mem(node);
2297 ir_graph *irg = current_ir_graph;
2298 dbg_info *dbgi = get_irn_dbg_info(node);
2302 ia32_address_t addr;
2304 assert(size % 4 == 0);
2307 build_address_ptr(&addr, ptr, mem);
2311 get_tarval_sub_bits(tv, ofs) |
2312 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2313 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2314 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2315 ir_node *imm = create_Immediate(NULL, 0, val);
2317 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2318 addr.index, addr.mem, imm);
2320 set_irn_pinned(new_node, get_irn_pinned(node));
2321 set_ia32_op_type(new_node, ia32_AddrModeD);
2322 set_ia32_ls_mode(new_node, mode_Iu);
2323 set_address(new_node, &addr);
2324 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2326 ins[i++] = new_node;
2331 } while (size != 0);
2333 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2337 * Generate a vfist or vfisttp instruction.
2339 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2340 ir_node *mem, ir_node *val, ir_node **fist)
2344 if (ia32_cg_config.use_fisttp) {
2345 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2346 if other users exists */
2347 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2348 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2349 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2350 be_new_Keep(reg_class, irg, block, 1, &value);
2352 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2355 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2358 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2364 * Transforms a normal Store.
2366 * @return the created ia32 Store node
2368 static ir_node *gen_normal_Store(ir_node *node)
2370 ir_node *val = get_Store_value(node);
2371 ir_mode *mode = get_irn_mode(val);
2372 ir_node *block = get_nodes_block(node);
2373 ir_node *new_block = be_transform_node(block);
2374 ir_node *ptr = get_Store_ptr(node);
2375 ir_node *mem = get_Store_mem(node);
2376 ir_graph *irg = current_ir_graph;
2377 dbg_info *dbgi = get_irn_dbg_info(node);
2378 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2379 ir_node *new_val, *new_node, *store;
2380 ia32_address_t addr;
2382 /* check for destination address mode */
2383 new_node = try_create_dest_am(node);
2384 if (new_node != NULL)
2387 /* construct store address */
2388 memset(&addr, 0, sizeof(addr));
2389 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2391 if (addr.base == NULL) {
2394 addr.base = be_transform_node(addr.base);
2397 if (addr.index == NULL) {
2400 addr.index = be_transform_node(addr.index);
2402 addr.mem = be_transform_node(mem);
2404 if (mode_is_float(mode)) {
2405 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2407 while (is_Conv(val) && mode == get_irn_mode(val)) {
2408 ir_node *op = get_Conv_op(val);
2409 if (!mode_is_float(get_irn_mode(op)))
2413 new_val = be_transform_node(val);
2414 if (ia32_cg_config.use_sse2) {
2415 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2416 addr.index, addr.mem, new_val);
2418 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2419 addr.index, addr.mem, new_val, mode);
2422 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2423 val = get_Conv_op(val);
2425 /* TODO: is this optimisation still necessary at all (middleend)? */
2426 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2427 while (is_Conv(val)) {
2428 ir_node *op = get_Conv_op(val);
2429 if (!mode_is_float(get_irn_mode(op)))
2431 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2435 new_val = be_transform_node(val);
2436 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2438 new_val = create_immediate_or_transform(val, 0);
2439 assert(mode != mode_b);
2441 if (get_mode_size_bits(mode) == 8) {
2442 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2443 addr.index, addr.mem, new_val);
2445 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2446 addr.index, addr.mem, new_val);
2451 set_irn_pinned(store, get_irn_pinned(node));
2452 set_ia32_op_type(store, ia32_AddrModeD);
2453 set_ia32_ls_mode(store, mode);
2455 set_address(store, &addr);
2456 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2462 * Transforms a Store.
2464 * @return the created ia32 Store node
2466 static ir_node *gen_Store(ir_node *node)
2468 ir_node *val = get_Store_value(node);
2469 ir_mode *mode = get_irn_mode(val);
2471 if (mode_is_float(mode) && is_Const(val)) {
2474 /* we are storing a floating point constant */
2475 if (ia32_cg_config.use_sse2) {
2476 transform = !is_simple_sse_Const(val);
2478 transform = !is_simple_x87_Const(val);
2481 return gen_float_const_Store(node, val);
2483 return gen_normal_Store(node);
2487 * Transforms a Switch.
2489 * @return the created ia32 SwitchJmp node
2491 static ir_node *create_Switch(ir_node *node)
2493 ir_graph *irg = current_ir_graph;
2494 dbg_info *dbgi = get_irn_dbg_info(node);
2495 ir_node *block = be_transform_node(get_nodes_block(node));
2496 ir_node *sel = get_Cond_selector(node);
2497 ir_node *new_sel = be_transform_node(sel);
2498 int switch_min = INT_MAX;
2499 int switch_max = INT_MIN;
2500 long default_pn = get_Cond_defaultProj(node);
2502 const ir_edge_t *edge;
2504 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2506 /* determine the smallest switch case value */
2507 foreach_out_edge(node, edge) {
2508 ir_node *proj = get_edge_src_irn(edge);
2509 long pn = get_Proj_proj(proj);
2510 if (pn == default_pn)
2513 if (pn < switch_min)
2515 if (pn > switch_max)
2519 if ((unsigned) (switch_max - switch_min) > 256000) {
2520 panic("Size of switch %+F bigger than 256000", node);
2523 if (switch_min != 0) {
2524 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2526 /* if smallest switch case is not 0 we need an additional sub */
2527 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2528 add_ia32_am_offs_int(new_sel, -switch_min);
2529 set_ia32_op_type(new_sel, ia32_AddrModeS);
2531 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2534 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2535 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2541 * Transform a Cond node.
2543 static ir_node *gen_Cond(ir_node *node)
2545 ir_node *block = get_nodes_block(node);
2546 ir_node *new_block = be_transform_node(block);
2547 ir_graph *irg = current_ir_graph;
2548 dbg_info *dbgi = get_irn_dbg_info(node);
2549 ir_node *sel = get_Cond_selector(node);
2550 ir_mode *sel_mode = get_irn_mode(sel);
2551 ir_node *flags = NULL;
2555 if (sel_mode != mode_b) {
2556 return create_Switch(node);
2559 /* we get flags from a Cmp */
2560 flags = get_flags_node(sel, &pnc);
2562 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2563 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2568 static ir_node *gen_be_Copy(ir_node *node)
2570 ir_node *new_node = be_duplicate_node(node);
2571 ir_mode *mode = get_irn_mode(new_node);
2573 if (ia32_mode_needs_gp_reg(mode)) {
2574 set_irn_mode(new_node, mode_Iu);
2580 static ir_node *create_Fucom(ir_node *node)
2582 ir_graph *irg = current_ir_graph;
2583 dbg_info *dbgi = get_irn_dbg_info(node);
2584 ir_node *block = get_nodes_block(node);
2585 ir_node *new_block = be_transform_node(block);
2586 ir_node *left = get_Cmp_left(node);
2587 ir_node *new_left = be_transform_node(left);
2588 ir_node *right = get_Cmp_right(node);
2592 if (ia32_cg_config.use_fucomi) {
2593 new_right = be_transform_node(right);
2594 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2596 set_ia32_commutative(new_node);
2597 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2599 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2600 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2603 new_right = be_transform_node(right);
2604 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2608 set_ia32_commutative(new_node);
2610 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2612 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2613 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2619 static ir_node *create_Ucomi(ir_node *node)
2621 ir_graph *irg = current_ir_graph;
2622 dbg_info *dbgi = get_irn_dbg_info(node);
2623 ir_node *src_block = get_nodes_block(node);
2624 ir_node *new_block = be_transform_node(src_block);
2625 ir_node *left = get_Cmp_left(node);
2626 ir_node *right = get_Cmp_right(node);
2628 ia32_address_mode_t am;
2629 ia32_address_t *addr = &am.addr;
2631 match_arguments(&am, src_block, left, right, NULL,
2632 match_commutative | match_am);
2634 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2635 addr->mem, am.new_op1, am.new_op2,
2637 set_am_attributes(new_node, &am);
2639 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2641 new_node = fix_mem_proj(new_node, &am);
2647 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2648 * to fold an and into a test node
2650 static bool can_fold_test_and(ir_node *node)
2652 const ir_edge_t *edge;
2654 /** we can only have eq and lg projs */
2655 foreach_out_edge(node, edge) {
2656 ir_node *proj = get_edge_src_irn(edge);
2657 pn_Cmp pnc = get_Proj_proj(proj);
2658 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2666 * returns true if it is assured, that the upper bits of a node are "clean"
2667 * which means for a 16 or 8 bit value, that the upper bits in the register
2668 * are 0 for unsigned and a copy of the last significant bit for signed
2671 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2673 assert(ia32_mode_needs_gp_reg(mode));
2674 if (get_mode_size_bits(mode) >= 32)
2677 if (is_Proj(transformed_node))
2678 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2680 if (is_ia32_Conv_I2I(transformed_node)
2681 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2682 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2683 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2685 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2691 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2692 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2693 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2694 const ia32_immediate_attr_t *attr
2695 = get_ia32_immediate_attr_const(right);
2696 if (attr->symconst == 0
2697 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2701 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2704 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2705 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2706 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2707 const ia32_immediate_attr_t *attr
2708 = get_ia32_immediate_attr_const(right);
2709 if (attr->symconst == 0
2710 && (unsigned) attr->offset
2711 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2718 /* TODO recurse on Or, Xor, ... if appropriate? */
2720 if (is_ia32_Immediate(transformed_node)
2721 || is_ia32_Const(transformed_node)) {
2722 const ia32_immediate_attr_t *attr
2723 = get_ia32_immediate_attr_const(transformed_node);
2724 if (mode_is_signed(mode)) {
2725 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2726 if (shifted == 0 || shifted == -1)
2729 unsigned long shifted = (unsigned long) attr->offset;
2730 shifted >>= get_mode_size_bits(mode);
2740 * Generate code for a Cmp.
2742 static ir_node *gen_Cmp(ir_node *node)
2744 ir_graph *irg = current_ir_graph;
2745 dbg_info *dbgi = get_irn_dbg_info(node);
2746 ir_node *block = get_nodes_block(node);
2747 ir_node *new_block = be_transform_node(block);
2748 ir_node *left = get_Cmp_left(node);
2749 ir_node *right = get_Cmp_right(node);
2750 ir_mode *cmp_mode = get_irn_mode(left);
2752 ia32_address_mode_t am;
2753 ia32_address_t *addr = &am.addr;
2756 if (mode_is_float(cmp_mode)) {
2757 if (ia32_cg_config.use_sse2) {
2758 return create_Ucomi(node);
2760 return create_Fucom(node);
2764 assert(ia32_mode_needs_gp_reg(cmp_mode));
2766 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2767 cmp_unsigned = !mode_is_signed(cmp_mode);
2768 if (is_Const_0(right) &&
2770 get_irn_n_edges(left) == 1 &&
2771 can_fold_test_and(node)) {
2772 /* Test(and_left, and_right) */
2773 ir_node *and_left = get_And_left(left);
2774 ir_node *and_right = get_And_right(left);
2776 /* matze: code here used mode instead of cmd_mode, I think it is always
2777 * the same as cmp_mode, but I leave this here to see if this is really
2780 assert(get_irn_mode(and_left) == cmp_mode);
2782 match_arguments(&am, block, and_left, and_right, NULL,
2784 match_am | match_8bit_am | match_16bit_am |
2785 match_am_and_immediates | match_immediate |
2786 match_8bit | match_16bit);
2788 /* use 32bit compare mode if possible since the opcode is smaller */
2789 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2790 upper_bits_clean(am.new_op2, cmp_mode)) {
2791 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2794 if (get_mode_size_bits(cmp_mode) == 8) {
2795 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2796 addr->index, addr->mem, am.new_op1,
2797 am.new_op2, am.ins_permuted,
2800 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2801 addr->index, addr->mem, am.new_op1,
2802 am.new_op2, am.ins_permuted,
2806 /* Cmp(left, right) */
2807 match_arguments(&am, block, left, right, NULL,
2808 match_commutative | match_am | match_8bit_am |
2809 match_16bit_am | match_am_and_immediates |
2810 match_immediate | match_8bit | match_16bit);
2811 /* use 32bit compare mode if possible since the opcode is smaller */
2812 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2813 upper_bits_clean(am.new_op2, cmp_mode)) {
2814 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2817 if (get_mode_size_bits(cmp_mode) == 8) {
2818 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2819 addr->index, addr->mem, am.new_op1,
2820 am.new_op2, am.ins_permuted,
2823 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2824 addr->index, addr->mem, am.new_op1,
2825 am.new_op2, am.ins_permuted, cmp_unsigned);
2828 set_am_attributes(new_node, &am);
2829 set_ia32_ls_mode(new_node, cmp_mode);
2831 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2833 new_node = fix_mem_proj(new_node, &am);
2838 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2841 ir_graph *irg = current_ir_graph;
2842 dbg_info *dbgi = get_irn_dbg_info(node);
2843 ir_node *block = get_nodes_block(node);
2844 ir_node *new_block = be_transform_node(block);
2845 ir_node *val_true = get_Mux_true(node);
2846 ir_node *val_false = get_Mux_false(node);
2848 match_flags_t match_flags;
2849 ia32_address_mode_t am;
2850 ia32_address_t *addr;
2852 assert(ia32_cg_config.use_cmov);
2853 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2857 match_flags = match_commutative | match_am | match_16bit_am |
2860 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2862 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2863 addr->mem, am.new_op1, am.new_op2, new_flags,
2864 am.ins_permuted, pnc);
2865 set_am_attributes(new_node, &am);
2867 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2869 new_node = fix_mem_proj(new_node, &am);
2875 * Creates a ia32 Setcc instruction.
2877 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2878 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2881 ir_graph *irg = current_ir_graph;
2882 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2883 ir_node *nomem = new_NoMem();
2884 ir_mode *mode = get_irn_mode(orig_node);
2887 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2888 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2890 /* we might need to conv the result up */
2891 if (get_mode_size_bits(mode) > 8) {
2892 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2893 nomem, new_node, mode_Bu);
2894 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2901 * Create instruction for an unsigned Difference or Zero.
2903 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2905 ir_graph *irg = current_ir_graph;
2906 ir_mode *mode = get_irn_mode(psi);
2907 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2910 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2911 match_mode_neutral | match_am | match_immediate | match_two_users);
2913 block = get_nodes_block(new_node);
2915 if (is_Proj(new_node)) {
2916 sub = get_Proj_pred(new_node);
2917 assert(is_ia32_Sub(sub));
2920 set_irn_mode(sub, mode_T);
2921 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2923 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2925 dbgi = get_irn_dbg_info(psi);
2926 noreg = ia32_new_NoReg_gp(env_cg);
2927 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2928 nomem = new_NoMem();
2929 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2931 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2932 set_ia32_commutative(new_node);
2937 * Transforms a Mux node into CMov.
2939 * @return The transformed node.
2941 static ir_node *gen_Mux(ir_node *node)
2943 dbg_info *dbgi = get_irn_dbg_info(node);
2944 ir_node *block = get_nodes_block(node);
2945 ir_node *new_block = be_transform_node(block);
2946 ir_node *mux_true = get_Mux_true(node);
2947 ir_node *mux_false = get_Mux_false(node);
2948 ir_node *cond = get_Mux_sel(node);
2949 ir_mode *mode = get_irn_mode(node);
2952 assert(get_irn_mode(cond) == mode_b);
2954 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2955 if (mode_is_float(mode)) {
2956 ir_node *cmp = get_Proj_pred(cond);
2957 ir_node *cmp_left = get_Cmp_left(cmp);
2958 ir_node *cmp_right = get_Cmp_right(cmp);
2959 pn_Cmp pnc = get_Proj_proj(cond);
2961 if (ia32_cg_config.use_sse2) {
2962 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2963 if (cmp_left == mux_true && cmp_right == mux_false) {
2964 /* Mux(a <= b, a, b) => MIN */
2965 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2966 match_commutative | match_am | match_two_users);
2967 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2968 /* Mux(a <= b, b, a) => MAX */
2969 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2970 match_commutative | match_am | match_two_users);
2972 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2973 if (cmp_left == mux_true && cmp_right == mux_false) {
2974 /* Mux(a >= b, a, b) => MAX */
2975 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2976 match_commutative | match_am | match_two_users);
2977 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2978 /* Mux(a >= b, b, a) => MIN */
2979 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2980 match_commutative | match_am | match_two_users);
2984 panic("cannot transform floating point Mux");
2990 assert(ia32_mode_needs_gp_reg(mode));
2992 if (is_Proj(cond)) {
2993 ir_node *cmp = get_Proj_pred(cond);
2995 ir_node *cmp_left = get_Cmp_left(cmp);
2996 ir_node *cmp_right = get_Cmp_right(cmp);
2997 pn_Cmp pnc = get_Proj_proj(cond);
2999 /* check for unsigned Doz first */
3000 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3001 is_Const_0(mux_false) && is_Sub(mux_true) &&
3002 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3003 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3004 return create_Doz(node, cmp_left, cmp_right);
3005 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3006 is_Const_0(mux_true) && is_Sub(mux_false) &&
3007 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3008 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3009 return create_Doz(node, cmp_left, cmp_right);
3014 flags = get_flags_node(cond, &pnc);
3016 if (is_Const(mux_true) && is_Const(mux_false)) {
3017 /* both are const, good */
3018 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3019 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3020 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3021 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3023 /* Not that simple. */
3028 new_node = create_CMov(node, cond, flags, pnc);
3036 * Create a conversion from x87 state register to general purpose.
3038 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3040 ir_node *block = be_transform_node(get_nodes_block(node));
3041 ir_node *op = get_Conv_op(node);
3042 ir_node *new_op = be_transform_node(op);
3043 ia32_code_gen_t *cg = env_cg;
3044 ir_graph *irg = current_ir_graph;
3045 dbg_info *dbgi = get_irn_dbg_info(node);
3046 ir_node *noreg = ia32_new_NoReg_gp(cg);
3047 ir_mode *mode = get_irn_mode(node);
3048 ir_node *fist, *load, *mem;
3050 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3051 set_irn_pinned(fist, op_pin_state_floats);
3052 set_ia32_use_frame(fist);
3053 set_ia32_op_type(fist, ia32_AddrModeD);
3055 assert(get_mode_size_bits(mode) <= 32);
3056 /* exception we can only store signed 32 bit integers, so for unsigned
3057 we store a 64bit (signed) integer and load the lower bits */
3058 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3059 set_ia32_ls_mode(fist, mode_Ls);
3061 set_ia32_ls_mode(fist, mode_Is);
3063 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3066 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3068 set_irn_pinned(load, op_pin_state_floats);
3069 set_ia32_use_frame(load);
3070 set_ia32_op_type(load, ia32_AddrModeS);
3071 set_ia32_ls_mode(load, mode_Is);
3072 if (get_ia32_ls_mode(fist) == mode_Ls) {
3073 ia32_attr_t *attr = get_ia32_attr(load);
3074 attr->data.need_64bit_stackent = 1;
3076 ia32_attr_t *attr = get_ia32_attr(load);
3077 attr->data.need_32bit_stackent = 1;
3079 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3081 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3085 * Creates a x87 strict Conv by placing a Store and a Load
3087 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3089 ir_node *block = get_nodes_block(node);
3090 ir_graph *irg = current_ir_graph;
3091 dbg_info *dbgi = get_irn_dbg_info(node);
3092 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3093 ir_node *nomem = new_NoMem();
3094 ir_node *frame = get_irg_frame(irg);
3095 ir_node *store, *load;
3098 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3100 set_ia32_use_frame(store);
3101 set_ia32_op_type(store, ia32_AddrModeD);
3102 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3104 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3106 set_ia32_use_frame(load);
3107 set_ia32_op_type(load, ia32_AddrModeS);
3108 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3110 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3115 * Create a conversion from general purpose to x87 register
3117 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3119 ir_node *src_block = get_nodes_block(node);
3120 ir_node *block = be_transform_node(src_block);
3121 ir_graph *irg = current_ir_graph;
3122 dbg_info *dbgi = get_irn_dbg_info(node);
3123 ir_node *op = get_Conv_op(node);
3124 ir_node *new_op = NULL;
3128 ir_mode *store_mode;
3134 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3135 if (src_mode == mode_Is || src_mode == mode_Hs) {
3136 ia32_address_mode_t am;
3138 match_arguments(&am, src_block, NULL, op, NULL,
3139 match_am | match_try_am | match_16bit | match_16bit_am);
3140 if (am.op_type == ia32_AddrModeS) {
3141 ia32_address_t *addr = &am.addr;
3143 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3144 addr->index, addr->mem);
3145 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3148 set_am_attributes(fild, &am);
3149 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3151 fix_mem_proj(fild, &am);
3156 if (new_op == NULL) {
3157 new_op = be_transform_node(op);
3160 noreg = ia32_new_NoReg_gp(env_cg);
3161 nomem = new_NoMem();
3162 mode = get_irn_mode(op);
3164 /* first convert to 32 bit signed if necessary */
3165 src_bits = get_mode_size_bits(src_mode);
3166 if (src_bits == 8) {
3167 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3169 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3171 } else if (src_bits < 32) {
3172 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3174 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3178 assert(get_mode_size_bits(mode) == 32);
3181 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3184 set_ia32_use_frame(store);
3185 set_ia32_op_type(store, ia32_AddrModeD);
3186 set_ia32_ls_mode(store, mode_Iu);
3188 /* exception for 32bit unsigned, do a 64bit spill+load */
3189 if (!mode_is_signed(mode)) {
3192 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3194 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3195 get_irg_frame(irg), noreg, nomem,
3198 set_ia32_use_frame(zero_store);
3199 set_ia32_op_type(zero_store, ia32_AddrModeD);
3200 add_ia32_am_offs_int(zero_store, 4);
3201 set_ia32_ls_mode(zero_store, mode_Iu);
3206 store = new_rd_Sync(dbgi, irg, block, 2, in);
3207 store_mode = mode_Ls;
3209 store_mode = mode_Is;
3213 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3215 set_ia32_use_frame(fild);
3216 set_ia32_op_type(fild, ia32_AddrModeS);
3217 set_ia32_ls_mode(fild, store_mode);
3219 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3225 * Create a conversion from one integer mode into another one
3227 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3228 dbg_info *dbgi, ir_node *block, ir_node *op,
3231 ir_graph *irg = current_ir_graph;
3232 int src_bits = get_mode_size_bits(src_mode);
3233 int tgt_bits = get_mode_size_bits(tgt_mode);
3234 ir_node *new_block = be_transform_node(block);
3236 ir_mode *smaller_mode;
3238 ia32_address_mode_t am;
3239 ia32_address_t *addr = &am.addr;
3242 if (src_bits < tgt_bits) {
3243 smaller_mode = src_mode;
3244 smaller_bits = src_bits;
3246 smaller_mode = tgt_mode;
3247 smaller_bits = tgt_bits;
3250 #ifdef DEBUG_libfirm
3252 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3257 match_arguments(&am, block, NULL, op, NULL,
3258 match_8bit | match_16bit |
3259 match_am | match_8bit_am | match_16bit_am);
3261 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3262 /* unnecessary conv. in theory it shouldn't have been AM */
3263 assert(is_ia32_NoReg_GP(addr->base));
3264 assert(is_ia32_NoReg_GP(addr->index));
3265 assert(is_NoMem(addr->mem));
3266 assert(am.addr.offset == 0);
3267 assert(am.addr.symconst_ent == NULL);
3271 if (smaller_bits == 8) {
3272 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3273 addr->index, addr->mem, am.new_op2,
3276 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3277 addr->index, addr->mem, am.new_op2,
3280 set_am_attributes(new_node, &am);
3281 /* match_arguments assume that out-mode = in-mode, this isn't true here
3283 set_ia32_ls_mode(new_node, smaller_mode);
3284 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3285 new_node = fix_mem_proj(new_node, &am);
3290 * Transforms a Conv node.
3292 * @return The created ia32 Conv node
3294 static ir_node *gen_Conv(ir_node *node)
3296 ir_node *block = get_nodes_block(node);
3297 ir_node *new_block = be_transform_node(block);
3298 ir_node *op = get_Conv_op(node);
3299 ir_node *new_op = NULL;
3300 ir_graph *irg = current_ir_graph;
3301 dbg_info *dbgi = get_irn_dbg_info(node);
3302 ir_mode *src_mode = get_irn_mode(op);
3303 ir_mode *tgt_mode = get_irn_mode(node);
3304 int src_bits = get_mode_size_bits(src_mode);
3305 int tgt_bits = get_mode_size_bits(tgt_mode);
3306 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3307 ir_node *nomem = new_rd_NoMem(irg);
3308 ir_node *res = NULL;
3310 if (src_mode == mode_b) {
3311 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3312 /* nothing to do, we already model bools as 0/1 ints */
3313 return be_transform_node(op);
3316 if (src_mode == tgt_mode) {
3317 if (get_Conv_strict(node)) {
3318 if (ia32_cg_config.use_sse2) {
3319 /* when we are in SSE mode, we can kill all strict no-op conversion */
3320 return be_transform_node(op);
3323 /* this should be optimized already, but who knows... */
3324 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3325 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3326 return be_transform_node(op);
3330 if (mode_is_float(src_mode)) {
3331 new_op = be_transform_node(op);
3332 /* we convert from float ... */
3333 if (mode_is_float(tgt_mode)) {
3334 if (src_mode == mode_E && tgt_mode == mode_D
3335 && !get_Conv_strict(node)) {
3336 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3341 if (ia32_cg_config.use_sse2) {
3342 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3343 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3345 set_ia32_ls_mode(res, tgt_mode);
3347 if (get_Conv_strict(node)) {
3348 res = gen_x87_strict_conv(tgt_mode, new_op);
3349 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3352 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3357 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3358 if (ia32_cg_config.use_sse2) {
3359 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3361 set_ia32_ls_mode(res, src_mode);
3363 return gen_x87_fp_to_gp(node);
3367 /* we convert from int ... */
3368 if (mode_is_float(tgt_mode)) {
3370 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3371 if (ia32_cg_config.use_sse2) {
3372 new_op = be_transform_node(op);
3373 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3375 set_ia32_ls_mode(res, tgt_mode);
3377 res = gen_x87_gp_to_fp(node, src_mode);
3378 if (get_Conv_strict(node)) {
3379 /* The strict-Conv is only necessary, if the int mode has more bits
3380 * than the float mantissa */
3381 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3382 size_t float_mantissa;
3383 /* FIXME There is no way to get the mantissa size of a mode */
3384 switch (get_mode_size_bits(tgt_mode)) {
3385 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3386 case 64: float_mantissa = 52 + 1; break;
3388 case 96: float_mantissa = 64; break;
3389 default: float_mantissa = 0; break;
3391 if (float_mantissa < int_mantissa) {
3392 res = gen_x87_strict_conv(tgt_mode, res);
3393 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3398 } else if (tgt_mode == mode_b) {
3399 /* mode_b lowering already took care that we only have 0/1 values */
3400 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3401 src_mode, tgt_mode));
3402 return be_transform_node(op);
3405 if (src_bits == tgt_bits) {
3406 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3407 src_mode, tgt_mode));
3408 return be_transform_node(op);
3411 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3419 static ir_node *create_immediate_or_transform(ir_node *node,
3420 char immediate_constraint_type)
3422 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3423 if (new_node == NULL) {
3424 new_node = be_transform_node(node);
3430 * Transforms a FrameAddr into an ia32 Add.
3432 static ir_node *gen_be_FrameAddr(ir_node *node)
3434 ir_node *block = be_transform_node(get_nodes_block(node));
3435 ir_node *op = be_get_FrameAddr_frame(node);
3436 ir_node *new_op = be_transform_node(op);
3437 ir_graph *irg = current_ir_graph;
3438 dbg_info *dbgi = get_irn_dbg_info(node);
3439 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3442 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3443 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3444 set_ia32_use_frame(new_node);
3446 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3452 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3454 static ir_node *gen_be_Return(ir_node *node)
3456 ir_graph *irg = current_ir_graph;
3457 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3458 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3459 ir_entity *ent = get_irg_entity(irg);
3460 ir_type *tp = get_entity_type(ent);
3465 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3466 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3469 int pn_ret_val, pn_ret_mem, arity, i;
3471 assert(ret_val != NULL);
3472 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3473 return be_duplicate_node(node);
3476 res_type = get_method_res_type(tp, 0);
3478 if (! is_Primitive_type(res_type)) {
3479 return be_duplicate_node(node);
3482 mode = get_type_mode(res_type);
3483 if (! mode_is_float(mode)) {
3484 return be_duplicate_node(node);
3487 assert(get_method_n_ress(tp) == 1);
3489 pn_ret_val = get_Proj_proj(ret_val);
3490 pn_ret_mem = get_Proj_proj(ret_mem);
3492 /* get the Barrier */
3493 barrier = get_Proj_pred(ret_val);
3495 /* get result input of the Barrier */
3496 ret_val = get_irn_n(barrier, pn_ret_val);
3497 new_ret_val = be_transform_node(ret_val);
3499 /* get memory input of the Barrier */
3500 ret_mem = get_irn_n(barrier, pn_ret_mem);
3501 new_ret_mem = be_transform_node(ret_mem);
3503 frame = get_irg_frame(irg);
3505 dbgi = get_irn_dbg_info(barrier);
3506 block = be_transform_node(get_nodes_block(barrier));
3508 noreg = ia32_new_NoReg_gp(env_cg);
3510 /* store xmm0 onto stack */
3511 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3512 new_ret_mem, new_ret_val);
3513 set_ia32_ls_mode(sse_store, mode);
3514 set_ia32_op_type(sse_store, ia32_AddrModeD);
3515 set_ia32_use_frame(sse_store);
3517 /* load into x87 register */
3518 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3519 set_ia32_op_type(fld, ia32_AddrModeS);
3520 set_ia32_use_frame(fld);
3522 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3523 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3525 /* create a new barrier */
3526 arity = get_irn_arity(barrier);
3527 in = alloca(arity * sizeof(in[0]));
3528 for (i = 0; i < arity; ++i) {
3531 if (i == pn_ret_val) {
3533 } else if (i == pn_ret_mem) {
3536 ir_node *in = get_irn_n(barrier, i);
3537 new_in = be_transform_node(in);
3542 new_barrier = new_ir_node(dbgi, irg, block,
3543 get_irn_op(barrier), get_irn_mode(barrier),
3545 copy_node_attr(barrier, new_barrier);
3546 be_duplicate_deps(barrier, new_barrier);
3547 be_set_transformed_node(barrier, new_barrier);
3549 /* transform normally */
3550 return be_duplicate_node(node);
3554 * Transform a be_AddSP into an ia32_SubSP.
3556 static ir_node *gen_be_AddSP(ir_node *node)
3558 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3559 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3561 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3562 match_am | match_immediate);
3566 * Transform a be_SubSP into an ia32_AddSP
3568 static ir_node *gen_be_SubSP(ir_node *node)
3570 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3571 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3573 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3574 match_am | match_immediate);
3578 * Change some phi modes
3580 static ir_node *gen_Phi(ir_node *node)
3582 ir_node *block = be_transform_node(get_nodes_block(node));
3583 ir_graph *irg = current_ir_graph;
3584 dbg_info *dbgi = get_irn_dbg_info(node);
3585 ir_mode *mode = get_irn_mode(node);
3588 if (ia32_mode_needs_gp_reg(mode)) {
3589 /* we shouldn't have any 64bit stuff around anymore */
3590 assert(get_mode_size_bits(mode) <= 32);
3591 /* all integer operations are on 32bit registers now */
3593 } else if (mode_is_float(mode)) {
3594 if (ia32_cg_config.use_sse2) {
3601 /* phi nodes allow loops, so we use the old arguments for now
3602 * and fix this later */
3603 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3604 get_irn_in(node) + 1);
3605 copy_node_attr(node, phi);
3606 be_duplicate_deps(node, phi);
3608 be_enqueue_preds(node);
3616 static ir_node *gen_IJmp(ir_node *node)
3618 ir_node *block = get_nodes_block(node);
3619 ir_node *new_block = be_transform_node(block);
3620 dbg_info *dbgi = get_irn_dbg_info(node);
3621 ir_node *op = get_IJmp_target(node);
3623 ia32_address_mode_t am;
3624 ia32_address_t *addr = &am.addr;
3626 assert(get_irn_mode(op) == mode_P);
3628 match_arguments(&am, block, NULL, op, NULL,
3629 match_am | match_8bit_am | match_16bit_am |
3630 match_immediate | match_8bit | match_16bit);
3632 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3633 addr->base, addr->index, addr->mem,
3635 set_am_attributes(new_node, &am);
3636 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3638 new_node = fix_mem_proj(new_node, &am);
3644 * Transform a Bound node.
3646 static ir_node *gen_Bound(ir_node *node)
3649 ir_node *lower = get_Bound_lower(node);
3650 dbg_info *dbgi = get_irn_dbg_info(node);
3652 if (is_Const_0(lower)) {
3653 /* typical case for Java */
3654 ir_node *sub, *res, *flags, *block;
3655 ir_graph *irg = current_ir_graph;
3657 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3658 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3660 block = get_nodes_block(res);
3661 if (! is_Proj(res)) {
3663 set_irn_mode(sub, mode_T);
3664 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3666 sub = get_Proj_pred(res);
3668 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3669 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3670 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3672 panic("generic Bound not supported in ia32 Backend");
3678 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3680 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3681 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3683 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3684 match_immediate | match_mode_neutral);
3687 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3689 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3690 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3691 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3695 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3697 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3698 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3699 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3703 static ir_node *gen_ia32_l_Add(ir_node *node)
3705 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3706 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3707 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3708 match_commutative | match_am | match_immediate |
3709 match_mode_neutral);
3711 if (is_Proj(lowered)) {
3712 lowered = get_Proj_pred(lowered);
3714 assert(is_ia32_Add(lowered));
3715 set_irn_mode(lowered, mode_T);
3721 static ir_node *gen_ia32_l_Adc(ir_node *node)
3723 return gen_binop_flags(node, new_rd_ia32_Adc,
3724 match_commutative | match_am | match_immediate |
3725 match_mode_neutral);
3729 * Transforms a l_MulS into a "real" MulS node.
3731 * @return the created ia32 Mul node
3733 static ir_node *gen_ia32_l_Mul(ir_node *node)
3735 ir_node *left = get_binop_left(node);
3736 ir_node *right = get_binop_right(node);
3738 return gen_binop(node, left, right, new_rd_ia32_Mul,
3739 match_commutative | match_am | match_mode_neutral);
3743 * Transforms a l_IMulS into a "real" IMul1OPS node.
3745 * @return the created ia32 IMul1OP node
3747 static ir_node *gen_ia32_l_IMul(ir_node *node)
3749 ir_node *left = get_binop_left(node);
3750 ir_node *right = get_binop_right(node);
3752 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3753 match_commutative | match_am | match_mode_neutral);
3756 static ir_node *gen_ia32_l_Sub(ir_node *node)
3758 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3759 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3760 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3761 match_am | match_immediate | match_mode_neutral);
3763 if (is_Proj(lowered)) {
3764 lowered = get_Proj_pred(lowered);
3766 assert(is_ia32_Sub(lowered));
3767 set_irn_mode(lowered, mode_T);
3773 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3775 return gen_binop_flags(node, new_rd_ia32_Sbb,
3776 match_am | match_immediate | match_mode_neutral);
3780 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3781 * op1 - target to be shifted
3782 * op2 - contains bits to be shifted into target
3784 * Only op3 can be an immediate.
3786 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3787 ir_node *low, ir_node *count)
3789 ir_node *block = get_nodes_block(node);
3790 ir_node *new_block = be_transform_node(block);
3791 ir_graph *irg = current_ir_graph;
3792 dbg_info *dbgi = get_irn_dbg_info(node);
3793 ir_node *new_high = be_transform_node(high);
3794 ir_node *new_low = be_transform_node(low);
3798 /* the shift amount can be any mode that is bigger than 5 bits, since all
3799 * other bits are ignored anyway */
3800 while (is_Conv(count) &&
3801 get_irn_n_edges(count) == 1 &&
3802 mode_is_int(get_irn_mode(count))) {
3803 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3804 count = get_Conv_op(count);
3806 new_count = create_immediate_or_transform(count, 0);
3808 if (is_ia32_l_ShlD(node)) {
3809 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3812 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3815 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3820 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3822 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3823 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3824 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3825 return gen_lowered_64bit_shifts(node, high, low, count);
3828 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3830 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3831 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3832 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3833 return gen_lowered_64bit_shifts(node, high, low, count);
3836 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3838 ir_node *src_block = get_nodes_block(node);
3839 ir_node *block = be_transform_node(src_block);
3840 ir_graph *irg = current_ir_graph;
3841 dbg_info *dbgi = get_irn_dbg_info(node);
3842 ir_node *frame = get_irg_frame(irg);
3843 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3844 ir_node *nomem = new_NoMem();
3845 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3846 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3847 ir_node *new_val_low = be_transform_node(val_low);
3848 ir_node *new_val_high = be_transform_node(val_high);
3853 ir_node *store_high;
3855 if (!mode_is_signed(get_irn_mode(val_high))) {
3856 panic("unsigned long long -> float not supported yet (%+F)", node);
3860 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3862 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3864 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3865 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3867 set_ia32_use_frame(store_low);
3868 set_ia32_use_frame(store_high);
3869 set_ia32_op_type(store_low, ia32_AddrModeD);
3870 set_ia32_op_type(store_high, ia32_AddrModeD);
3871 set_ia32_ls_mode(store_low, mode_Iu);
3872 set_ia32_ls_mode(store_high, mode_Is);
3873 add_ia32_am_offs_int(store_high, 4);
3877 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3880 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3882 set_ia32_use_frame(fild);
3883 set_ia32_op_type(fild, ia32_AddrModeS);
3884 set_ia32_ls_mode(fild, mode_Ls);
3886 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3888 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3891 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3893 ir_node *src_block = get_nodes_block(node);
3894 ir_node *block = be_transform_node(src_block);
3895 ir_graph *irg = current_ir_graph;
3896 dbg_info *dbgi = get_irn_dbg_info(node);
3897 ir_node *frame = get_irg_frame(irg);
3898 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3899 ir_node *nomem = new_NoMem();
3900 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3901 ir_node *new_val = be_transform_node(val);
3902 ir_node *fist, *mem;
3904 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3905 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3906 set_ia32_use_frame(fist);
3907 set_ia32_op_type(fist, ia32_AddrModeD);
3908 set_ia32_ls_mode(fist, mode_Ls);
3914 * the BAD transformer.
3916 static ir_node *bad_transform(ir_node *node)
3918 panic("No transform function for %+F available.", node);
3922 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3924 ir_graph *irg = current_ir_graph;
3925 ir_node *block = be_transform_node(get_nodes_block(node));
3926 ir_node *pred = get_Proj_pred(node);
3927 ir_node *new_pred = be_transform_node(pred);
3928 ir_node *frame = get_irg_frame(irg);
3929 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3930 dbg_info *dbgi = get_irn_dbg_info(node);
3931 long pn = get_Proj_proj(node);
3936 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3937 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3938 set_ia32_use_frame(load);
3939 set_ia32_op_type(load, ia32_AddrModeS);
3940 set_ia32_ls_mode(load, mode_Iu);
3941 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3942 * 32 bit from it with this particular load */
3943 attr = get_ia32_attr(load);
3944 attr->data.need_64bit_stackent = 1;
3946 if (pn == pn_ia32_l_FloattoLL_res_high) {
3947 add_ia32_am_offs_int(load, 4);
3949 assert(pn == pn_ia32_l_FloattoLL_res_low);
3952 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3958 * Transform the Projs of an AddSP.
3960 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3962 ir_node *block = be_transform_node(get_nodes_block(node));
3963 ir_node *pred = get_Proj_pred(node);
3964 ir_node *new_pred = be_transform_node(pred);
3965 ir_graph *irg = current_ir_graph;
3966 dbg_info *dbgi = get_irn_dbg_info(node);
3967 long proj = get_Proj_proj(node);
3969 if (proj == pn_be_AddSP_sp) {
3970 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3971 pn_ia32_SubSP_stack);
3972 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3974 } else if (proj == pn_be_AddSP_res) {
3975 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3976 pn_ia32_SubSP_addr);
3977 } else if (proj == pn_be_AddSP_M) {
3978 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3981 panic("No idea how to transform proj->AddSP");
3985 * Transform the Projs of a SubSP.
3987 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3989 ir_node *block = be_transform_node(get_nodes_block(node));
3990 ir_node *pred = get_Proj_pred(node);
3991 ir_node *new_pred = be_transform_node(pred);
3992 ir_graph *irg = current_ir_graph;
3993 dbg_info *dbgi = get_irn_dbg_info(node);
3994 long proj = get_Proj_proj(node);
3996 if (proj == pn_be_SubSP_sp) {
3997 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3998 pn_ia32_AddSP_stack);
3999 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4001 } else if (proj == pn_be_SubSP_M) {
4002 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4005 panic("No idea how to transform proj->SubSP");
4009 * Transform and renumber the Projs from a Load.
4011 static ir_node *gen_Proj_Load(ir_node *node)
4014 ir_node *block = be_transform_node(get_nodes_block(node));
4015 ir_node *pred = get_Proj_pred(node);
4016 ir_graph *irg = current_ir_graph;
4017 dbg_info *dbgi = get_irn_dbg_info(node);
4018 long proj = get_Proj_proj(node);
4020 /* loads might be part of source address mode matches, so we don't
4021 * transform the ProjMs yet (with the exception of loads whose result is
4024 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4027 /* this is needed, because sometimes we have loops that are only
4028 reachable through the ProjM */
4029 be_enqueue_preds(node);
4030 /* do it in 2 steps, to silence firm verifier */
4031 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4032 set_Proj_proj(res, pn_ia32_mem);
4036 /* renumber the proj */
4037 new_pred = be_transform_node(pred);
4038 if (is_ia32_Load(new_pred)) {
4041 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4043 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4044 case pn_Load_X_regular:
4045 return new_rd_Jmp(dbgi, irg, block);
4046 case pn_Load_X_except:
4047 /* This Load might raise an exception. Mark it. */
4048 set_ia32_exc_label(new_pred, 1);
4049 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4053 } else if (is_ia32_Conv_I2I(new_pred) ||
4054 is_ia32_Conv_I2I8Bit(new_pred)) {
4055 set_irn_mode(new_pred, mode_T);
4056 if (proj == pn_Load_res) {
4057 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4058 } else if (proj == pn_Load_M) {
4059 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4061 } else if (is_ia32_xLoad(new_pred)) {
4064 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4066 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4067 case pn_Load_X_regular:
4068 return new_rd_Jmp(dbgi, irg, block);
4069 case pn_Load_X_except:
4070 /* This Load might raise an exception. Mark it. */
4071 set_ia32_exc_label(new_pred, 1);
4072 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4076 } else if (is_ia32_vfld(new_pred)) {
4079 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4081 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4082 case pn_Load_X_regular:
4083 return new_rd_Jmp(dbgi, irg, block);
4084 case pn_Load_X_except:
4085 /* This Load might raise an exception. Mark it. */
4086 set_ia32_exc_label(new_pred, 1);
4087 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4092 /* can happen for ProJMs when source address mode happened for the
4095 /* however it should not be the result proj, as that would mean the
4096 load had multiple users and should not have been used for
4098 if (proj != pn_Load_M) {
4099 panic("internal error: transformed node not a Load");
4101 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4104 panic("No idea how to transform proj");
4108 * Transform and renumber the Projs from a DivMod like instruction.
4110 static ir_node *gen_Proj_DivMod(ir_node *node)
4112 ir_node *block = be_transform_node(get_nodes_block(node));
4113 ir_node *pred = get_Proj_pred(node);
4114 ir_node *new_pred = be_transform_node(pred);
4115 ir_graph *irg = current_ir_graph;
4116 dbg_info *dbgi = get_irn_dbg_info(node);
4117 long proj = get_Proj_proj(node);
4119 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4121 switch (get_irn_opcode(pred)) {
4125 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4127 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4128 case pn_Div_X_regular:
4129 return new_rd_Jmp(dbgi, irg, block);
4130 case pn_Div_X_except:
4131 set_ia32_exc_label(new_pred, 1);
4132 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4140 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4142 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4143 case pn_Mod_X_except:
4144 set_ia32_exc_label(new_pred, 1);
4145 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4153 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4154 case pn_DivMod_res_div:
4155 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4156 case pn_DivMod_res_mod:
4157 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4158 case pn_DivMod_X_regular:
4159 return new_rd_Jmp(dbgi, irg, block);
4160 case pn_DivMod_X_except:
4161 set_ia32_exc_label(new_pred, 1);
4162 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4171 panic("No idea how to transform proj->DivMod");
4175 * Transform and renumber the Projs from a CopyB.
4177 static ir_node *gen_Proj_CopyB(ir_node *node)
4179 ir_node *block = be_transform_node(get_nodes_block(node));
4180 ir_node *pred = get_Proj_pred(node);
4181 ir_node *new_pred = be_transform_node(pred);
4182 ir_graph *irg = current_ir_graph;
4183 dbg_info *dbgi = get_irn_dbg_info(node);
4184 long proj = get_Proj_proj(node);
4187 case pn_CopyB_M_regular:
4188 if (is_ia32_CopyB_i(new_pred)) {
4189 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4190 } else if (is_ia32_CopyB(new_pred)) {
4191 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4198 panic("No idea how to transform proj->CopyB");
4202 * Transform and renumber the Projs from a Quot.
4204 static ir_node *gen_Proj_Quot(ir_node *node)
4206 ir_node *block = be_transform_node(get_nodes_block(node));
4207 ir_node *pred = get_Proj_pred(node);
4208 ir_node *new_pred = be_transform_node(pred);
4209 ir_graph *irg = current_ir_graph;
4210 dbg_info *dbgi = get_irn_dbg_info(node);
4211 long proj = get_Proj_proj(node);
4215 if (is_ia32_xDiv(new_pred)) {
4216 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4217 } else if (is_ia32_vfdiv(new_pred)) {
4218 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4222 if (is_ia32_xDiv(new_pred)) {
4223 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4224 } else if (is_ia32_vfdiv(new_pred)) {
4225 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4228 case pn_Quot_X_regular:
4229 case pn_Quot_X_except:
4234 panic("No idea how to transform proj->Quot");
4237 static ir_node *gen_be_Call(ir_node *node)
4239 dbg_info *const dbgi = get_irn_dbg_info(node);
4240 ir_graph *const irg = current_ir_graph;
4241 ir_node *const src_block = get_nodes_block(node);
4242 ir_node *const block = be_transform_node(src_block);
4243 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4244 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4245 ir_node *const sp = be_transform_node(src_sp);
4246 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4247 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4248 ia32_address_mode_t am;
4249 ia32_address_t *const addr = &am.addr;
4254 ir_node * eax = noreg;
4255 ir_node * ecx = noreg;
4256 ir_node * edx = noreg;
4257 unsigned const pop = be_Call_get_pop(node);
4258 ir_type *const call_tp = be_Call_get_type(node);
4260 /* Run the x87 simulator if the call returns a float value */
4261 if (get_method_n_ress(call_tp) > 0) {
4262 ir_type *const res_type = get_method_res_type(call_tp, 0);
4263 ir_mode *const res_mode = get_type_mode(res_type);
4265 if (res_mode != NULL && mode_is_float(res_mode)) {
4266 env_cg->do_x87_sim = 1;
4270 /* We do not want be_Call direct calls */
4271 assert(be_Call_get_entity(node) == NULL);
4273 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4274 match_am | match_immediate);
4276 i = get_irn_arity(node) - 1;
4277 fpcw = be_transform_node(get_irn_n(node, i--));
4278 for (; i >= be_pos_Call_first_arg; --i) {
4279 arch_register_req_t const *const req = arch_get_register_req(node, i);
4280 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4282 assert(req->type == arch_register_req_type_limited);
4283 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4285 switch (*req->limited) {
4286 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4287 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4288 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4289 default: panic("Invalid GP register for register parameter");
4293 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4294 call = new_rd_ia32_Call(dbgi, irg, block, addr->base, addr->index, mem,
4295 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4296 set_am_attributes(call, &am);
4297 call = fix_mem_proj(call, &am);
4299 if (get_irn_pinned(node) == op_pin_state_pinned)
4300 set_irn_pinned(call, op_pin_state_pinned);
4302 SET_IA32_ORIG_NODE(call, ia32_get_old_node_name(env_cg, node));
4306 static ir_node *gen_be_IncSP(ir_node *node)
4308 ir_node *res = be_duplicate_node(node);
4309 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4315 * Transform the Projs from a be_Call.
4317 static ir_node *gen_Proj_be_Call(ir_node *node)
4319 ir_node *block = be_transform_node(get_nodes_block(node));
4320 ir_node *call = get_Proj_pred(node);
4321 ir_node *new_call = be_transform_node(call);
4322 ir_graph *irg = current_ir_graph;
4323 dbg_info *dbgi = get_irn_dbg_info(node);
4324 ir_type *method_type = be_Call_get_type(call);
4325 int n_res = get_method_n_ress(method_type);
4326 long proj = get_Proj_proj(node);
4327 ir_mode *mode = get_irn_mode(node);
4329 const arch_register_class_t *cls;
4332 /* The following is kinda tricky: If we're using SSE, then we have to
4333 * move the result value of the call in floating point registers to an
4334 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4335 * after the call, we have to make sure to correctly make the
4336 * MemProj and the result Proj use these 2 nodes
4338 if (proj == pn_be_Call_M_regular) {
4339 // get new node for result, are we doing the sse load/store hack?
4340 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4341 ir_node *call_res_new;
4342 ir_node *call_res_pred = NULL;
4344 if (call_res != NULL) {
4345 call_res_new = be_transform_node(call_res);
4346 call_res_pred = get_Proj_pred(call_res_new);
4349 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4350 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4353 assert(is_ia32_xLoad(call_res_pred));
4354 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4358 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4359 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4361 ir_node *frame = get_irg_frame(irg);
4362 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4364 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4367 /* in case there is no memory output: create one to serialize the copy
4369 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4370 pn_be_Call_M_regular);
4371 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4372 pn_be_Call_first_res);
4374 /* store st(0) onto stack */
4375 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4377 set_ia32_op_type(fstp, ia32_AddrModeD);
4378 set_ia32_use_frame(fstp);
4380 /* load into SSE register */
4381 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4383 set_ia32_op_type(sse_load, ia32_AddrModeS);
4384 set_ia32_use_frame(sse_load);
4386 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4392 /* transform call modes */
4393 if (mode_is_data(mode)) {
4394 cls = arch_get_irn_reg_class(node, -1);
4398 /* Map from be_Call to ia32_Call proj number */
4399 if (proj == pn_be_Call_sp) {
4400 proj = pn_ia32_Call_stack;
4401 } else if (proj == pn_be_Call_M_regular) {
4402 proj = pn_ia32_Call_M;
4404 arch_register_req_t const *const req = arch_get_register_req(node, BE_OUT_POS(proj));
4405 int const n_outs = get_ia32_n_res(new_call);
4408 assert(proj >= pn_be_Call_first_res);
4409 assert(req->type == arch_register_req_type_limited);
4411 for (i = 0; i < n_outs; ++i) {
4412 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4414 if (new_req->type != arch_register_req_type_limited ||
4415 new_req->cls != req->cls ||
4416 *new_req->limited != *req->limited)
4425 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4427 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4429 case pn_ia32_Call_stack:
4430 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4433 case pn_ia32_Call_fpcw:
4434 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4442 * Transform the Projs from a Cmp.
4444 static ir_node *gen_Proj_Cmp(ir_node *node)
4446 /* this probably means not all mode_b nodes were lowered... */
4447 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4452 * Transform the Projs from a Bound.
4454 static ir_node *gen_Proj_Bound(ir_node *node)
4456 ir_node *new_node, *block;
4457 ir_node *pred = get_Proj_pred(node);
4459 switch (get_Proj_proj(node)) {
4461 return be_transform_node(get_Bound_mem(pred));
4462 case pn_Bound_X_regular:
4463 new_node = be_transform_node(pred);
4464 block = get_nodes_block(new_node);
4465 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4466 case pn_Bound_X_except:
4467 new_node = be_transform_node(pred);
4468 block = get_nodes_block(new_node);
4469 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4471 return be_transform_node(get_Bound_index(pred));
4473 panic("unsupported Proj from Bound");
4477 static ir_node *gen_Proj_ASM(ir_node *node)
4483 if (get_irn_mode(node) != mode_M)
4484 return be_duplicate_node(node);
4486 pred = get_Proj_pred(node);
4487 new_pred = be_transform_node(pred);
4488 block = get_nodes_block(new_pred);
4489 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4490 get_ia32_n_res(new_pred) + 1);
4494 * Transform and potentially renumber Proj nodes.
4496 static ir_node *gen_Proj(ir_node *node)
4498 ir_node *pred = get_Proj_pred(node);
4501 switch (get_irn_opcode(pred)) {
4503 proj = get_Proj_proj(node);
4504 if (proj == pn_Store_M) {
4505 return be_transform_node(pred);
4507 panic("No idea how to transform proj->Store");
4510 return gen_Proj_Load(node);
4512 return gen_Proj_ASM(node);
4516 return gen_Proj_DivMod(node);
4518 return gen_Proj_CopyB(node);
4520 return gen_Proj_Quot(node);
4522 return gen_Proj_be_SubSP(node);
4524 return gen_Proj_be_AddSP(node);
4526 return gen_Proj_be_Call(node);
4528 return gen_Proj_Cmp(node);
4530 return gen_Proj_Bound(node);
4532 proj = get_Proj_proj(node);
4534 case pn_Start_X_initial_exec: {
4535 ir_node *block = get_nodes_block(pred);
4536 ir_node *new_block = be_transform_node(block);
4537 dbg_info *dbgi = get_irn_dbg_info(node);
4538 /* we exchange the ProjX with a jump */
4539 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4544 case pn_Start_P_tls:
4545 return gen_Proj_tls(node);
4550 if (is_ia32_l_FloattoLL(pred)) {
4551 return gen_Proj_l_FloattoLL(node);
4553 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4557 ir_mode *mode = get_irn_mode(node);
4558 if (ia32_mode_needs_gp_reg(mode)) {
4559 ir_node *new_pred = be_transform_node(pred);
4560 ir_node *block = be_transform_node(get_nodes_block(node));
4561 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4562 mode_Iu, get_Proj_proj(node));
4563 #ifdef DEBUG_libfirm
4564 new_proj->node_nr = node->node_nr;
4570 return be_duplicate_node(node);
4574 * Enters all transform functions into the generic pointer
4576 static void register_transformers(void)
4580 /* first clear the generic function pointer for all ops */
4581 clear_irp_opcodes_generic_func();
4583 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4584 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4622 /* transform ops from intrinsic lowering */
4634 GEN(ia32_l_LLtoFloat);
4635 GEN(ia32_l_FloattoLL);
4641 /* we should never see these nodes */
4656 /* handle generic backend nodes */
4665 op_Mulh = get_op_Mulh();
4674 * Pre-transform all unknown and noreg nodes.
4676 static void ia32_pretransform_node(void)
4678 ia32_code_gen_t *cg = env_cg;
4680 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4681 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4682 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4683 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4684 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4685 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4690 * Walker, checks if all ia32 nodes producing more than one result have their
4691 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4693 static void add_missing_keep_walker(ir_node *node, void *data)
4696 unsigned found_projs = 0;
4697 const ir_edge_t *edge;
4698 ir_mode *mode = get_irn_mode(node);
4703 if (!is_ia32_irn(node))
4706 n_outs = get_ia32_n_res(node);
4709 if (is_ia32_SwitchJmp(node))
4712 assert(n_outs < (int) sizeof(unsigned) * 8);
4713 foreach_out_edge(node, edge) {
4714 ir_node *proj = get_edge_src_irn(edge);
4717 /* The node could be kept */
4721 if (get_irn_mode(proj) == mode_M)
4724 pn = get_Proj_proj(proj);
4725 assert(pn < n_outs);
4726 found_projs |= 1 << pn;
4730 /* are keeps missing? */
4732 for (i = 0; i < n_outs; ++i) {
4735 const arch_register_req_t *req;
4736 const arch_register_class_t *cls;
4738 if (found_projs & (1 << i)) {
4742 req = get_ia32_out_req(node, i);
4747 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4751 block = get_nodes_block(node);
4752 in[0] = new_r_Proj(current_ir_graph, block, node,
4753 arch_register_class_mode(cls), i);
4754 if (last_keep != NULL) {
4755 be_Keep_add_node(last_keep, cls, in[0]);
4757 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4758 if (sched_is_scheduled(node)) {
4759 sched_add_after(node, last_keep);
4766 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4769 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4771 ir_graph *irg = be_get_birg_irg(cg->birg);
4772 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4775 /* do the transformation */
4776 void ia32_transform_graph(ia32_code_gen_t *cg)
4780 register_transformers();
4782 initial_fpcw = NULL;
4784 BE_TIMER_PUSH(t_heights);
4785 heights = heights_new(cg->irg);
4786 BE_TIMER_POP(t_heights);
4787 ia32_calculate_non_address_mode_nodes(cg->birg);
4789 /* the transform phase is not safe for CSE (yet) because several nodes get
4790 * attributes set after their creation */
4791 cse_last = get_opt_cse();
4794 be_transform_graph(cg->birg, ia32_pretransform_node);
4796 set_opt_cse(cse_last);
4798 ia32_free_non_address_mode_nodes();
4799 heights_free(heights);
4803 void ia32_init_transform(void)
4805 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");