2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
34 #include "irgraph_t.h"
39 #include "iredges_t.h"
52 #include "../benode_t.h"
53 #include "../besched.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
60 #include "bearch_ia32_t.h"
61 #include "ia32_common_transform.h"
62 #include "ia32_nodes_attr.h"
63 #include "ia32_transform.h"
64 #include "ia32_new_nodes.h"
65 #include "ia32_map_regs.h"
66 #include "ia32_dbg_stat.h"
67 #include "ia32_optimize.h"
68 #include "ia32_util.h"
69 #include "ia32_address_mode.h"
70 #include "ia32_architecture.h"
72 #include "gen_ia32_regalloc_if.h"
74 #define SFP_SIGN "0x80000000"
75 #define DFP_SIGN "0x8000000000000000"
76 #define SFP_ABS "0x7FFFFFFF"
77 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
78 #define DFP_INTMAX "9223372036854775807"
80 #define TP_SFP_SIGN "ia32_sfp_sign"
81 #define TP_DFP_SIGN "ia32_dfp_sign"
82 #define TP_SFP_ABS "ia32_sfp_abs"
83 #define TP_DFP_ABS "ia32_dfp_abs"
84 #define TP_INT_MAX "ia32_int_max"
86 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
87 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
88 #define ENT_SFP_ABS "IA32_SFP_ABS"
89 #define ENT_DFP_ABS "IA32_DFP_ABS"
90 #define ENT_INT_MAX "IA32_INT_MAX"
92 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
93 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
95 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
97 static ir_node *initial_fpcw = NULL;
99 extern ir_op *get_op_Mulh(void);
101 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
102 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
103 ir_node *op1, ir_node *op2);
105 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
106 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
107 ir_node *op1, ir_node *op2, ir_node *flags);
109 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
110 ir_node *block, ir_node *op1, ir_node *op2);
112 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
113 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
116 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
117 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
119 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
120 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
121 ir_node *op1, ir_node *op2, ir_node *fpcw);
123 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
124 ir_node *block, ir_node *op);
126 static ir_node *create_immediate_or_transform(ir_node *node,
127 char immediate_constraint_type);
129 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
130 dbg_info *dbgi, ir_node *block,
131 ir_node *op, ir_node *orig_node);
133 /** Return non-zero is a node represents the 0 constant. */
134 static bool is_Const_0(ir_node *node)
136 return is_Const(node) && is_Const_null(node);
139 /** Return non-zero is a node represents the 1 constant. */
140 static bool is_Const_1(ir_node *node)
142 return is_Const(node) && is_Const_one(node);
145 /** Return non-zero is a node represents the -1 constant. */
146 static bool is_Const_Minus_1(ir_node *node)
148 return is_Const(node) && is_Const_all_one(node);
152 * returns true if constant can be created with a simple float command
154 static bool is_simple_x87_Const(ir_node *node)
156 tarval *tv = get_Const_tarval(node);
157 if (tarval_is_null(tv) || tarval_is_one(tv))
160 /* TODO: match all the other float constants */
165 * returns true if constant can be created with a simple float command
167 static bool is_simple_sse_Const(ir_node *node)
169 tarval *tv = get_Const_tarval(node);
170 ir_mode *mode = get_tarval_mode(tv);
175 if (tarval_is_null(tv) || tarval_is_one(tv))
178 if (mode == mode_D) {
179 unsigned val = get_tarval_sub_bits(tv, 0) |
180 (get_tarval_sub_bits(tv, 1) << 8) |
181 (get_tarval_sub_bits(tv, 2) << 16) |
182 (get_tarval_sub_bits(tv, 3) << 24);
184 /* lower 32bit are zero, really a 32bit constant */
188 /* TODO: match all the other float constants */
193 * Transforms a Const.
195 static ir_node *gen_Const(ir_node *node)
197 ir_graph *irg = current_ir_graph;
198 ir_node *old_block = get_nodes_block(node);
199 ir_node *block = be_transform_node(old_block);
200 dbg_info *dbgi = get_irn_dbg_info(node);
201 ir_mode *mode = get_irn_mode(node);
203 assert(is_Const(node));
205 if (mode_is_float(mode)) {
207 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
208 ir_node *nomem = new_NoMem();
212 if (ia32_cg_config.use_sse2) {
213 tarval *tv = get_Const_tarval(node);
214 if (tarval_is_null(tv)) {
215 load = new_rd_ia32_xZero(dbgi, irg, block);
216 set_ia32_ls_mode(load, mode);
218 } else if (tarval_is_one(tv)) {
219 int cnst = mode == mode_F ? 26 : 55;
220 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
221 ir_node *imm2 = create_Immediate(NULL, 0, 2);
222 ir_node *pslld, *psrld;
224 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
225 set_ia32_ls_mode(load, mode);
226 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
227 set_ia32_ls_mode(pslld, mode);
228 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
229 set_ia32_ls_mode(psrld, mode);
231 } else if (mode == mode_F) {
232 /* we can place any 32bit constant by using a movd gp, sse */
233 unsigned val = get_tarval_sub_bits(tv, 0) |
234 (get_tarval_sub_bits(tv, 1) << 8) |
235 (get_tarval_sub_bits(tv, 2) << 16) |
236 (get_tarval_sub_bits(tv, 3) << 24);
237 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
238 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
239 set_ia32_ls_mode(load, mode);
242 if (mode == mode_D) {
243 unsigned val = get_tarval_sub_bits(tv, 0) |
244 (get_tarval_sub_bits(tv, 1) << 8) |
245 (get_tarval_sub_bits(tv, 2) << 16) |
246 (get_tarval_sub_bits(tv, 3) << 24);
248 ir_node *imm32 = create_Immediate(NULL, 0, 32);
249 ir_node *cnst, *psllq;
251 /* fine, lower 32bit are zero, produce 32bit value */
252 val = get_tarval_sub_bits(tv, 4) |
253 (get_tarval_sub_bits(tv, 5) << 8) |
254 (get_tarval_sub_bits(tv, 6) << 16) |
255 (get_tarval_sub_bits(tv, 7) << 24);
256 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
257 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
258 set_ia32_ls_mode(load, mode);
259 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
260 set_ia32_ls_mode(psllq, mode);
265 floatent = create_float_const_entity(node);
267 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
269 set_ia32_op_type(load, ia32_AddrModeS);
270 set_ia32_am_sc(load, floatent);
271 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
272 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
275 if (is_Const_null(node)) {
276 load = new_rd_ia32_vfldz(dbgi, irg, block);
278 set_ia32_ls_mode(load, mode);
279 } else if (is_Const_one(node)) {
280 load = new_rd_ia32_vfld1(dbgi, irg, block);
282 set_ia32_ls_mode(load, mode);
284 floatent = create_float_const_entity(node);
286 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
287 set_ia32_op_type(load, ia32_AddrModeS);
288 set_ia32_am_sc(load, floatent);
289 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
290 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
291 /* take the mode from the entity */
292 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
296 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
298 be_dep_on_frame(load);
300 } else { /* non-float mode */
302 tarval *tv = get_Const_tarval(node);
305 tv = tarval_convert_to(tv, mode_Iu);
307 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
309 panic("couldn't convert constant tarval (%+F)", node);
311 val = get_tarval_long(tv);
313 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
314 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
316 be_dep_on_frame(cnst);
322 * Transforms a SymConst.
324 static ir_node *gen_SymConst(ir_node *node)
326 ir_graph *irg = current_ir_graph;
327 ir_node *old_block = get_nodes_block(node);
328 ir_node *block = be_transform_node(old_block);
329 dbg_info *dbgi = get_irn_dbg_info(node);
330 ir_mode *mode = get_irn_mode(node);
333 if (mode_is_float(mode)) {
334 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
335 ir_node *nomem = new_NoMem();
337 if (ia32_cg_config.use_sse2)
338 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
340 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
341 set_ia32_am_sc(cnst, get_SymConst_entity(node));
342 set_ia32_use_frame(cnst);
346 if (get_SymConst_kind(node) != symconst_addr_ent) {
347 panic("backend only support symconst_addr_ent (at %+F)", node);
349 entity = get_SymConst_entity(node);
350 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
353 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
355 be_dep_on_frame(cnst);
359 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
360 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
362 static const struct {
364 const char *ent_name;
365 const char *cnst_str;
368 } names [ia32_known_const_max] = {
369 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
370 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
371 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
372 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
373 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
375 static ir_entity *ent_cache[ia32_known_const_max];
377 const char *tp_name, *ent_name, *cnst_str;
385 ent_name = names[kct].ent_name;
386 if (! ent_cache[kct]) {
387 tp_name = names[kct].tp_name;
388 cnst_str = names[kct].cnst_str;
390 switch (names[kct].mode) {
391 case 0: mode = mode_Iu; break;
392 case 1: mode = mode_Lu; break;
393 default: mode = mode_F; break;
395 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
396 tp = new_type_primitive(new_id_from_str(tp_name), mode);
397 /* set the specified alignment */
398 set_type_alignment_bytes(tp, names[kct].align);
400 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
402 set_entity_ld_ident(ent, get_entity_ident(ent));
403 set_entity_visibility(ent, visibility_local);
404 set_entity_variability(ent, variability_constant);
405 set_entity_allocation(ent, allocation_static);
407 /* we create a new entity here: It's initialization must resist on the
409 rem = current_ir_graph;
410 current_ir_graph = get_const_code_irg();
411 cnst = new_Const(mode, tv);
412 current_ir_graph = rem;
414 set_atomic_ent_value(ent, cnst);
416 /* cache the entry */
417 ent_cache[kct] = ent;
420 return ent_cache[kct];
424 * return true if the node is a Proj(Load) and could be used in source address
425 * mode for another node. Will return only true if the @p other node is not
426 * dependent on the memory of the Load (for binary operations use the other
427 * input here, for unary operations use NULL).
429 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
430 ir_node *other, ir_node *other2, match_flags_t flags)
435 /* float constants are always available */
436 if (is_Const(node)) {
437 ir_mode *mode = get_irn_mode(node);
438 if (mode_is_float(mode)) {
439 if (ia32_cg_config.use_sse2) {
440 if (is_simple_sse_Const(node))
443 if (is_simple_x87_Const(node))
446 if (get_irn_n_edges(node) > 1)
454 load = get_Proj_pred(node);
455 pn = get_Proj_proj(node);
456 if (!is_Load(load) || pn != pn_Load_res)
458 if (get_nodes_block(load) != block)
460 /* we only use address mode if we're the only user of the load */
461 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
463 /* in some edge cases with address mode we might reach the load normally
464 * and through some AM sequence, if it is already materialized then we
465 * can't create an AM node from it */
466 if (be_is_transformed(node))
469 /* don't do AM if other node inputs depend on the load (via mem-proj) */
470 if (other != NULL && prevents_AM(block, load, other))
473 if (other2 != NULL && prevents_AM(block, load, other2))
479 typedef struct ia32_address_mode_t ia32_address_mode_t;
480 struct ia32_address_mode_t {
485 ia32_op_type_t op_type;
489 unsigned commutative : 1;
490 unsigned ins_permuted : 1;
493 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
497 /* construct load address */
498 memset(addr, 0, sizeof(addr[0]));
499 ia32_create_address_mode(addr, ptr, /*force=*/0);
501 noreg_gp = ia32_new_NoReg_gp(env_cg);
502 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
503 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
504 addr->mem = be_transform_node(mem);
507 static void build_address(ia32_address_mode_t *am, ir_node *node)
509 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
510 ia32_address_t *addr = &am->addr;
516 if (is_Const(node)) {
517 ir_entity *entity = create_float_const_entity(node);
518 addr->base = noreg_gp;
519 addr->index = noreg_gp;
520 addr->mem = new_NoMem();
521 addr->symconst_ent = entity;
523 am->ls_mode = get_type_mode(get_entity_type(entity));
524 am->pinned = op_pin_state_floats;
528 load = get_Proj_pred(node);
529 ptr = get_Load_ptr(load);
530 mem = get_Load_mem(load);
531 new_mem = be_transform_node(mem);
532 am->pinned = get_irn_pinned(load);
533 am->ls_mode = get_Load_mode(load);
534 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
537 /* construct load address */
538 ia32_create_address_mode(addr, ptr, /*force=*/0);
540 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
541 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
545 static void set_address(ir_node *node, const ia32_address_t *addr)
547 set_ia32_am_scale(node, addr->scale);
548 set_ia32_am_sc(node, addr->symconst_ent);
549 set_ia32_am_offs_int(node, addr->offset);
550 if (addr->symconst_sign)
551 set_ia32_am_sc_sign(node);
553 set_ia32_use_frame(node);
554 set_ia32_frame_ent(node, addr->frame_entity);
558 * Apply attributes of a given address mode to a node.
560 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
562 set_address(node, &am->addr);
564 set_ia32_op_type(node, am->op_type);
565 set_ia32_ls_mode(node, am->ls_mode);
566 if (am->pinned == op_pin_state_pinned) {
567 /* beware: some nodes are already pinned and did not allow to change the state */
568 if (get_irn_pinned(node) != op_pin_state_pinned)
569 set_irn_pinned(node, op_pin_state_pinned);
572 set_ia32_commutative(node);
576 * Check, if a given node is a Down-Conv, ie. a integer Conv
577 * from a mode with a mode with more bits to a mode with lesser bits.
578 * Moreover, we return only true if the node has not more than 1 user.
580 * @param node the node
581 * @return non-zero if node is a Down-Conv
583 static int is_downconv(const ir_node *node)
591 /* we only want to skip the conv when we're the only user
592 * (not optimal but for now...)
594 if (get_irn_n_edges(node) > 1)
597 src_mode = get_irn_mode(get_Conv_op(node));
598 dest_mode = get_irn_mode(node);
599 return ia32_mode_needs_gp_reg(src_mode)
600 && ia32_mode_needs_gp_reg(dest_mode)
601 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
604 /* Skip all Down-Conv's on a given node and return the resulting node. */
605 ir_node *ia32_skip_downconv(ir_node *node)
607 while (is_downconv(node))
608 node = get_Conv_op(node);
613 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
615 ir_mode *mode = get_irn_mode(node);
620 if (mode_is_signed(mode)) {
625 block = get_nodes_block(node);
626 dbgi = get_irn_dbg_info(node);
628 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
632 * matches operands of a node into ia32 addressing/operand modes. This covers
633 * usage of source address mode, immediates, operations with non 32-bit modes,
635 * The resulting data is filled into the @p am struct. block is the block
636 * of the node whose arguments are matched. op1, op2 are the first and second
637 * input that are matched (op1 may be NULL). other_op is another unrelated
638 * input that is not matched! but which is needed sometimes to check if AM
639 * for op1/op2 is legal.
640 * @p flags describes the supported modes of the operation in detail.
642 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
643 ir_node *op1, ir_node *op2, ir_node *other_op,
646 ia32_address_t *addr = &am->addr;
647 ir_mode *mode = get_irn_mode(op2);
648 int mode_bits = get_mode_size_bits(mode);
649 ir_node *noreg_gp, *new_op1, *new_op2;
651 unsigned commutative;
652 int use_am_and_immediates;
655 memset(am, 0, sizeof(am[0]));
657 commutative = (flags & match_commutative) != 0;
658 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
659 use_am = (flags & match_am) != 0;
660 use_immediate = (flags & match_immediate) != 0;
661 assert(!use_am_and_immediates || use_immediate);
664 assert(!commutative || op1 != NULL);
665 assert(use_am || !(flags & match_8bit_am));
666 assert(use_am || !(flags & match_16bit_am));
668 if (mode_bits == 8) {
669 if (!(flags & match_8bit_am))
671 /* we don't automatically add upconvs yet */
672 assert((flags & match_mode_neutral) || (flags & match_8bit));
673 } else if (mode_bits == 16) {
674 if (!(flags & match_16bit_am))
676 /* we don't automatically add upconvs yet */
677 assert((flags & match_mode_neutral) || (flags & match_16bit));
680 /* we can simply skip downconvs for mode neutral nodes: the upper bits
681 * can be random for these operations */
682 if (flags & match_mode_neutral) {
683 op2 = ia32_skip_downconv(op2);
685 op1 = ia32_skip_downconv(op1);
689 /* match immediates. firm nodes are normalized: constants are always on the
692 if (!(flags & match_try_am) && use_immediate) {
693 new_op2 = try_create_Immediate(op2, 0);
696 noreg_gp = ia32_new_NoReg_gp(env_cg);
697 if (new_op2 == NULL &&
698 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
699 build_address(am, op2);
700 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
701 if (mode_is_float(mode)) {
702 new_op2 = ia32_new_NoReg_vfp(env_cg);
706 am->op_type = ia32_AddrModeS;
707 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
709 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
711 build_address(am, op1);
713 if (mode_is_float(mode)) {
714 noreg = ia32_new_NoReg_vfp(env_cg);
719 if (new_op2 != NULL) {
722 new_op1 = be_transform_node(op2);
724 am->ins_permuted = 1;
726 am->op_type = ia32_AddrModeS;
728 am->op_type = ia32_Normal;
730 if (flags & match_try_am) {
736 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
738 new_op2 = be_transform_node(op2);
740 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
742 if (addr->base == NULL)
743 addr->base = noreg_gp;
744 if (addr->index == NULL)
745 addr->index = noreg_gp;
746 if (addr->mem == NULL)
747 addr->mem = new_NoMem();
749 am->new_op1 = new_op1;
750 am->new_op2 = new_op2;
751 am->commutative = commutative;
754 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
759 if (am->mem_proj == NULL)
762 /* we have to create a mode_T so the old MemProj can attach to us */
763 mode = get_irn_mode(node);
764 load = get_Proj_pred(am->mem_proj);
766 be_set_transformed_node(load, node);
768 if (mode != mode_T) {
769 set_irn_mode(node, mode_T);
770 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
777 * Construct a standard binary operation, set AM and immediate if required.
779 * @param node The original node for which the binop is created
780 * @param op1 The first operand
781 * @param op2 The second operand
782 * @param func The node constructor function
783 * @return The constructed ia32 node.
785 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
786 construct_binop_func *func, match_flags_t flags)
789 ir_node *block, *new_block, *new_node;
790 ia32_address_mode_t am;
791 ia32_address_t *addr = &am.addr;
793 block = get_nodes_block(node);
794 match_arguments(&am, block, op1, op2, NULL, flags);
796 dbgi = get_irn_dbg_info(node);
797 new_block = be_transform_node(block);
798 new_node = func(dbgi, current_ir_graph, new_block,
799 addr->base, addr->index, addr->mem,
800 am.new_op1, am.new_op2);
801 set_am_attributes(new_node, &am);
802 /* we can't use source address mode anymore when using immediates */
803 if (!(flags & match_am_and_immediates) &&
804 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
805 set_ia32_am_support(new_node, ia32_am_none);
806 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
808 new_node = fix_mem_proj(new_node, &am);
815 n_ia32_l_binop_right,
816 n_ia32_l_binop_eflags
818 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
819 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
820 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
821 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
822 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
823 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
826 * Construct a binary operation which also consumes the eflags.
828 * @param node The node to transform
829 * @param func The node constructor function
830 * @param flags The match flags
831 * @return The constructor ia32 node
833 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
836 ir_node *src_block = get_nodes_block(node);
837 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
838 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
839 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
841 ir_node *block, *new_node, *new_eflags;
842 ia32_address_mode_t am;
843 ia32_address_t *addr = &am.addr;
845 match_arguments(&am, src_block, op1, op2, eflags, flags);
847 dbgi = get_irn_dbg_info(node);
848 block = be_transform_node(src_block);
849 new_eflags = be_transform_node(eflags);
850 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
851 addr->mem, am.new_op1, am.new_op2, new_eflags);
852 set_am_attributes(new_node, &am);
853 /* we can't use source address mode anymore when using immediates */
854 if (!(flags & match_am_and_immediates) &&
855 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
856 set_ia32_am_support(new_node, ia32_am_none);
857 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
859 new_node = fix_mem_proj(new_node, &am);
864 static ir_node *get_fpcw(void)
867 if (initial_fpcw != NULL)
870 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
871 &ia32_fp_cw_regs[REG_FPCW]);
872 initial_fpcw = be_transform_node(fpcw);
878 * Construct a standard binary operation, set AM and immediate if required.
880 * @param op1 The first operand
881 * @param op2 The second operand
882 * @param func The node constructor function
883 * @return The constructed ia32 node.
885 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
886 construct_binop_float_func *func)
888 ir_mode *mode = get_irn_mode(node);
890 ir_node *block, *new_block, *new_node;
891 ia32_address_mode_t am;
892 ia32_address_t *addr = &am.addr;
893 ia32_x87_attr_t *attr;
894 /* All operations are considered commutative, because there are reverse
896 match_flags_t flags = match_commutative;
898 /* cannot use address mode with long double on x87 */
899 if (get_mode_size_bits(mode) <= 64)
902 block = get_nodes_block(node);
903 match_arguments(&am, block, op1, op2, NULL, flags);
905 dbgi = get_irn_dbg_info(node);
906 new_block = be_transform_node(block);
907 new_node = func(dbgi, current_ir_graph, new_block,
908 addr->base, addr->index, addr->mem,
909 am.new_op1, am.new_op2, get_fpcw());
910 set_am_attributes(new_node, &am);
912 attr = get_ia32_x87_attr(new_node);
913 attr->attr.data.ins_permuted = am.ins_permuted;
915 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
917 new_node = fix_mem_proj(new_node, &am);
923 * Construct a shift/rotate binary operation, sets AM and immediate if required.
925 * @param op1 The first operand
926 * @param op2 The second operand
927 * @param func The node constructor function
928 * @return The constructed ia32 node.
930 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
931 construct_shift_func *func,
935 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
937 assert(! mode_is_float(get_irn_mode(node)));
938 assert(flags & match_immediate);
939 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
941 if (flags & match_mode_neutral) {
942 op1 = ia32_skip_downconv(op1);
943 new_op1 = be_transform_node(op1);
944 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
945 new_op1 = create_upconv(op1, node);
947 new_op1 = be_transform_node(op1);
950 /* the shift amount can be any mode that is bigger than 5 bits, since all
951 * other bits are ignored anyway */
952 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
953 ir_node *const op = get_Conv_op(op2);
954 if (mode_is_float(get_irn_mode(op)))
957 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
959 new_op2 = create_immediate_or_transform(op2, 0);
961 dbgi = get_irn_dbg_info(node);
962 block = get_nodes_block(node);
963 new_block = be_transform_node(block);
964 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
965 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
967 /* lowered shift instruction may have a dependency operand, handle it here */
968 if (get_irn_arity(node) == 3) {
969 /* we have a dependency */
970 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
971 add_irn_dep(new_node, new_dep);
979 * Construct a standard unary operation, set AM and immediate if required.
981 * @param op The operand
982 * @param func The node constructor function
983 * @return The constructed ia32 node.
985 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
989 ir_node *block, *new_block, *new_op, *new_node;
991 assert(flags == 0 || flags == match_mode_neutral);
992 if (flags & match_mode_neutral) {
993 op = ia32_skip_downconv(op);
996 new_op = be_transform_node(op);
997 dbgi = get_irn_dbg_info(node);
998 block = get_nodes_block(node);
999 new_block = be_transform_node(block);
1000 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1002 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1007 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1008 ia32_address_t *addr)
1010 ir_node *base, *index, *res;
1014 base = ia32_new_NoReg_gp(env_cg);
1016 base = be_transform_node(base);
1019 index = addr->index;
1020 if (index == NULL) {
1021 index = ia32_new_NoReg_gp(env_cg);
1023 index = be_transform_node(index);
1026 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1027 set_address(res, addr);
1033 * Returns non-zero if a given address mode has a symbolic or
1034 * numerical offset != 0.
1036 static int am_has_immediates(const ia32_address_t *addr)
1038 return addr->offset != 0 || addr->symconst_ent != NULL
1039 || addr->frame_entity || addr->use_frame;
1043 * Creates an ia32 Add.
1045 * @return the created ia32 Add node
1047 static ir_node *gen_Add(ir_node *node)
1049 ir_mode *mode = get_irn_mode(node);
1050 ir_node *op1 = get_Add_left(node);
1051 ir_node *op2 = get_Add_right(node);
1053 ir_node *block, *new_block, *new_node, *add_immediate_op;
1054 ia32_address_t addr;
1055 ia32_address_mode_t am;
1057 if (mode_is_float(mode)) {
1058 if (ia32_cg_config.use_sse2)
1059 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1060 match_commutative | match_am);
1062 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd);
1065 ia32_mark_non_am(node);
1067 op2 = ia32_skip_downconv(op2);
1068 op1 = ia32_skip_downconv(op1);
1072 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1073 * 1. Add with immediate -> Lea
1074 * 2. Add with possible source address mode -> Add
1075 * 3. Otherwise -> Lea
1077 memset(&addr, 0, sizeof(addr));
1078 ia32_create_address_mode(&addr, node, /*force=*/1);
1079 add_immediate_op = NULL;
1081 dbgi = get_irn_dbg_info(node);
1082 block = get_nodes_block(node);
1083 new_block = be_transform_node(block);
1086 if (addr.base == NULL && addr.index == NULL) {
1087 ir_graph *irg = current_ir_graph;
1088 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1089 addr.symconst_sign, addr.offset);
1090 be_dep_on_frame(new_node);
1091 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1094 /* add with immediate? */
1095 if (addr.index == NULL) {
1096 add_immediate_op = addr.base;
1097 } else if (addr.base == NULL && addr.scale == 0) {
1098 add_immediate_op = addr.index;
1101 if (add_immediate_op != NULL) {
1102 if (!am_has_immediates(&addr)) {
1103 #ifdef DEBUG_libfirm
1104 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1107 return be_transform_node(add_immediate_op);
1110 new_node = create_lea_from_address(dbgi, new_block, &addr);
1111 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1115 /* test if we can use source address mode */
1116 match_arguments(&am, block, op1, op2, NULL, match_commutative
1117 | match_mode_neutral | match_am | match_immediate | match_try_am);
1119 /* construct an Add with source address mode */
1120 if (am.op_type == ia32_AddrModeS) {
1121 ir_graph *irg = current_ir_graph;
1122 ia32_address_t *am_addr = &am.addr;
1123 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1124 am_addr->index, am_addr->mem, am.new_op1,
1126 set_am_attributes(new_node, &am);
1127 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1129 new_node = fix_mem_proj(new_node, &am);
1134 /* otherwise construct a lea */
1135 new_node = create_lea_from_address(dbgi, new_block, &addr);
1136 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1141 * Creates an ia32 Mul.
1143 * @return the created ia32 Mul node
1145 static ir_node *gen_Mul(ir_node *node)
1147 ir_node *op1 = get_Mul_left(node);
1148 ir_node *op2 = get_Mul_right(node);
1149 ir_mode *mode = get_irn_mode(node);
1151 if (mode_is_float(mode)) {
1152 if (ia32_cg_config.use_sse2)
1153 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1154 match_commutative | match_am);
1156 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul);
1158 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1159 match_commutative | match_am | match_mode_neutral |
1160 match_immediate | match_am_and_immediates);
1164 * Creates an ia32 Mulh.
1165 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1166 * this result while Mul returns the lower 32 bit.
1168 * @return the created ia32 Mulh node
1170 static ir_node *gen_Mulh(ir_node *node)
1172 ir_node *block = get_nodes_block(node);
1173 ir_node *new_block = be_transform_node(block);
1174 dbg_info *dbgi = get_irn_dbg_info(node);
1175 ir_node *op1 = get_Mulh_left(node);
1176 ir_node *op2 = get_Mulh_right(node);
1177 ir_mode *mode = get_irn_mode(node);
1179 ir_node *proj_res_high;
1181 if (mode_is_signed(mode)) {
1182 new_node = gen_binop(node, op1, op2, new_rd_ia32_IMul1OP, match_commutative | match_am);
1183 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1184 mode_Iu, pn_ia32_IMul1OP_res_high);
1186 new_node = gen_binop(node, op1, op2, new_rd_ia32_Mul, match_commutative | match_am);
1187 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1188 mode_Iu, pn_ia32_Mul_res_high);
1190 return proj_res_high;
1194 * Creates an ia32 And.
1196 * @return The created ia32 And node
1198 static ir_node *gen_And(ir_node *node)
1200 ir_node *op1 = get_And_left(node);
1201 ir_node *op2 = get_And_right(node);
1202 assert(! mode_is_float(get_irn_mode(node)));
1204 /* is it a zero extension? */
1205 if (is_Const(op2)) {
1206 tarval *tv = get_Const_tarval(op2);
1207 long v = get_tarval_long(tv);
1209 if (v == 0xFF || v == 0xFFFF) {
1210 dbg_info *dbgi = get_irn_dbg_info(node);
1211 ir_node *block = get_nodes_block(node);
1218 assert(v == 0xFFFF);
1221 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1226 return gen_binop(node, op1, op2, new_rd_ia32_And,
1227 match_commutative | match_mode_neutral | match_am
1234 * Creates an ia32 Or.
1236 * @return The created ia32 Or node
1238 static ir_node *gen_Or(ir_node *node)
1240 ir_node *op1 = get_Or_left(node);
1241 ir_node *op2 = get_Or_right(node);
1243 assert (! mode_is_float(get_irn_mode(node)));
1244 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1245 | match_mode_neutral | match_am | match_immediate);
1251 * Creates an ia32 Eor.
1253 * @return The created ia32 Eor node
1255 static ir_node *gen_Eor(ir_node *node)
1257 ir_node *op1 = get_Eor_left(node);
1258 ir_node *op2 = get_Eor_right(node);
1260 assert(! mode_is_float(get_irn_mode(node)));
1261 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1262 | match_mode_neutral | match_am | match_immediate);
1267 * Creates an ia32 Sub.
1269 * @return The created ia32 Sub node
1271 static ir_node *gen_Sub(ir_node *node)
1273 ir_node *op1 = get_Sub_left(node);
1274 ir_node *op2 = get_Sub_right(node);
1275 ir_mode *mode = get_irn_mode(node);
1277 if (mode_is_float(mode)) {
1278 if (ia32_cg_config.use_sse2)
1279 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1281 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub);
1284 if (is_Const(op2)) {
1285 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1289 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1290 | match_am | match_immediate);
1293 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1294 ir_node *const src_val,
1295 ir_node *const src_mem,
1296 ir_node *const am_mem)
1298 if (is_NoMem(am_mem)) {
1299 return be_transform_node(src_mem);
1300 } else if (is_Proj(src_val) &&
1302 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1303 /* avoid memory loop */
1305 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1306 ir_node *const ptr_pred = get_Proj_pred(src_val);
1307 int const arity = get_Sync_n_preds(src_mem);
1312 NEW_ARR_A(ir_node*, ins, arity + 1);
1314 for (i = arity - 1; i >= 0; --i) {
1315 ir_node *const pred = get_Sync_pred(src_mem, i);
1317 /* avoid memory loop */
1318 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1321 ins[n++] = be_transform_node(pred);
1326 return new_r_Sync(irg, block, n, ins);
1330 ins[0] = be_transform_node(src_mem);
1332 return new_r_Sync(irg, block, 2, ins);
1337 * Generates an ia32 DivMod with additional infrastructure for the
1338 * register allocator if needed.
1340 static ir_node *create_Div(ir_node *node)
1342 ir_graph *irg = current_ir_graph;
1343 dbg_info *dbgi = get_irn_dbg_info(node);
1344 ir_node *block = get_nodes_block(node);
1345 ir_node *new_block = be_transform_node(block);
1352 ir_node *sign_extension;
1353 ia32_address_mode_t am;
1354 ia32_address_t *addr = &am.addr;
1356 /* the upper bits have random contents for smaller modes */
1357 switch (get_irn_opcode(node)) {
1359 op1 = get_Div_left(node);
1360 op2 = get_Div_right(node);
1361 mem = get_Div_mem(node);
1362 mode = get_Div_resmode(node);
1365 op1 = get_Mod_left(node);
1366 op2 = get_Mod_right(node);
1367 mem = get_Mod_mem(node);
1368 mode = get_Mod_resmode(node);
1371 op1 = get_DivMod_left(node);
1372 op2 = get_DivMod_right(node);
1373 mem = get_DivMod_mem(node);
1374 mode = get_DivMod_resmode(node);
1377 panic("invalid divmod node %+F", node);
1380 match_arguments(&am, block, op1, op2, NULL, match_am);
1382 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1383 is the memory of the consumed address. We can have only the second op as address
1384 in Div nodes, so check only op2. */
1385 new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem);
1387 if (mode_is_signed(mode)) {
1388 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1389 be_dep_on_frame(produceval);
1390 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1393 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1394 addr->index, new_mem, am.new_op2,
1395 am.new_op1, sign_extension);
1397 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1398 be_dep_on_frame(sign_extension);
1400 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1401 addr->index, new_mem, am.new_op2,
1402 am.new_op1, sign_extension);
1405 set_irn_pinned(new_node, get_irn_pinned(node));
1407 set_am_attributes(new_node, &am);
1408 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1410 new_node = fix_mem_proj(new_node, &am);
1416 static ir_node *gen_Mod(ir_node *node)
1418 return create_Div(node);
1421 static ir_node *gen_Div(ir_node *node)
1423 return create_Div(node);
1426 static ir_node *gen_DivMod(ir_node *node)
1428 return create_Div(node);
1434 * Creates an ia32 floating Div.
1436 * @return The created ia32 xDiv node
1438 static ir_node *gen_Quot(ir_node *node)
1440 ir_node *op1 = get_Quot_left(node);
1441 ir_node *op2 = get_Quot_right(node);
1443 if (ia32_cg_config.use_sse2) {
1444 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1446 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv);
1452 * Creates an ia32 Shl.
1454 * @return The created ia32 Shl node
1456 static ir_node *gen_Shl(ir_node *node)
1458 ir_node *left = get_Shl_left(node);
1459 ir_node *right = get_Shl_right(node);
1461 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1462 match_mode_neutral | match_immediate);
1466 * Creates an ia32 Shr.
1468 * @return The created ia32 Shr node
1470 static ir_node *gen_Shr(ir_node *node)
1472 ir_node *left = get_Shr_left(node);
1473 ir_node *right = get_Shr_right(node);
1475 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1481 * Creates an ia32 Sar.
1483 * @return The created ia32 Shrs node
1485 static ir_node *gen_Shrs(ir_node *node)
1487 ir_node *left = get_Shrs_left(node);
1488 ir_node *right = get_Shrs_right(node);
1489 ir_mode *mode = get_irn_mode(node);
1491 if (is_Const(right) && mode == mode_Is) {
1492 tarval *tv = get_Const_tarval(right);
1493 long val = get_tarval_long(tv);
1495 /* this is a sign extension */
1496 ir_graph *irg = current_ir_graph;
1497 dbg_info *dbgi = get_irn_dbg_info(node);
1498 ir_node *block = be_transform_node(get_nodes_block(node));
1500 ir_node *new_op = be_transform_node(op);
1501 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1503 be_dep_on_frame(pval);
1504 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1508 /* 8 or 16 bit sign extension? */
1509 if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1510 ir_node *shl_left = get_Shl_left(left);
1511 ir_node *shl_right = get_Shl_right(left);
1512 if (is_Const(shl_right)) {
1513 tarval *tv1 = get_Const_tarval(right);
1514 tarval *tv2 = get_Const_tarval(shl_right);
1515 if (tv1 == tv2 && tarval_is_long(tv1)) {
1516 long val = get_tarval_long(tv1);
1517 if (val == 16 || val == 24) {
1518 dbg_info *dbgi = get_irn_dbg_info(node);
1519 ir_node *block = get_nodes_block(node);
1529 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1538 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1544 * Creates an ia32 Rol.
1546 * @param op1 The first operator
1547 * @param op2 The second operator
1548 * @return The created ia32 RotL node
1550 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1552 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1558 * Creates an ia32 Ror.
1559 * NOTE: There is no RotR with immediate because this would always be a RotL
1560 * "imm-mode_size_bits" which can be pre-calculated.
1562 * @param op1 The first operator
1563 * @param op2 The second operator
1564 * @return The created ia32 RotR node
1566 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1568 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1574 * Creates an ia32 RotR or RotL (depending on the found pattern).
1576 * @return The created ia32 RotL or RotR node
1578 static ir_node *gen_Rotl(ir_node *node)
1580 ir_node *rotate = NULL;
1581 ir_node *op1 = get_Rotl_left(node);
1582 ir_node *op2 = get_Rotl_right(node);
1584 /* Firm has only RotL, so we are looking for a right (op2)
1585 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1586 that means we can create a RotR instead of an Add and a RotL */
1590 ir_node *left = get_Add_left(add);
1591 ir_node *right = get_Add_right(add);
1592 if (is_Const(right)) {
1593 tarval *tv = get_Const_tarval(right);
1594 ir_mode *mode = get_irn_mode(node);
1595 long bits = get_mode_size_bits(mode);
1597 if (is_Minus(left) &&
1598 tarval_is_long(tv) &&
1599 get_tarval_long(tv) == bits &&
1602 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1603 rotate = gen_Ror(node, op1, get_Minus_op(left));
1608 if (rotate == NULL) {
1609 rotate = gen_Rol(node, op1, op2);
1618 * Transforms a Minus node.
1620 * @return The created ia32 Minus node
1622 static ir_node *gen_Minus(ir_node *node)
1624 ir_node *op = get_Minus_op(node);
1625 ir_node *block = be_transform_node(get_nodes_block(node));
1626 ir_graph *irg = current_ir_graph;
1627 dbg_info *dbgi = get_irn_dbg_info(node);
1628 ir_mode *mode = get_irn_mode(node);
1633 if (mode_is_float(mode)) {
1634 ir_node *new_op = be_transform_node(op);
1635 if (ia32_cg_config.use_sse2) {
1636 /* TODO: non-optimal... if we have many xXors, then we should
1637 * rather create a load for the const and use that instead of
1638 * several AM nodes... */
1639 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1640 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1641 ir_node *nomem = new_rd_NoMem(irg);
1643 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1644 nomem, new_op, noreg_xmm);
1646 size = get_mode_size_bits(mode);
1647 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1649 set_ia32_am_sc(new_node, ent);
1650 set_ia32_op_type(new_node, ia32_AddrModeS);
1651 set_ia32_ls_mode(new_node, mode);
1653 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1656 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1659 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1665 * Transforms a Not node.
1667 * @return The created ia32 Not node
1669 static ir_node *gen_Not(ir_node *node)
1671 ir_node *op = get_Not_op(node);
1673 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1674 assert (! mode_is_float(get_irn_mode(node)));
1676 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1682 * Transforms an Abs node.
1684 * @return The created ia32 Abs node
1686 static ir_node *gen_Abs(ir_node *node)
1688 ir_node *block = get_nodes_block(node);
1689 ir_node *new_block = be_transform_node(block);
1690 ir_node *op = get_Abs_op(node);
1691 ir_graph *irg = current_ir_graph;
1692 dbg_info *dbgi = get_irn_dbg_info(node);
1693 ir_mode *mode = get_irn_mode(node);
1694 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1695 ir_node *nomem = new_NoMem();
1701 if (mode_is_float(mode)) {
1702 new_op = be_transform_node(op);
1704 if (ia32_cg_config.use_sse2) {
1705 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1706 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1707 nomem, new_op, noreg_fp);
1709 size = get_mode_size_bits(mode);
1710 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1712 set_ia32_am_sc(new_node, ent);
1714 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1716 set_ia32_op_type(new_node, ia32_AddrModeS);
1717 set_ia32_ls_mode(new_node, mode);
1719 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1720 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1723 ir_node *xor, *pval, *sign_extension;
1725 if (get_mode_size_bits(mode) == 32) {
1726 new_op = be_transform_node(op);
1728 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1731 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1732 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1735 be_dep_on_frame(pval);
1736 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1738 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1739 nomem, new_op, sign_extension);
1740 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1742 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1743 nomem, xor, sign_extension);
1744 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1751 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1753 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1755 dbg_info *dbgi = get_irn_dbg_info(cmp);
1756 ir_node *block = get_nodes_block(cmp);
1757 ir_node *new_block = be_transform_node(block);
1758 ir_node *op1 = be_transform_node(x);
1759 ir_node *op2 = be_transform_node(n);
1761 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1765 * Transform a node returning a "flag" result.
1767 * @param node the node to transform
1768 * @param pnc_out the compare mode to use
1770 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1779 /* we have a Cmp as input */
1780 if (is_Proj(node)) {
1781 ir_node *pred = get_Proj_pred(node);
1783 pn_Cmp pnc = get_Proj_proj(node);
1784 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1785 ir_node *l = get_Cmp_left(pred);
1786 ir_node *r = get_Cmp_right(pred);
1788 ir_node *la = get_And_left(l);
1789 ir_node *ra = get_And_right(l);
1791 ir_node *c = get_Shl_left(la);
1792 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1793 /* (1 << n) & ra) */
1794 ir_node *n = get_Shl_right(la);
1795 flags = gen_bt(pred, ra, n);
1796 /* we must generate a Jc/Jnc jump */
1797 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1800 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1805 ir_node *c = get_Shl_left(ra);
1806 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1807 /* la & (1 << n)) */
1808 ir_node *n = get_Shl_right(ra);
1809 flags = gen_bt(pred, la, n);
1810 /* we must generate a Jc/Jnc jump */
1811 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1814 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1820 flags = be_transform_node(pred);
1826 /* a mode_b value, we have to compare it against 0 */
1827 dbgi = get_irn_dbg_info(node);
1828 new_block = be_transform_node(get_nodes_block(node));
1829 new_op = be_transform_node(node);
1830 noreg = ia32_new_NoReg_gp(env_cg);
1831 nomem = new_NoMem();
1832 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1833 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1834 *pnc_out = pn_Cmp_Lg;
1839 * Transforms a Load.
1841 * @return the created ia32 Load node
1843 static ir_node *gen_Load(ir_node *node)
1845 ir_node *old_block = get_nodes_block(node);
1846 ir_node *block = be_transform_node(old_block);
1847 ir_node *ptr = get_Load_ptr(node);
1848 ir_node *mem = get_Load_mem(node);
1849 ir_node *new_mem = be_transform_node(mem);
1852 ir_graph *irg = current_ir_graph;
1853 dbg_info *dbgi = get_irn_dbg_info(node);
1854 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1855 ir_mode *mode = get_Load_mode(node);
1858 ia32_address_t addr;
1860 /* construct load address */
1861 memset(&addr, 0, sizeof(addr));
1862 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1869 base = be_transform_node(base);
1872 if (index == NULL) {
1875 index = be_transform_node(index);
1878 if (mode_is_float(mode)) {
1879 if (ia32_cg_config.use_sse2) {
1880 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1882 res_mode = mode_xmm;
1884 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1886 res_mode = mode_vfp;
1889 assert(mode != mode_b);
1891 /* create a conv node with address mode for smaller modes */
1892 if (get_mode_size_bits(mode) < 32) {
1893 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1894 new_mem, noreg, mode);
1896 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1901 set_irn_pinned(new_node, get_irn_pinned(node));
1902 set_ia32_op_type(new_node, ia32_AddrModeS);
1903 set_ia32_ls_mode(new_node, mode);
1904 set_address(new_node, &addr);
1906 if (get_irn_pinned(node) == op_pin_state_floats) {
1907 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1910 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1912 be_dep_on_frame(new_node);
1916 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1917 ir_node *ptr, ir_node *other)
1924 /* we only use address mode if we're the only user of the load */
1925 if (get_irn_n_edges(node) > 1)
1928 load = get_Proj_pred(node);
1931 if (get_nodes_block(load) != block)
1934 /* store should have the same pointer as the load */
1935 if (get_Load_ptr(load) != ptr)
1938 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1939 if (other != NULL &&
1940 get_nodes_block(other) == block &&
1941 heights_reachable_in_block(heights, other, load)) {
1948 for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
1949 ir_node *const pred = get_Sync_pred(mem, i);
1951 if (is_Proj(pred) && get_Proj_pred(pred) == load)
1954 if (get_nodes_block(pred) == block &&
1955 heights_reachable_in_block(heights, pred, load)) {
1960 /* Store should be attached to the load */
1961 if (!is_Proj(mem) || get_Proj_pred(mem) != load)
1968 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1969 ir_node *mem, ir_node *ptr, ir_mode *mode,
1970 construct_binop_dest_func *func,
1971 construct_binop_dest_func *func8bit,
1972 match_flags_t flags)
1974 ir_node *src_block = get_nodes_block(node);
1976 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1977 ir_graph *irg = current_ir_graph;
1984 ia32_address_mode_t am;
1985 ia32_address_t *addr = &am.addr;
1986 memset(&am, 0, sizeof(am));
1988 assert(flags & match_dest_am);
1989 assert(flags & match_immediate); /* there is no destam node without... */
1990 commutative = (flags & match_commutative) != 0;
1992 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1993 build_address(&am, op1);
1994 new_op = create_immediate_or_transform(op2, 0);
1995 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1996 build_address(&am, op2);
1997 new_op = create_immediate_or_transform(op1, 0);
2002 if (addr->base == NULL)
2003 addr->base = noreg_gp;
2004 if (addr->index == NULL)
2005 addr->index = noreg_gp;
2006 if (addr->mem == NULL)
2007 addr->mem = new_NoMem();
2009 dbgi = get_irn_dbg_info(node);
2010 block = be_transform_node(src_block);
2011 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2013 if (get_mode_size_bits(mode) == 8) {
2014 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2017 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
2020 set_address(new_node, addr);
2021 set_ia32_op_type(new_node, ia32_AddrModeD);
2022 set_ia32_ls_mode(new_node, mode);
2023 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2025 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2026 mem_proj = be_transform_node(am.mem_proj);
2027 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2032 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2033 ir_node *ptr, ir_mode *mode,
2034 construct_unop_dest_func *func)
2036 ir_graph *irg = current_ir_graph;
2037 ir_node *src_block = get_nodes_block(node);
2043 ia32_address_mode_t am;
2044 ia32_address_t *addr = &am.addr;
2045 memset(&am, 0, sizeof(am));
2047 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2050 build_address(&am, op);
2052 dbgi = get_irn_dbg_info(node);
2053 block = be_transform_node(src_block);
2054 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2055 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2056 set_address(new_node, addr);
2057 set_ia32_op_type(new_node, ia32_AddrModeD);
2058 set_ia32_ls_mode(new_node, mode);
2059 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2061 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2062 mem_proj = be_transform_node(am.mem_proj);
2063 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2068 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2070 ir_mode *mode = get_irn_mode(node);
2071 ir_node *mux_true = get_Mux_true(node);
2072 ir_node *mux_false = get_Mux_false(node);
2083 ia32_address_t addr;
2085 if (get_mode_size_bits(mode) != 8)
2088 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2090 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2096 build_address_ptr(&addr, ptr, mem);
2098 irg = current_ir_graph;
2099 dbgi = get_irn_dbg_info(node);
2100 block = get_nodes_block(node);
2101 new_block = be_transform_node(block);
2102 cond = get_Mux_sel(node);
2103 flags = get_flags_node(cond, &pnc);
2104 new_mem = be_transform_node(mem);
2105 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2106 addr.index, addr.mem, flags, pnc, negated);
2107 set_address(new_node, &addr);
2108 set_ia32_op_type(new_node, ia32_AddrModeD);
2109 set_ia32_ls_mode(new_node, mode);
2110 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2115 static ir_node *try_create_dest_am(ir_node *node)
2117 ir_node *val = get_Store_value(node);
2118 ir_node *mem = get_Store_mem(node);
2119 ir_node *ptr = get_Store_ptr(node);
2120 ir_mode *mode = get_irn_mode(val);
2121 unsigned bits = get_mode_size_bits(mode);
2126 /* handle only GP modes for now... */
2127 if (!ia32_mode_needs_gp_reg(mode))
2131 /* store must be the only user of the val node */
2132 if (get_irn_n_edges(val) > 1)
2134 /* skip pointless convs */
2136 ir_node *conv_op = get_Conv_op(val);
2137 ir_mode *pred_mode = get_irn_mode(conv_op);
2138 if (!ia32_mode_needs_gp_reg(pred_mode))
2140 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2148 /* value must be in the same block */
2149 if (get_nodes_block(node) != get_nodes_block(val))
2152 switch (get_irn_opcode(val)) {
2154 op1 = get_Add_left(val);
2155 op2 = get_Add_right(val);
2156 if (ia32_cg_config.use_incdec) {
2157 if (is_Const_1(op2)) {
2158 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_IncMem);
2160 } else if (is_Const_Minus_1(op2)) {
2161 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_DecMem);
2165 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2166 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2167 match_dest_am | match_commutative |
2171 op1 = get_Sub_left(val);
2172 op2 = get_Sub_right(val);
2173 if (is_Const(op2)) {
2174 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2176 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2177 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2178 match_dest_am | match_immediate |
2182 op1 = get_And_left(val);
2183 op2 = get_And_right(val);
2184 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2185 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2186 match_dest_am | match_commutative |
2190 op1 = get_Or_left(val);
2191 op2 = get_Or_right(val);
2192 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2193 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2194 match_dest_am | match_commutative |
2198 op1 = get_Eor_left(val);
2199 op2 = get_Eor_right(val);
2200 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2201 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2202 match_dest_am | match_commutative |
2206 op1 = get_Shl_left(val);
2207 op2 = get_Shl_right(val);
2208 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2209 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2210 match_dest_am | match_immediate);
2213 op1 = get_Shr_left(val);
2214 op2 = get_Shr_right(val);
2215 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2216 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2217 match_dest_am | match_immediate);
2220 op1 = get_Shrs_left(val);
2221 op2 = get_Shrs_right(val);
2222 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2223 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2224 match_dest_am | match_immediate);
2227 op1 = get_Rotl_left(val);
2228 op2 = get_Rotl_right(val);
2229 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2230 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2231 match_dest_am | match_immediate);
2233 /* TODO: match ROR patterns... */
2235 new_node = try_create_SetMem(val, ptr, mem);
2238 op1 = get_Minus_op(val);
2239 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2242 /* should be lowered already */
2243 assert(mode != mode_b);
2244 op1 = get_Not_op(val);
2245 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2251 if (new_node != NULL) {
2252 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2253 get_irn_pinned(node) == op_pin_state_pinned) {
2254 set_irn_pinned(new_node, op_pin_state_pinned);
2261 static int is_float_to_int_conv(const ir_node *node)
2263 ir_mode *mode = get_irn_mode(node);
2267 if (mode != mode_Is && mode != mode_Hs)
2272 conv_op = get_Conv_op(node);
2273 conv_mode = get_irn_mode(conv_op);
2275 if (!mode_is_float(conv_mode))
2282 * Transform a Store(floatConst).
2284 * @return the created ia32 Store node
2286 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2288 ir_mode *mode = get_irn_mode(cns);
2289 unsigned size = get_mode_size_bytes(mode);
2290 tarval *tv = get_Const_tarval(cns);
2291 ir_node *block = get_nodes_block(node);
2292 ir_node *new_block = be_transform_node(block);
2293 ir_node *ptr = get_Store_ptr(node);
2294 ir_node *mem = get_Store_mem(node);
2295 ir_graph *irg = current_ir_graph;
2296 dbg_info *dbgi = get_irn_dbg_info(node);
2300 ia32_address_t addr;
2302 assert(size % 4 == 0);
2305 build_address_ptr(&addr, ptr, mem);
2309 get_tarval_sub_bits(tv, ofs) |
2310 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2311 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2312 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2313 ir_node *imm = create_Immediate(NULL, 0, val);
2315 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2316 addr.index, addr.mem, imm);
2318 set_irn_pinned(new_node, get_irn_pinned(node));
2319 set_ia32_op_type(new_node, ia32_AddrModeD);
2320 set_ia32_ls_mode(new_node, mode_Iu);
2321 set_address(new_node, &addr);
2322 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2324 ins[i++] = new_node;
2329 } while (size != 0);
2331 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2335 * Generate a vfist or vfisttp instruction.
2337 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2338 ir_node *mem, ir_node *val, ir_node **fist)
2342 if (ia32_cg_config.use_fisttp) {
2343 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2344 if other users exists */
2345 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2346 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2347 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2348 be_new_Keep(reg_class, irg, block, 1, &value);
2350 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2353 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2356 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2362 * Transforms a normal Store.
2364 * @return the created ia32 Store node
2366 static ir_node *gen_normal_Store(ir_node *node)
2368 ir_node *val = get_Store_value(node);
2369 ir_mode *mode = get_irn_mode(val);
2370 ir_node *block = get_nodes_block(node);
2371 ir_node *new_block = be_transform_node(block);
2372 ir_node *ptr = get_Store_ptr(node);
2373 ir_node *mem = get_Store_mem(node);
2374 ir_graph *irg = current_ir_graph;
2375 dbg_info *dbgi = get_irn_dbg_info(node);
2376 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2377 ir_node *new_val, *new_node, *store;
2378 ia32_address_t addr;
2380 /* check for destination address mode */
2381 new_node = try_create_dest_am(node);
2382 if (new_node != NULL)
2385 /* construct store address */
2386 memset(&addr, 0, sizeof(addr));
2387 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2389 if (addr.base == NULL) {
2392 addr.base = be_transform_node(addr.base);
2395 if (addr.index == NULL) {
2398 addr.index = be_transform_node(addr.index);
2400 addr.mem = be_transform_node(mem);
2402 if (mode_is_float(mode)) {
2403 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2405 while (is_Conv(val) && mode == get_irn_mode(val)) {
2406 ir_node *op = get_Conv_op(val);
2407 if (!mode_is_float(get_irn_mode(op)))
2411 new_val = be_transform_node(val);
2412 if (ia32_cg_config.use_sse2) {
2413 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2414 addr.index, addr.mem, new_val);
2416 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2417 addr.index, addr.mem, new_val, mode);
2420 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2421 val = get_Conv_op(val);
2423 /* TODO: is this optimisation still necessary at all (middleend)? */
2424 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2425 while (is_Conv(val)) {
2426 ir_node *op = get_Conv_op(val);
2427 if (!mode_is_float(get_irn_mode(op)))
2429 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2433 new_val = be_transform_node(val);
2434 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2436 new_val = create_immediate_or_transform(val, 0);
2437 assert(mode != mode_b);
2439 if (get_mode_size_bits(mode) == 8) {
2440 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2441 addr.index, addr.mem, new_val);
2443 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2444 addr.index, addr.mem, new_val);
2449 set_irn_pinned(store, get_irn_pinned(node));
2450 set_ia32_op_type(store, ia32_AddrModeD);
2451 set_ia32_ls_mode(store, mode);
2453 set_address(store, &addr);
2454 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2460 * Transforms a Store.
2462 * @return the created ia32 Store node
2464 static ir_node *gen_Store(ir_node *node)
2466 ir_node *val = get_Store_value(node);
2467 ir_mode *mode = get_irn_mode(val);
2469 if (mode_is_float(mode) && is_Const(val)) {
2472 /* we are storing a floating point constant */
2473 if (ia32_cg_config.use_sse2) {
2474 transform = !is_simple_sse_Const(val);
2476 transform = !is_simple_x87_Const(val);
2479 return gen_float_const_Store(node, val);
2481 return gen_normal_Store(node);
2485 * Transforms a Switch.
2487 * @return the created ia32 SwitchJmp node
2489 static ir_node *create_Switch(ir_node *node)
2491 ir_graph *irg = current_ir_graph;
2492 dbg_info *dbgi = get_irn_dbg_info(node);
2493 ir_node *block = be_transform_node(get_nodes_block(node));
2494 ir_node *sel = get_Cond_selector(node);
2495 ir_node *new_sel = be_transform_node(sel);
2496 int switch_min = INT_MAX;
2497 int switch_max = INT_MIN;
2498 long default_pn = get_Cond_defaultProj(node);
2500 const ir_edge_t *edge;
2502 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2504 /* determine the smallest switch case value */
2505 foreach_out_edge(node, edge) {
2506 ir_node *proj = get_edge_src_irn(edge);
2507 long pn = get_Proj_proj(proj);
2508 if (pn == default_pn)
2511 if (pn < switch_min)
2513 if (pn > switch_max)
2517 if ((unsigned) (switch_max - switch_min) > 256000) {
2518 panic("Size of switch %+F bigger than 256000", node);
2521 if (switch_min != 0) {
2522 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2524 /* if smallest switch case is not 0 we need an additional sub */
2525 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2526 add_ia32_am_offs_int(new_sel, -switch_min);
2527 set_ia32_op_type(new_sel, ia32_AddrModeS);
2529 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2532 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2533 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2539 * Transform a Cond node.
2541 static ir_node *gen_Cond(ir_node *node)
2543 ir_node *block = get_nodes_block(node);
2544 ir_node *new_block = be_transform_node(block);
2545 ir_graph *irg = current_ir_graph;
2546 dbg_info *dbgi = get_irn_dbg_info(node);
2547 ir_node *sel = get_Cond_selector(node);
2548 ir_mode *sel_mode = get_irn_mode(sel);
2549 ir_node *flags = NULL;
2553 if (sel_mode != mode_b) {
2554 return create_Switch(node);
2557 /* we get flags from a Cmp */
2558 flags = get_flags_node(sel, &pnc);
2560 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2561 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2566 static ir_node *gen_be_Copy(ir_node *node)
2568 ir_node *new_node = be_duplicate_node(node);
2569 ir_mode *mode = get_irn_mode(new_node);
2571 if (ia32_mode_needs_gp_reg(mode)) {
2572 set_irn_mode(new_node, mode_Iu);
2578 static ir_node *create_Fucom(ir_node *node)
2580 ir_graph *irg = current_ir_graph;
2581 dbg_info *dbgi = get_irn_dbg_info(node);
2582 ir_node *block = get_nodes_block(node);
2583 ir_node *new_block = be_transform_node(block);
2584 ir_node *left = get_Cmp_left(node);
2585 ir_node *new_left = be_transform_node(left);
2586 ir_node *right = get_Cmp_right(node);
2590 if (ia32_cg_config.use_fucomi) {
2591 new_right = be_transform_node(right);
2592 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2594 set_ia32_commutative(new_node);
2595 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2597 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2598 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2601 new_right = be_transform_node(right);
2602 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2606 set_ia32_commutative(new_node);
2608 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2610 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2611 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2617 static ir_node *create_Ucomi(ir_node *node)
2619 ir_graph *irg = current_ir_graph;
2620 dbg_info *dbgi = get_irn_dbg_info(node);
2621 ir_node *src_block = get_nodes_block(node);
2622 ir_node *new_block = be_transform_node(src_block);
2623 ir_node *left = get_Cmp_left(node);
2624 ir_node *right = get_Cmp_right(node);
2626 ia32_address_mode_t am;
2627 ia32_address_t *addr = &am.addr;
2629 match_arguments(&am, src_block, left, right, NULL,
2630 match_commutative | match_am);
2632 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2633 addr->mem, am.new_op1, am.new_op2,
2635 set_am_attributes(new_node, &am);
2637 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2639 new_node = fix_mem_proj(new_node, &am);
2645 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2646 * to fold an and into a test node
2648 static bool can_fold_test_and(ir_node *node)
2650 const ir_edge_t *edge;
2652 /** we can only have eq and lg projs */
2653 foreach_out_edge(node, edge) {
2654 ir_node *proj = get_edge_src_irn(edge);
2655 pn_Cmp pnc = get_Proj_proj(proj);
2656 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2664 * returns true if it is assured, that the upper bits of a node are "clean"
2665 * which means for a 16 or 8 bit value, that the upper bits in the register
2666 * are 0 for unsigned and a copy of the last significant bit for signed
2669 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2671 assert(ia32_mode_needs_gp_reg(mode));
2672 if (get_mode_size_bits(mode) >= 32)
2675 if (is_Proj(transformed_node))
2676 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2678 if (is_ia32_Conv_I2I(transformed_node)
2679 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2680 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2681 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2683 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2689 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2690 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2691 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2692 const ia32_immediate_attr_t *attr
2693 = get_ia32_immediate_attr_const(right);
2694 if (attr->symconst == 0
2695 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2699 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2702 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2703 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2704 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2705 const ia32_immediate_attr_t *attr
2706 = get_ia32_immediate_attr_const(right);
2707 if (attr->symconst == 0
2708 && (unsigned) attr->offset
2709 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2716 /* TODO recurse on Or, Xor, ... if appropriate? */
2718 if (is_ia32_Immediate(transformed_node)
2719 || is_ia32_Const(transformed_node)) {
2720 const ia32_immediate_attr_t *attr
2721 = get_ia32_immediate_attr_const(transformed_node);
2722 if (mode_is_signed(mode)) {
2723 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2724 if (shifted == 0 || shifted == -1)
2727 unsigned long shifted = (unsigned long) attr->offset;
2728 shifted >>= get_mode_size_bits(mode);
2738 * Generate code for a Cmp.
2740 static ir_node *gen_Cmp(ir_node *node)
2742 ir_graph *irg = current_ir_graph;
2743 dbg_info *dbgi = get_irn_dbg_info(node);
2744 ir_node *block = get_nodes_block(node);
2745 ir_node *new_block = be_transform_node(block);
2746 ir_node *left = get_Cmp_left(node);
2747 ir_node *right = get_Cmp_right(node);
2748 ir_mode *cmp_mode = get_irn_mode(left);
2750 ia32_address_mode_t am;
2751 ia32_address_t *addr = &am.addr;
2754 if (mode_is_float(cmp_mode)) {
2755 if (ia32_cg_config.use_sse2) {
2756 return create_Ucomi(node);
2758 return create_Fucom(node);
2762 assert(ia32_mode_needs_gp_reg(cmp_mode));
2764 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2765 cmp_unsigned = !mode_is_signed(cmp_mode);
2766 if (is_Const_0(right) &&
2768 get_irn_n_edges(left) == 1 &&
2769 can_fold_test_and(node)) {
2770 /* Test(and_left, and_right) */
2771 ir_node *and_left = get_And_left(left);
2772 ir_node *and_right = get_And_right(left);
2774 /* matze: code here used mode instead of cmd_mode, I think it is always
2775 * the same as cmp_mode, but I leave this here to see if this is really
2778 assert(get_irn_mode(and_left) == cmp_mode);
2780 match_arguments(&am, block, and_left, and_right, NULL,
2782 match_am | match_8bit_am | match_16bit_am |
2783 match_am_and_immediates | match_immediate |
2784 match_8bit | match_16bit);
2786 /* use 32bit compare mode if possible since the opcode is smaller */
2787 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2788 upper_bits_clean(am.new_op2, cmp_mode)) {
2789 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2792 if (get_mode_size_bits(cmp_mode) == 8) {
2793 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2794 addr->index, addr->mem, am.new_op1,
2795 am.new_op2, am.ins_permuted,
2798 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2799 addr->index, addr->mem, am.new_op1,
2800 am.new_op2, am.ins_permuted,
2804 /* Cmp(left, right) */
2805 match_arguments(&am, block, left, right, NULL,
2806 match_commutative | match_am | match_8bit_am |
2807 match_16bit_am | match_am_and_immediates |
2808 match_immediate | match_8bit | match_16bit);
2809 /* use 32bit compare mode if possible since the opcode is smaller */
2810 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2811 upper_bits_clean(am.new_op2, cmp_mode)) {
2812 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2815 if (get_mode_size_bits(cmp_mode) == 8) {
2816 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2817 addr->index, addr->mem, am.new_op1,
2818 am.new_op2, am.ins_permuted,
2821 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2822 addr->index, addr->mem, am.new_op1,
2823 am.new_op2, am.ins_permuted, cmp_unsigned);
2826 set_am_attributes(new_node, &am);
2827 set_ia32_ls_mode(new_node, cmp_mode);
2829 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2831 new_node = fix_mem_proj(new_node, &am);
2836 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2839 ir_graph *irg = current_ir_graph;
2840 dbg_info *dbgi = get_irn_dbg_info(node);
2841 ir_node *block = get_nodes_block(node);
2842 ir_node *new_block = be_transform_node(block);
2843 ir_node *val_true = get_Mux_true(node);
2844 ir_node *val_false = get_Mux_false(node);
2846 match_flags_t match_flags;
2847 ia32_address_mode_t am;
2848 ia32_address_t *addr;
2850 assert(ia32_cg_config.use_cmov);
2851 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2855 match_flags = match_commutative | match_am | match_16bit_am |
2858 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2860 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2861 addr->mem, am.new_op1, am.new_op2, new_flags,
2862 am.ins_permuted, pnc);
2863 set_am_attributes(new_node, &am);
2865 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2867 new_node = fix_mem_proj(new_node, &am);
2873 * Creates a ia32 Setcc instruction.
2875 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2876 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2879 ir_graph *irg = current_ir_graph;
2880 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2881 ir_node *nomem = new_NoMem();
2882 ir_mode *mode = get_irn_mode(orig_node);
2885 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2886 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2888 /* we might need to conv the result up */
2889 if (get_mode_size_bits(mode) > 8) {
2890 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2891 nomem, new_node, mode_Bu);
2892 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2899 * Create instruction for an unsigned Difference or Zero.
2901 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2903 ir_graph *irg = current_ir_graph;
2904 ir_mode *mode = get_irn_mode(psi);
2905 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2908 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2909 match_mode_neutral | match_am | match_immediate | match_two_users);
2911 block = get_nodes_block(new_node);
2913 if (is_Proj(new_node)) {
2914 sub = get_Proj_pred(new_node);
2915 assert(is_ia32_Sub(sub));
2918 set_irn_mode(sub, mode_T);
2919 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2921 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2923 dbgi = get_irn_dbg_info(psi);
2924 noreg = ia32_new_NoReg_gp(env_cg);
2925 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2926 nomem = new_NoMem();
2927 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2929 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2930 set_ia32_commutative(new_node);
2935 * Transforms a Mux node into CMov.
2937 * @return The transformed node.
2939 static ir_node *gen_Mux(ir_node *node)
2941 dbg_info *dbgi = get_irn_dbg_info(node);
2942 ir_node *block = get_nodes_block(node);
2943 ir_node *new_block = be_transform_node(block);
2944 ir_node *mux_true = get_Mux_true(node);
2945 ir_node *mux_false = get_Mux_false(node);
2946 ir_node *cond = get_Mux_sel(node);
2947 ir_mode *mode = get_irn_mode(node);
2950 assert(get_irn_mode(cond) == mode_b);
2952 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2953 if (mode_is_float(mode)) {
2954 ir_node *cmp = get_Proj_pred(cond);
2955 ir_node *cmp_left = get_Cmp_left(cmp);
2956 ir_node *cmp_right = get_Cmp_right(cmp);
2957 pn_Cmp pnc = get_Proj_proj(cond);
2959 if (ia32_cg_config.use_sse2) {
2960 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2961 if (cmp_left == mux_true && cmp_right == mux_false) {
2962 /* Mux(a <= b, a, b) => MIN */
2963 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2964 match_commutative | match_am | match_two_users);
2965 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2966 /* Mux(a <= b, b, a) => MAX */
2967 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2968 match_commutative | match_am | match_two_users);
2970 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2971 if (cmp_left == mux_true && cmp_right == mux_false) {
2972 /* Mux(a >= b, a, b) => MAX */
2973 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2974 match_commutative | match_am | match_two_users);
2975 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2976 /* Mux(a >= b, b, a) => MIN */
2977 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2978 match_commutative | match_am | match_two_users);
2982 panic("cannot transform floating point Mux");
2988 assert(ia32_mode_needs_gp_reg(mode));
2990 if (is_Proj(cond)) {
2991 ir_node *cmp = get_Proj_pred(cond);
2993 ir_node *cmp_left = get_Cmp_left(cmp);
2994 ir_node *cmp_right = get_Cmp_right(cmp);
2995 pn_Cmp pnc = get_Proj_proj(cond);
2997 /* check for unsigned Doz first */
2998 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2999 is_Const_0(mux_false) && is_Sub(mux_true) &&
3000 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3001 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3002 return create_Doz(node, cmp_left, cmp_right);
3003 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3004 is_Const_0(mux_true) && is_Sub(mux_false) &&
3005 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3006 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3007 return create_Doz(node, cmp_left, cmp_right);
3012 flags = get_flags_node(cond, &pnc);
3014 if (is_Const(mux_true) && is_Const(mux_false)) {
3015 /* both are const, good */
3016 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3017 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3018 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3019 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3021 /* Not that simple. */
3026 new_node = create_CMov(node, cond, flags, pnc);
3034 * Create a conversion from x87 state register to general purpose.
3036 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3038 ir_node *block = be_transform_node(get_nodes_block(node));
3039 ir_node *op = get_Conv_op(node);
3040 ir_node *new_op = be_transform_node(op);
3041 ia32_code_gen_t *cg = env_cg;
3042 ir_graph *irg = current_ir_graph;
3043 dbg_info *dbgi = get_irn_dbg_info(node);
3044 ir_node *noreg = ia32_new_NoReg_gp(cg);
3045 ir_mode *mode = get_irn_mode(node);
3046 ir_node *fist, *load, *mem;
3048 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3049 set_irn_pinned(fist, op_pin_state_floats);
3050 set_ia32_use_frame(fist);
3051 set_ia32_op_type(fist, ia32_AddrModeD);
3053 assert(get_mode_size_bits(mode) <= 32);
3054 /* exception we can only store signed 32 bit integers, so for unsigned
3055 we store a 64bit (signed) integer and load the lower bits */
3056 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3057 set_ia32_ls_mode(fist, mode_Ls);
3059 set_ia32_ls_mode(fist, mode_Is);
3061 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3064 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3066 set_irn_pinned(load, op_pin_state_floats);
3067 set_ia32_use_frame(load);
3068 set_ia32_op_type(load, ia32_AddrModeS);
3069 set_ia32_ls_mode(load, mode_Is);
3070 if (get_ia32_ls_mode(fist) == mode_Ls) {
3071 ia32_attr_t *attr = get_ia32_attr(load);
3072 attr->data.need_64bit_stackent = 1;
3074 ia32_attr_t *attr = get_ia32_attr(load);
3075 attr->data.need_32bit_stackent = 1;
3077 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3079 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3083 * Creates a x87 strict Conv by placing a Store and a Load
3085 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3087 ir_node *block = get_nodes_block(node);
3088 ir_graph *irg = current_ir_graph;
3089 dbg_info *dbgi = get_irn_dbg_info(node);
3090 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3091 ir_node *nomem = new_NoMem();
3092 ir_node *frame = get_irg_frame(irg);
3093 ir_node *store, *load;
3096 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3098 set_ia32_use_frame(store);
3099 set_ia32_op_type(store, ia32_AddrModeD);
3100 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3102 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3104 set_ia32_use_frame(load);
3105 set_ia32_op_type(load, ia32_AddrModeS);
3106 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3108 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3113 * Create a conversion from general purpose to x87 register
3115 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3117 ir_node *src_block = get_nodes_block(node);
3118 ir_node *block = be_transform_node(src_block);
3119 ir_graph *irg = current_ir_graph;
3120 dbg_info *dbgi = get_irn_dbg_info(node);
3121 ir_node *op = get_Conv_op(node);
3122 ir_node *new_op = NULL;
3126 ir_mode *store_mode;
3132 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3133 if (src_mode == mode_Is || src_mode == mode_Hs) {
3134 ia32_address_mode_t am;
3136 match_arguments(&am, src_block, NULL, op, NULL,
3137 match_am | match_try_am | match_16bit | match_16bit_am);
3138 if (am.op_type == ia32_AddrModeS) {
3139 ia32_address_t *addr = &am.addr;
3141 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3142 addr->index, addr->mem);
3143 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3146 set_am_attributes(fild, &am);
3147 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3149 fix_mem_proj(fild, &am);
3154 if (new_op == NULL) {
3155 new_op = be_transform_node(op);
3158 noreg = ia32_new_NoReg_gp(env_cg);
3159 nomem = new_NoMem();
3160 mode = get_irn_mode(op);
3162 /* first convert to 32 bit signed if necessary */
3163 src_bits = get_mode_size_bits(src_mode);
3164 if (src_bits == 8) {
3165 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3167 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3169 } else if (src_bits < 32) {
3170 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3172 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3176 assert(get_mode_size_bits(mode) == 32);
3179 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3182 set_ia32_use_frame(store);
3183 set_ia32_op_type(store, ia32_AddrModeD);
3184 set_ia32_ls_mode(store, mode_Iu);
3186 /* exception for 32bit unsigned, do a 64bit spill+load */
3187 if (!mode_is_signed(mode)) {
3190 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3192 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3193 get_irg_frame(irg), noreg, nomem,
3196 set_ia32_use_frame(zero_store);
3197 set_ia32_op_type(zero_store, ia32_AddrModeD);
3198 add_ia32_am_offs_int(zero_store, 4);
3199 set_ia32_ls_mode(zero_store, mode_Iu);
3204 store = new_rd_Sync(dbgi, irg, block, 2, in);
3205 store_mode = mode_Ls;
3207 store_mode = mode_Is;
3211 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3213 set_ia32_use_frame(fild);
3214 set_ia32_op_type(fild, ia32_AddrModeS);
3215 set_ia32_ls_mode(fild, store_mode);
3217 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3223 * Create a conversion from one integer mode into another one
3225 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3226 dbg_info *dbgi, ir_node *block, ir_node *op,
3229 ir_graph *irg = current_ir_graph;
3230 int src_bits = get_mode_size_bits(src_mode);
3231 int tgt_bits = get_mode_size_bits(tgt_mode);
3232 ir_node *new_block = be_transform_node(block);
3234 ir_mode *smaller_mode;
3236 ia32_address_mode_t am;
3237 ia32_address_t *addr = &am.addr;
3240 if (src_bits < tgt_bits) {
3241 smaller_mode = src_mode;
3242 smaller_bits = src_bits;
3244 smaller_mode = tgt_mode;
3245 smaller_bits = tgt_bits;
3248 #ifdef DEBUG_libfirm
3250 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3255 match_arguments(&am, block, NULL, op, NULL,
3256 match_8bit | match_16bit |
3257 match_am | match_8bit_am | match_16bit_am);
3259 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3260 /* unnecessary conv. in theory it shouldn't have been AM */
3261 assert(is_ia32_NoReg_GP(addr->base));
3262 assert(is_ia32_NoReg_GP(addr->index));
3263 assert(is_NoMem(addr->mem));
3264 assert(am.addr.offset == 0);
3265 assert(am.addr.symconst_ent == NULL);
3269 if (smaller_bits == 8) {
3270 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3271 addr->index, addr->mem, am.new_op2,
3274 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3275 addr->index, addr->mem, am.new_op2,
3278 set_am_attributes(new_node, &am);
3279 /* match_arguments assume that out-mode = in-mode, this isn't true here
3281 set_ia32_ls_mode(new_node, smaller_mode);
3282 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3283 new_node = fix_mem_proj(new_node, &am);
3288 * Transforms a Conv node.
3290 * @return The created ia32 Conv node
3292 static ir_node *gen_Conv(ir_node *node)
3294 ir_node *block = get_nodes_block(node);
3295 ir_node *new_block = be_transform_node(block);
3296 ir_node *op = get_Conv_op(node);
3297 ir_node *new_op = NULL;
3298 ir_graph *irg = current_ir_graph;
3299 dbg_info *dbgi = get_irn_dbg_info(node);
3300 ir_mode *src_mode = get_irn_mode(op);
3301 ir_mode *tgt_mode = get_irn_mode(node);
3302 int src_bits = get_mode_size_bits(src_mode);
3303 int tgt_bits = get_mode_size_bits(tgt_mode);
3304 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3305 ir_node *nomem = new_rd_NoMem(irg);
3306 ir_node *res = NULL;
3308 if (src_mode == mode_b) {
3309 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3310 /* nothing to do, we already model bools as 0/1 ints */
3311 return be_transform_node(op);
3314 if (src_mode == tgt_mode) {
3315 if (get_Conv_strict(node)) {
3316 if (ia32_cg_config.use_sse2) {
3317 /* when we are in SSE mode, we can kill all strict no-op conversion */
3318 return be_transform_node(op);
3321 /* this should be optimized already, but who knows... */
3322 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3323 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3324 return be_transform_node(op);
3328 if (mode_is_float(src_mode)) {
3329 new_op = be_transform_node(op);
3330 /* we convert from float ... */
3331 if (mode_is_float(tgt_mode)) {
3332 if (src_mode == mode_E && tgt_mode == mode_D
3333 && !get_Conv_strict(node)) {
3334 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3339 if (ia32_cg_config.use_sse2) {
3340 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3341 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3343 set_ia32_ls_mode(res, tgt_mode);
3345 if (get_Conv_strict(node)) {
3346 res = gen_x87_strict_conv(tgt_mode, new_op);
3347 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3350 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3355 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3356 if (ia32_cg_config.use_sse2) {
3357 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3359 set_ia32_ls_mode(res, src_mode);
3361 return gen_x87_fp_to_gp(node);
3365 /* we convert from int ... */
3366 if (mode_is_float(tgt_mode)) {
3368 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3369 if (ia32_cg_config.use_sse2) {
3370 new_op = be_transform_node(op);
3371 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3373 set_ia32_ls_mode(res, tgt_mode);
3375 res = gen_x87_gp_to_fp(node, src_mode);
3376 if (get_Conv_strict(node)) {
3377 /* The strict-Conv is only necessary, if the int mode has more bits
3378 * than the float mantissa */
3379 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3380 size_t float_mantissa;
3381 /* FIXME There is no way to get the mantissa size of a mode */
3382 switch (get_mode_size_bits(tgt_mode)) {
3383 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3384 case 64: float_mantissa = 52 + 1; break;
3386 case 96: float_mantissa = 64; break;
3387 default: float_mantissa = 0; break;
3389 if (float_mantissa < int_mantissa) {
3390 res = gen_x87_strict_conv(tgt_mode, res);
3391 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3396 } else if (tgt_mode == mode_b) {
3397 /* mode_b lowering already took care that we only have 0/1 values */
3398 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3399 src_mode, tgt_mode));
3400 return be_transform_node(op);
3403 if (src_bits == tgt_bits) {
3404 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3405 src_mode, tgt_mode));
3406 return be_transform_node(op);
3409 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3417 static ir_node *create_immediate_or_transform(ir_node *node,
3418 char immediate_constraint_type)
3420 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3421 if (new_node == NULL) {
3422 new_node = be_transform_node(node);
3428 * Transforms a FrameAddr into an ia32 Add.
3430 static ir_node *gen_be_FrameAddr(ir_node *node)
3432 ir_node *block = be_transform_node(get_nodes_block(node));
3433 ir_node *op = be_get_FrameAddr_frame(node);
3434 ir_node *new_op = be_transform_node(op);
3435 ir_graph *irg = current_ir_graph;
3436 dbg_info *dbgi = get_irn_dbg_info(node);
3437 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3440 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3441 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3442 set_ia32_use_frame(new_node);
3444 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3450 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3452 static ir_node *gen_be_Return(ir_node *node)
3454 ir_graph *irg = current_ir_graph;
3455 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3456 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3457 ir_entity *ent = get_irg_entity(irg);
3458 ir_type *tp = get_entity_type(ent);
3463 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3464 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3467 int pn_ret_val, pn_ret_mem, arity, i;
3469 assert(ret_val != NULL);
3470 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3471 return be_duplicate_node(node);
3474 res_type = get_method_res_type(tp, 0);
3476 if (! is_Primitive_type(res_type)) {
3477 return be_duplicate_node(node);
3480 mode = get_type_mode(res_type);
3481 if (! mode_is_float(mode)) {
3482 return be_duplicate_node(node);
3485 assert(get_method_n_ress(tp) == 1);
3487 pn_ret_val = get_Proj_proj(ret_val);
3488 pn_ret_mem = get_Proj_proj(ret_mem);
3490 /* get the Barrier */
3491 barrier = get_Proj_pred(ret_val);
3493 /* get result input of the Barrier */
3494 ret_val = get_irn_n(barrier, pn_ret_val);
3495 new_ret_val = be_transform_node(ret_val);
3497 /* get memory input of the Barrier */
3498 ret_mem = get_irn_n(barrier, pn_ret_mem);
3499 new_ret_mem = be_transform_node(ret_mem);
3501 frame = get_irg_frame(irg);
3503 dbgi = get_irn_dbg_info(barrier);
3504 block = be_transform_node(get_nodes_block(barrier));
3506 noreg = ia32_new_NoReg_gp(env_cg);
3508 /* store xmm0 onto stack */
3509 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3510 new_ret_mem, new_ret_val);
3511 set_ia32_ls_mode(sse_store, mode);
3512 set_ia32_op_type(sse_store, ia32_AddrModeD);
3513 set_ia32_use_frame(sse_store);
3515 /* load into x87 register */
3516 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3517 set_ia32_op_type(fld, ia32_AddrModeS);
3518 set_ia32_use_frame(fld);
3520 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3521 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3523 /* create a new barrier */
3524 arity = get_irn_arity(barrier);
3525 in = alloca(arity * sizeof(in[0]));
3526 for (i = 0; i < arity; ++i) {
3529 if (i == pn_ret_val) {
3531 } else if (i == pn_ret_mem) {
3534 ir_node *in = get_irn_n(barrier, i);
3535 new_in = be_transform_node(in);
3540 new_barrier = new_ir_node(dbgi, irg, block,
3541 get_irn_op(barrier), get_irn_mode(barrier),
3543 copy_node_attr(barrier, new_barrier);
3544 be_duplicate_deps(barrier, new_barrier);
3545 be_set_transformed_node(barrier, new_barrier);
3547 /* transform normally */
3548 return be_duplicate_node(node);
3552 * Transform a be_AddSP into an ia32_SubSP.
3554 static ir_node *gen_be_AddSP(ir_node *node)
3556 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3557 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3559 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3560 match_am | match_immediate);
3564 * Transform a be_SubSP into an ia32_AddSP
3566 static ir_node *gen_be_SubSP(ir_node *node)
3568 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3569 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3571 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3572 match_am | match_immediate);
3576 * Change some phi modes
3578 static ir_node *gen_Phi(ir_node *node)
3580 ir_node *block = be_transform_node(get_nodes_block(node));
3581 ir_graph *irg = current_ir_graph;
3582 dbg_info *dbgi = get_irn_dbg_info(node);
3583 ir_mode *mode = get_irn_mode(node);
3586 if (ia32_mode_needs_gp_reg(mode)) {
3587 /* we shouldn't have any 64bit stuff around anymore */
3588 assert(get_mode_size_bits(mode) <= 32);
3589 /* all integer operations are on 32bit registers now */
3591 } else if (mode_is_float(mode)) {
3592 if (ia32_cg_config.use_sse2) {
3599 /* phi nodes allow loops, so we use the old arguments for now
3600 * and fix this later */
3601 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3602 get_irn_in(node) + 1);
3603 copy_node_attr(node, phi);
3604 be_duplicate_deps(node, phi);
3606 be_enqueue_preds(node);
3614 static ir_node *gen_IJmp(ir_node *node)
3616 ir_node *block = get_nodes_block(node);
3617 ir_node *new_block = be_transform_node(block);
3618 dbg_info *dbgi = get_irn_dbg_info(node);
3619 ir_node *op = get_IJmp_target(node);
3621 ia32_address_mode_t am;
3622 ia32_address_t *addr = &am.addr;
3624 assert(get_irn_mode(op) == mode_P);
3626 match_arguments(&am, block, NULL, op, NULL,
3627 match_am | match_8bit_am | match_16bit_am |
3628 match_immediate | match_8bit | match_16bit);
3630 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3631 addr->base, addr->index, addr->mem,
3633 set_am_attributes(new_node, &am);
3634 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3636 new_node = fix_mem_proj(new_node, &am);
3642 * Transform a Bound node.
3644 static ir_node *gen_Bound(ir_node *node)
3647 ir_node *lower = get_Bound_lower(node);
3648 dbg_info *dbgi = get_irn_dbg_info(node);
3650 if (is_Const_0(lower)) {
3651 /* typical case for Java */
3652 ir_node *sub, *res, *flags, *block;
3653 ir_graph *irg = current_ir_graph;
3655 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3656 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3658 block = get_nodes_block(res);
3659 if (! is_Proj(res)) {
3661 set_irn_mode(sub, mode_T);
3662 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3664 sub = get_Proj_pred(res);
3666 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3667 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3668 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3670 panic("generic Bound not supported in ia32 Backend");
3676 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3678 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3679 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3681 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3682 match_immediate | match_mode_neutral);
3685 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3687 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3688 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3689 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3693 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3695 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3696 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3697 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3701 static ir_node *gen_ia32_l_Add(ir_node *node)
3703 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3704 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3705 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3706 match_commutative | match_am | match_immediate |
3707 match_mode_neutral);
3709 if (is_Proj(lowered)) {
3710 lowered = get_Proj_pred(lowered);
3712 assert(is_ia32_Add(lowered));
3713 set_irn_mode(lowered, mode_T);
3719 static ir_node *gen_ia32_l_Adc(ir_node *node)
3721 return gen_binop_flags(node, new_rd_ia32_Adc,
3722 match_commutative | match_am | match_immediate |
3723 match_mode_neutral);
3727 * Transforms a l_MulS into a "real" MulS node.
3729 * @return the created ia32 Mul node
3731 static ir_node *gen_ia32_l_Mul(ir_node *node)
3733 ir_node *left = get_binop_left(node);
3734 ir_node *right = get_binop_right(node);
3736 return gen_binop(node, left, right, new_rd_ia32_Mul,
3737 match_commutative | match_am | match_mode_neutral);
3741 * Transforms a l_IMulS into a "real" IMul1OPS node.
3743 * @return the created ia32 IMul1OP node
3745 static ir_node *gen_ia32_l_IMul(ir_node *node)
3747 ir_node *left = get_binop_left(node);
3748 ir_node *right = get_binop_right(node);
3750 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3751 match_commutative | match_am | match_mode_neutral);
3754 static ir_node *gen_ia32_l_Sub(ir_node *node)
3756 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3757 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3758 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3759 match_am | match_immediate | match_mode_neutral);
3761 if (is_Proj(lowered)) {
3762 lowered = get_Proj_pred(lowered);
3764 assert(is_ia32_Sub(lowered));
3765 set_irn_mode(lowered, mode_T);
3771 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3773 return gen_binop_flags(node, new_rd_ia32_Sbb,
3774 match_am | match_immediate | match_mode_neutral);
3778 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3779 * op1 - target to be shifted
3780 * op2 - contains bits to be shifted into target
3782 * Only op3 can be an immediate.
3784 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3785 ir_node *low, ir_node *count)
3787 ir_node *block = get_nodes_block(node);
3788 ir_node *new_block = be_transform_node(block);
3789 ir_graph *irg = current_ir_graph;
3790 dbg_info *dbgi = get_irn_dbg_info(node);
3791 ir_node *new_high = be_transform_node(high);
3792 ir_node *new_low = be_transform_node(low);
3796 /* the shift amount can be any mode that is bigger than 5 bits, since all
3797 * other bits are ignored anyway */
3798 while (is_Conv(count) &&
3799 get_irn_n_edges(count) == 1 &&
3800 mode_is_int(get_irn_mode(count))) {
3801 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3802 count = get_Conv_op(count);
3804 new_count = create_immediate_or_transform(count, 0);
3806 if (is_ia32_l_ShlD(node)) {
3807 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3810 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3813 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3818 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3820 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3821 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3822 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3823 return gen_lowered_64bit_shifts(node, high, low, count);
3826 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3828 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3829 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3830 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3831 return gen_lowered_64bit_shifts(node, high, low, count);
3834 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3836 ir_node *src_block = get_nodes_block(node);
3837 ir_node *block = be_transform_node(src_block);
3838 ir_graph *irg = current_ir_graph;
3839 dbg_info *dbgi = get_irn_dbg_info(node);
3840 ir_node *frame = get_irg_frame(irg);
3841 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3842 ir_node *nomem = new_NoMem();
3843 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3844 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3845 ir_node *new_val_low = be_transform_node(val_low);
3846 ir_node *new_val_high = be_transform_node(val_high);
3851 ir_node *store_high;
3853 if (!mode_is_signed(get_irn_mode(val_high))) {
3854 panic("unsigned long long -> float not supported yet (%+F)", node);
3858 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3860 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3862 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3863 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3865 set_ia32_use_frame(store_low);
3866 set_ia32_use_frame(store_high);
3867 set_ia32_op_type(store_low, ia32_AddrModeD);
3868 set_ia32_op_type(store_high, ia32_AddrModeD);
3869 set_ia32_ls_mode(store_low, mode_Iu);
3870 set_ia32_ls_mode(store_high, mode_Is);
3871 add_ia32_am_offs_int(store_high, 4);
3875 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3878 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3880 set_ia32_use_frame(fild);
3881 set_ia32_op_type(fild, ia32_AddrModeS);
3882 set_ia32_ls_mode(fild, mode_Ls);
3884 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3886 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3889 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3891 ir_node *src_block = get_nodes_block(node);
3892 ir_node *block = be_transform_node(src_block);
3893 ir_graph *irg = current_ir_graph;
3894 dbg_info *dbgi = get_irn_dbg_info(node);
3895 ir_node *frame = get_irg_frame(irg);
3896 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3897 ir_node *nomem = new_NoMem();
3898 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3899 ir_node *new_val = be_transform_node(val);
3900 ir_node *fist, *mem;
3902 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3903 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3904 set_ia32_use_frame(fist);
3905 set_ia32_op_type(fist, ia32_AddrModeD);
3906 set_ia32_ls_mode(fist, mode_Ls);
3912 * the BAD transformer.
3914 static ir_node *bad_transform(ir_node *node)
3916 panic("No transform function for %+F available.", node);
3920 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3922 ir_graph *irg = current_ir_graph;
3923 ir_node *block = be_transform_node(get_nodes_block(node));
3924 ir_node *pred = get_Proj_pred(node);
3925 ir_node *new_pred = be_transform_node(pred);
3926 ir_node *frame = get_irg_frame(irg);
3927 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3928 dbg_info *dbgi = get_irn_dbg_info(node);
3929 long pn = get_Proj_proj(node);
3934 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3935 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3936 set_ia32_use_frame(load);
3937 set_ia32_op_type(load, ia32_AddrModeS);
3938 set_ia32_ls_mode(load, mode_Iu);
3939 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3940 * 32 bit from it with this particular load */
3941 attr = get_ia32_attr(load);
3942 attr->data.need_64bit_stackent = 1;
3944 if (pn == pn_ia32_l_FloattoLL_res_high) {
3945 add_ia32_am_offs_int(load, 4);
3947 assert(pn == pn_ia32_l_FloattoLL_res_low);
3950 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3956 * Transform the Projs of an AddSP.
3958 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3960 ir_node *block = be_transform_node(get_nodes_block(node));
3961 ir_node *pred = get_Proj_pred(node);
3962 ir_node *new_pred = be_transform_node(pred);
3963 ir_graph *irg = current_ir_graph;
3964 dbg_info *dbgi = get_irn_dbg_info(node);
3965 long proj = get_Proj_proj(node);
3967 if (proj == pn_be_AddSP_sp) {
3968 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3969 pn_ia32_SubSP_stack);
3970 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3972 } else if (proj == pn_be_AddSP_res) {
3973 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3974 pn_ia32_SubSP_addr);
3975 } else if (proj == pn_be_AddSP_M) {
3976 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3979 panic("No idea how to transform proj->AddSP");
3983 * Transform the Projs of a SubSP.
3985 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3987 ir_node *block = be_transform_node(get_nodes_block(node));
3988 ir_node *pred = get_Proj_pred(node);
3989 ir_node *new_pred = be_transform_node(pred);
3990 ir_graph *irg = current_ir_graph;
3991 dbg_info *dbgi = get_irn_dbg_info(node);
3992 long proj = get_Proj_proj(node);
3994 if (proj == pn_be_SubSP_sp) {
3995 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3996 pn_ia32_AddSP_stack);
3997 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3999 } else if (proj == pn_be_SubSP_M) {
4000 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4003 panic("No idea how to transform proj->SubSP");
4007 * Transform and renumber the Projs from a Load.
4009 static ir_node *gen_Proj_Load(ir_node *node)
4012 ir_node *block = be_transform_node(get_nodes_block(node));
4013 ir_node *pred = get_Proj_pred(node);
4014 ir_graph *irg = current_ir_graph;
4015 dbg_info *dbgi = get_irn_dbg_info(node);
4016 long proj = get_Proj_proj(node);
4018 /* loads might be part of source address mode matches, so we don't
4019 * transform the ProjMs yet (with the exception of loads whose result is
4022 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4025 /* this is needed, because sometimes we have loops that are only
4026 reachable through the ProjM */
4027 be_enqueue_preds(node);
4028 /* do it in 2 steps, to silence firm verifier */
4029 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4030 set_Proj_proj(res, pn_ia32_mem);
4034 /* renumber the proj */
4035 new_pred = be_transform_node(pred);
4036 if (is_ia32_Load(new_pred)) {
4039 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4041 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4042 case pn_Load_X_regular:
4043 return new_rd_Jmp(dbgi, irg, block);
4044 case pn_Load_X_except:
4045 /* This Load might raise an exception. Mark it. */
4046 set_ia32_exc_label(new_pred, 1);
4047 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4051 } else if (is_ia32_Conv_I2I(new_pred) ||
4052 is_ia32_Conv_I2I8Bit(new_pred)) {
4053 set_irn_mode(new_pred, mode_T);
4054 if (proj == pn_Load_res) {
4055 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4056 } else if (proj == pn_Load_M) {
4057 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4059 } else if (is_ia32_xLoad(new_pred)) {
4062 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4064 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4065 case pn_Load_X_regular:
4066 return new_rd_Jmp(dbgi, irg, block);
4067 case pn_Load_X_except:
4068 /* This Load might raise an exception. Mark it. */
4069 set_ia32_exc_label(new_pred, 1);
4070 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4074 } else if (is_ia32_vfld(new_pred)) {
4077 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4079 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4080 case pn_Load_X_regular:
4081 return new_rd_Jmp(dbgi, irg, block);
4082 case pn_Load_X_except:
4083 /* This Load might raise an exception. Mark it. */
4084 set_ia32_exc_label(new_pred, 1);
4085 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4090 /* can happen for ProJMs when source address mode happened for the
4093 /* however it should not be the result proj, as that would mean the
4094 load had multiple users and should not have been used for
4096 if (proj != pn_Load_M) {
4097 panic("internal error: transformed node not a Load");
4099 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4102 panic("No idea how to transform proj");
4106 * Transform and renumber the Projs from a DivMod like instruction.
4108 static ir_node *gen_Proj_DivMod(ir_node *node)
4110 ir_node *block = be_transform_node(get_nodes_block(node));
4111 ir_node *pred = get_Proj_pred(node);
4112 ir_node *new_pred = be_transform_node(pred);
4113 ir_graph *irg = current_ir_graph;
4114 dbg_info *dbgi = get_irn_dbg_info(node);
4115 long proj = get_Proj_proj(node);
4117 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4119 switch (get_irn_opcode(pred)) {
4123 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4125 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4126 case pn_Div_X_regular:
4127 return new_rd_Jmp(dbgi, irg, block);
4128 case pn_Div_X_except:
4129 set_ia32_exc_label(new_pred, 1);
4130 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4138 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4140 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4141 case pn_Mod_X_except:
4142 set_ia32_exc_label(new_pred, 1);
4143 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4151 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4152 case pn_DivMod_res_div:
4153 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4154 case pn_DivMod_res_mod:
4155 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4156 case pn_DivMod_X_regular:
4157 return new_rd_Jmp(dbgi, irg, block);
4158 case pn_DivMod_X_except:
4159 set_ia32_exc_label(new_pred, 1);
4160 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4169 panic("No idea how to transform proj->DivMod");
4173 * Transform and renumber the Projs from a CopyB.
4175 static ir_node *gen_Proj_CopyB(ir_node *node)
4177 ir_node *block = be_transform_node(get_nodes_block(node));
4178 ir_node *pred = get_Proj_pred(node);
4179 ir_node *new_pred = be_transform_node(pred);
4180 ir_graph *irg = current_ir_graph;
4181 dbg_info *dbgi = get_irn_dbg_info(node);
4182 long proj = get_Proj_proj(node);
4185 case pn_CopyB_M_regular:
4186 if (is_ia32_CopyB_i(new_pred)) {
4187 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4188 } else if (is_ia32_CopyB(new_pred)) {
4189 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4196 panic("No idea how to transform proj->CopyB");
4200 * Transform and renumber the Projs from a Quot.
4202 static ir_node *gen_Proj_Quot(ir_node *node)
4204 ir_node *block = be_transform_node(get_nodes_block(node));
4205 ir_node *pred = get_Proj_pred(node);
4206 ir_node *new_pred = be_transform_node(pred);
4207 ir_graph *irg = current_ir_graph;
4208 dbg_info *dbgi = get_irn_dbg_info(node);
4209 long proj = get_Proj_proj(node);
4213 if (is_ia32_xDiv(new_pred)) {
4214 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4215 } else if (is_ia32_vfdiv(new_pred)) {
4216 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4220 if (is_ia32_xDiv(new_pred)) {
4221 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4222 } else if (is_ia32_vfdiv(new_pred)) {
4223 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4226 case pn_Quot_X_regular:
4227 case pn_Quot_X_except:
4232 panic("No idea how to transform proj->Quot");
4235 static ir_node *gen_be_Call(ir_node *node)
4237 dbg_info *const dbgi = get_irn_dbg_info(node);
4238 ir_graph *const irg = current_ir_graph;
4239 ir_node *const src_block = get_nodes_block(node);
4240 ir_node *const block = be_transform_node(src_block);
4241 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4242 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4243 ir_node *const sp = be_transform_node(src_sp);
4244 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4245 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4246 ia32_address_mode_t am;
4247 ia32_address_t *const addr = &am.addr;
4252 ir_node * eax = noreg;
4253 ir_node * ecx = noreg;
4254 ir_node * edx = noreg;
4255 unsigned const pop = be_Call_get_pop(node);
4256 ir_type *const call_tp = be_Call_get_type(node);
4258 /* Run the x87 simulator if the call returns a float value */
4259 if (get_method_n_ress(call_tp) > 0) {
4260 ir_type *const res_type = get_method_res_type(call_tp, 0);
4261 ir_mode *const res_mode = get_type_mode(res_type);
4263 if (res_mode != NULL && mode_is_float(res_mode)) {
4264 env_cg->do_x87_sim = 1;
4268 /* We do not want be_Call direct calls */
4269 assert(be_Call_get_entity(node) == NULL);
4271 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4272 match_am | match_immediate);
4274 i = get_irn_arity(node) - 1;
4275 fpcw = be_transform_node(get_irn_n(node, i--));
4276 for (; i >= be_pos_Call_first_arg; --i) {
4277 arch_register_req_t const *const req = arch_get_register_req(node, i);
4278 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4280 assert(req->type == arch_register_req_type_limited);
4281 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4283 switch (*req->limited) {
4284 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4285 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4286 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4287 default: panic("Invalid GP register for register parameter");
4291 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4292 call = new_rd_ia32_Call(dbgi, irg, block, addr->base, addr->index, mem,
4293 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4294 set_am_attributes(call, &am);
4295 call = fix_mem_proj(call, &am);
4297 if (get_irn_pinned(node) == op_pin_state_pinned)
4298 set_irn_pinned(call, op_pin_state_pinned);
4300 SET_IA32_ORIG_NODE(call, ia32_get_old_node_name(env_cg, node));
4304 static ir_node *gen_be_IncSP(ir_node *node)
4306 ir_node *res = be_duplicate_node(node);
4307 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4313 * Transform the Projs from a be_Call.
4315 static ir_node *gen_Proj_be_Call(ir_node *node)
4317 ir_node *block = be_transform_node(get_nodes_block(node));
4318 ir_node *call = get_Proj_pred(node);
4319 ir_node *new_call = be_transform_node(call);
4320 ir_graph *irg = current_ir_graph;
4321 dbg_info *dbgi = get_irn_dbg_info(node);
4322 ir_type *method_type = be_Call_get_type(call);
4323 int n_res = get_method_n_ress(method_type);
4324 long proj = get_Proj_proj(node);
4325 ir_mode *mode = get_irn_mode(node);
4327 const arch_register_class_t *cls;
4330 /* The following is kinda tricky: If we're using SSE, then we have to
4331 * move the result value of the call in floating point registers to an
4332 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4333 * after the call, we have to make sure to correctly make the
4334 * MemProj and the result Proj use these 2 nodes
4336 if (proj == pn_be_Call_M_regular) {
4337 // get new node for result, are we doing the sse load/store hack?
4338 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4339 ir_node *call_res_new;
4340 ir_node *call_res_pred = NULL;
4342 if (call_res != NULL) {
4343 call_res_new = be_transform_node(call_res);
4344 call_res_pred = get_Proj_pred(call_res_new);
4347 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4348 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4351 assert(is_ia32_xLoad(call_res_pred));
4352 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4356 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4357 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4359 ir_node *frame = get_irg_frame(irg);
4360 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4362 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4365 /* in case there is no memory output: create one to serialize the copy
4367 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4368 pn_be_Call_M_regular);
4369 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4370 pn_be_Call_first_res);
4372 /* store st(0) onto stack */
4373 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4375 set_ia32_op_type(fstp, ia32_AddrModeD);
4376 set_ia32_use_frame(fstp);
4378 /* load into SSE register */
4379 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4381 set_ia32_op_type(sse_load, ia32_AddrModeS);
4382 set_ia32_use_frame(sse_load);
4384 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4390 /* transform call modes */
4391 if (mode_is_data(mode)) {
4392 cls = arch_get_irn_reg_class(node, -1);
4396 /* Map from be_Call to ia32_Call proj number */
4397 if (proj == pn_be_Call_sp) {
4398 proj = pn_ia32_Call_stack;
4399 } else if (proj == pn_be_Call_M_regular) {
4400 proj = pn_ia32_Call_M;
4402 arch_register_req_t const *const req = arch_get_register_req(node, BE_OUT_POS(proj));
4403 int const n_outs = get_ia32_n_res(new_call);
4406 assert(proj >= pn_be_Call_first_res);
4407 assert(req->type == arch_register_req_type_limited);
4409 for (i = 0; i < n_outs; ++i) {
4410 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4412 if (new_req->type != arch_register_req_type_limited ||
4413 new_req->cls != req->cls ||
4414 *new_req->limited != *req->limited)
4423 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4425 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4427 case pn_ia32_Call_stack:
4428 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4431 case pn_ia32_Call_fpcw:
4432 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4440 * Transform the Projs from a Cmp.
4442 static ir_node *gen_Proj_Cmp(ir_node *node)
4444 /* this probably means not all mode_b nodes were lowered... */
4445 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4450 * Transform the Projs from a Bound.
4452 static ir_node *gen_Proj_Bound(ir_node *node)
4454 ir_node *new_node, *block;
4455 ir_node *pred = get_Proj_pred(node);
4457 switch (get_Proj_proj(node)) {
4459 return be_transform_node(get_Bound_mem(pred));
4460 case pn_Bound_X_regular:
4461 new_node = be_transform_node(pred);
4462 block = get_nodes_block(new_node);
4463 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4464 case pn_Bound_X_except:
4465 new_node = be_transform_node(pred);
4466 block = get_nodes_block(new_node);
4467 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4469 return be_transform_node(get_Bound_index(pred));
4471 panic("unsupported Proj from Bound");
4475 static ir_node *gen_Proj_ASM(ir_node *node)
4481 if (get_irn_mode(node) != mode_M)
4482 return be_duplicate_node(node);
4484 pred = get_Proj_pred(node);
4485 new_pred = be_transform_node(pred);
4486 block = get_nodes_block(new_pred);
4487 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4488 get_ia32_n_res(new_pred) + 1);
4492 * Transform and potentially renumber Proj nodes.
4494 static ir_node *gen_Proj(ir_node *node)
4496 ir_node *pred = get_Proj_pred(node);
4499 switch (get_irn_opcode(pred)) {
4501 proj = get_Proj_proj(node);
4502 if (proj == pn_Store_M) {
4503 return be_transform_node(pred);
4505 panic("No idea how to transform proj->Store");
4508 return gen_Proj_Load(node);
4510 return gen_Proj_ASM(node);
4514 return gen_Proj_DivMod(node);
4516 return gen_Proj_CopyB(node);
4518 return gen_Proj_Quot(node);
4520 return gen_Proj_be_SubSP(node);
4522 return gen_Proj_be_AddSP(node);
4524 return gen_Proj_be_Call(node);
4526 return gen_Proj_Cmp(node);
4528 return gen_Proj_Bound(node);
4530 proj = get_Proj_proj(node);
4532 case pn_Start_X_initial_exec: {
4533 ir_node *block = get_nodes_block(pred);
4534 ir_node *new_block = be_transform_node(block);
4535 dbg_info *dbgi = get_irn_dbg_info(node);
4536 /* we exchange the ProjX with a jump */
4537 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4542 case pn_Start_P_tls:
4543 return gen_Proj_tls(node);
4548 if (is_ia32_l_FloattoLL(pred)) {
4549 return gen_Proj_l_FloattoLL(node);
4551 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4555 ir_mode *mode = get_irn_mode(node);
4556 if (ia32_mode_needs_gp_reg(mode)) {
4557 ir_node *new_pred = be_transform_node(pred);
4558 ir_node *block = be_transform_node(get_nodes_block(node));
4559 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4560 mode_Iu, get_Proj_proj(node));
4561 #ifdef DEBUG_libfirm
4562 new_proj->node_nr = node->node_nr;
4568 return be_duplicate_node(node);
4572 * Enters all transform functions into the generic pointer
4574 static void register_transformers(void)
4578 /* first clear the generic function pointer for all ops */
4579 clear_irp_opcodes_generic_func();
4581 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4582 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4620 /* transform ops from intrinsic lowering */
4632 GEN(ia32_l_LLtoFloat);
4633 GEN(ia32_l_FloattoLL);
4639 /* we should never see these nodes */
4654 /* handle generic backend nodes */
4663 op_Mulh = get_op_Mulh();
4672 * Pre-transform all unknown and noreg nodes.
4674 static void ia32_pretransform_node(void)
4676 ia32_code_gen_t *cg = env_cg;
4678 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4679 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4680 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4681 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4682 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4683 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4688 * Walker, checks if all ia32 nodes producing more than one result have their
4689 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4691 static void add_missing_keep_walker(ir_node *node, void *data)
4694 unsigned found_projs = 0;
4695 const ir_edge_t *edge;
4696 ir_mode *mode = get_irn_mode(node);
4701 if (!is_ia32_irn(node))
4704 n_outs = get_ia32_n_res(node);
4707 if (is_ia32_SwitchJmp(node))
4710 assert(n_outs < (int) sizeof(unsigned) * 8);
4711 foreach_out_edge(node, edge) {
4712 ir_node *proj = get_edge_src_irn(edge);
4715 /* The node could be kept */
4719 if (get_irn_mode(proj) == mode_M)
4722 pn = get_Proj_proj(proj);
4723 assert(pn < n_outs);
4724 found_projs |= 1 << pn;
4728 /* are keeps missing? */
4730 for (i = 0; i < n_outs; ++i) {
4733 const arch_register_req_t *req;
4734 const arch_register_class_t *cls;
4736 if (found_projs & (1 << i)) {
4740 req = get_ia32_out_req(node, i);
4745 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4749 block = get_nodes_block(node);
4750 in[0] = new_r_Proj(current_ir_graph, block, node,
4751 arch_register_class_mode(cls), i);
4752 if (last_keep != NULL) {
4753 be_Keep_add_node(last_keep, cls, in[0]);
4755 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4756 if (sched_is_scheduled(node)) {
4757 sched_add_after(node, last_keep);
4764 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4767 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4769 ir_graph *irg = be_get_birg_irg(cg->birg);
4770 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4773 /* do the transformation */
4774 void ia32_transform_graph(ia32_code_gen_t *cg)
4778 register_transformers();
4780 initial_fpcw = NULL;
4782 BE_TIMER_PUSH(t_heights);
4783 heights = heights_new(cg->irg);
4784 BE_TIMER_POP(t_heights);
4785 ia32_calculate_non_address_mode_nodes(cg->birg);
4787 /* the transform phase is not safe for CSE (yet) because several nodes get
4788 * attributes set after their creation */
4789 cse_last = get_opt_cse();
4792 be_transform_graph(cg->birg, ia32_pretransform_node);
4794 set_opt_cse(cse_last);
4796 ia32_free_non_address_mode_nodes();
4797 heights_free(heights);
4801 void ia32_init_transform(void)
4803 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");