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)) {
1945 if (prevents_AM(block, load, mem))
1947 /* Store should be attached to the load via mem */
1948 assert(heights_reachable_in_block(heights, mem, load));
1953 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1954 ir_node *mem, ir_node *ptr, ir_mode *mode,
1955 construct_binop_dest_func *func,
1956 construct_binop_dest_func *func8bit,
1957 match_flags_t flags)
1959 ir_node *src_block = get_nodes_block(node);
1961 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1962 ir_graph *irg = current_ir_graph;
1969 ia32_address_mode_t am;
1970 ia32_address_t *addr = &am.addr;
1971 memset(&am, 0, sizeof(am));
1973 assert(flags & match_dest_am);
1974 assert(flags & match_immediate); /* there is no destam node without... */
1975 commutative = (flags & match_commutative) != 0;
1977 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1978 build_address(&am, op1);
1979 new_op = create_immediate_or_transform(op2, 0);
1980 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1981 build_address(&am, op2);
1982 new_op = create_immediate_or_transform(op1, 0);
1987 if (addr->base == NULL)
1988 addr->base = noreg_gp;
1989 if (addr->index == NULL)
1990 addr->index = noreg_gp;
1991 if (addr->mem == NULL)
1992 addr->mem = new_NoMem();
1994 dbgi = get_irn_dbg_info(node);
1995 block = be_transform_node(src_block);
1996 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
1998 if (get_mode_size_bits(mode) == 8) {
1999 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2002 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem,
2005 set_address(new_node, addr);
2006 set_ia32_op_type(new_node, ia32_AddrModeD);
2007 set_ia32_ls_mode(new_node, mode);
2008 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2010 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2011 mem_proj = be_transform_node(am.mem_proj);
2012 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2017 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2018 ir_node *ptr, ir_mode *mode,
2019 construct_unop_dest_func *func)
2021 ir_graph *irg = current_ir_graph;
2022 ir_node *src_block = get_nodes_block(node);
2028 ia32_address_mode_t am;
2029 ia32_address_t *addr = &am.addr;
2031 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2034 memset(&am, 0, sizeof(am));
2035 build_address(&am, op);
2037 dbgi = get_irn_dbg_info(node);
2038 block = be_transform_node(src_block);
2039 new_mem = transform_AM_mem(irg, block, am.am_node, mem, addr->mem);
2040 new_node = func(dbgi, irg, block, addr->base, addr->index, new_mem);
2041 set_address(new_node, addr);
2042 set_ia32_op_type(new_node, ia32_AddrModeD);
2043 set_ia32_ls_mode(new_node, mode);
2044 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2046 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2047 mem_proj = be_transform_node(am.mem_proj);
2048 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2053 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2055 ir_mode *mode = get_irn_mode(node);
2056 ir_node *mux_true = get_Mux_true(node);
2057 ir_node *mux_false = get_Mux_false(node);
2068 ia32_address_t addr;
2070 if (get_mode_size_bits(mode) != 8)
2073 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2075 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2081 build_address_ptr(&addr, ptr, mem);
2083 irg = current_ir_graph;
2084 dbgi = get_irn_dbg_info(node);
2085 block = get_nodes_block(node);
2086 new_block = be_transform_node(block);
2087 cond = get_Mux_sel(node);
2088 flags = get_flags_node(cond, &pnc);
2089 new_mem = be_transform_node(mem);
2090 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2091 addr.index, addr.mem, flags, pnc, negated);
2092 set_address(new_node, &addr);
2093 set_ia32_op_type(new_node, ia32_AddrModeD);
2094 set_ia32_ls_mode(new_node, mode);
2095 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2100 static ir_node *try_create_dest_am(ir_node *node)
2102 ir_node *val = get_Store_value(node);
2103 ir_node *mem = get_Store_mem(node);
2104 ir_node *ptr = get_Store_ptr(node);
2105 ir_mode *mode = get_irn_mode(val);
2106 unsigned bits = get_mode_size_bits(mode);
2111 /* handle only GP modes for now... */
2112 if (!ia32_mode_needs_gp_reg(mode))
2116 /* store must be the only user of the val node */
2117 if (get_irn_n_edges(val) > 1)
2119 /* skip pointless convs */
2121 ir_node *conv_op = get_Conv_op(val);
2122 ir_mode *pred_mode = get_irn_mode(conv_op);
2123 if (!ia32_mode_needs_gp_reg(pred_mode))
2125 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2133 /* value must be in the same block */
2134 if (get_nodes_block(node) != get_nodes_block(val))
2137 switch (get_irn_opcode(val)) {
2139 op1 = get_Add_left(val);
2140 op2 = get_Add_right(val);
2141 if (ia32_cg_config.use_incdec) {
2142 if (is_Const_1(op2)) {
2143 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_IncMem);
2145 } else if (is_Const_Minus_1(op2)) {
2146 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_DecMem);
2150 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2151 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2152 match_dest_am | match_commutative |
2156 op1 = get_Sub_left(val);
2157 op2 = get_Sub_right(val);
2158 if (is_Const(op2)) {
2159 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2161 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2162 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2163 match_dest_am | match_immediate);
2166 op1 = get_And_left(val);
2167 op2 = get_And_right(val);
2168 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2169 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2170 match_dest_am | match_commutative |
2174 op1 = get_Or_left(val);
2175 op2 = get_Or_right(val);
2176 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2177 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2178 match_dest_am | match_commutative |
2182 op1 = get_Eor_left(val);
2183 op2 = get_Eor_right(val);
2184 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2185 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2186 match_dest_am | match_commutative |
2190 op1 = get_Shl_left(val);
2191 op2 = get_Shl_right(val);
2192 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2193 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2194 match_dest_am | match_immediate);
2197 op1 = get_Shr_left(val);
2198 op2 = get_Shr_right(val);
2199 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2200 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2201 match_dest_am | match_immediate);
2204 op1 = get_Shrs_left(val);
2205 op2 = get_Shrs_right(val);
2206 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2207 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2208 match_dest_am | match_immediate);
2211 op1 = get_Rotl_left(val);
2212 op2 = get_Rotl_right(val);
2213 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2214 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2215 match_dest_am | match_immediate);
2217 /* TODO: match ROR patterns... */
2219 new_node = try_create_SetMem(val, ptr, mem);
2222 op1 = get_Minus_op(val);
2223 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2226 /* should be lowered already */
2227 assert(mode != mode_b);
2228 op1 = get_Not_op(val);
2229 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2235 if (new_node != NULL) {
2236 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2237 get_irn_pinned(node) == op_pin_state_pinned) {
2238 set_irn_pinned(new_node, op_pin_state_pinned);
2245 static int is_float_to_int_conv(const ir_node *node)
2247 ir_mode *mode = get_irn_mode(node);
2251 if (mode != mode_Is && mode != mode_Hs)
2256 conv_op = get_Conv_op(node);
2257 conv_mode = get_irn_mode(conv_op);
2259 if (!mode_is_float(conv_mode))
2266 * Transform a Store(floatConst).
2268 * @return the created ia32 Store node
2270 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2272 ir_mode *mode = get_irn_mode(cns);
2273 unsigned size = get_mode_size_bytes(mode);
2274 tarval *tv = get_Const_tarval(cns);
2275 ir_node *block = get_nodes_block(node);
2276 ir_node *new_block = be_transform_node(block);
2277 ir_node *ptr = get_Store_ptr(node);
2278 ir_node *mem = get_Store_mem(node);
2279 ir_graph *irg = current_ir_graph;
2280 dbg_info *dbgi = get_irn_dbg_info(node);
2284 ia32_address_t addr;
2286 assert(size % 4 == 0);
2289 build_address_ptr(&addr, ptr, mem);
2293 get_tarval_sub_bits(tv, ofs) |
2294 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2295 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2296 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2297 ir_node *imm = create_Immediate(NULL, 0, val);
2299 ir_node *new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2300 addr.index, addr.mem, imm);
2302 set_irn_pinned(new_node, get_irn_pinned(node));
2303 set_ia32_op_type(new_node, ia32_AddrModeD);
2304 set_ia32_ls_mode(new_node, mode_Iu);
2305 set_address(new_node, &addr);
2306 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2308 ins[i++] = new_node;
2313 } while (size != 0);
2315 return i == 1 ? ins[0] : new_rd_Sync(dbgi, irg, new_block, i, ins);
2319 * Generate a vfist or vfisttp instruction.
2321 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2322 ir_node *mem, ir_node *val, ir_node **fist)
2326 if (ia32_cg_config.use_fisttp) {
2327 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2328 if other users exists */
2329 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2330 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2331 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2332 be_new_Keep(reg_class, irg, block, 1, &value);
2334 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2337 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2340 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2346 * Transforms a normal Store.
2348 * @return the created ia32 Store node
2350 static ir_node *gen_normal_Store(ir_node *node)
2352 ir_node *val = get_Store_value(node);
2353 ir_mode *mode = get_irn_mode(val);
2354 ir_node *block = get_nodes_block(node);
2355 ir_node *new_block = be_transform_node(block);
2356 ir_node *ptr = get_Store_ptr(node);
2357 ir_node *mem = get_Store_mem(node);
2358 ir_graph *irg = current_ir_graph;
2359 dbg_info *dbgi = get_irn_dbg_info(node);
2360 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2361 ir_node *new_val, *new_node, *store;
2362 ia32_address_t addr;
2364 /* check for destination address mode */
2365 new_node = try_create_dest_am(node);
2366 if (new_node != NULL)
2369 /* construct store address */
2370 memset(&addr, 0, sizeof(addr));
2371 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2373 if (addr.base == NULL) {
2376 addr.base = be_transform_node(addr.base);
2379 if (addr.index == NULL) {
2382 addr.index = be_transform_node(addr.index);
2384 addr.mem = be_transform_node(mem);
2386 if (mode_is_float(mode)) {
2387 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2389 while (is_Conv(val) && mode == get_irn_mode(val)) {
2390 ir_node *op = get_Conv_op(val);
2391 if (!mode_is_float(get_irn_mode(op)))
2395 new_val = be_transform_node(val);
2396 if (ia32_cg_config.use_sse2) {
2397 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2398 addr.index, addr.mem, new_val);
2400 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2401 addr.index, addr.mem, new_val, mode);
2404 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2405 val = get_Conv_op(val);
2407 /* TODO: is this optimisation still necessary at all (middleend)? */
2408 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2409 while (is_Conv(val)) {
2410 ir_node *op = get_Conv_op(val);
2411 if (!mode_is_float(get_irn_mode(op)))
2413 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2417 new_val = be_transform_node(val);
2418 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2420 new_val = create_immediate_or_transform(val, 0);
2421 assert(mode != mode_b);
2423 if (get_mode_size_bits(mode) == 8) {
2424 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2425 addr.index, addr.mem, new_val);
2427 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2428 addr.index, addr.mem, new_val);
2433 set_irn_pinned(store, get_irn_pinned(node));
2434 set_ia32_op_type(store, ia32_AddrModeD);
2435 set_ia32_ls_mode(store, mode);
2437 set_address(store, &addr);
2438 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2444 * Transforms a Store.
2446 * @return the created ia32 Store node
2448 static ir_node *gen_Store(ir_node *node)
2450 ir_node *val = get_Store_value(node);
2451 ir_mode *mode = get_irn_mode(val);
2453 if (mode_is_float(mode) && is_Const(val)) {
2456 /* we are storing a floating point constant */
2457 if (ia32_cg_config.use_sse2) {
2458 transform = !is_simple_sse_Const(val);
2460 transform = !is_simple_x87_Const(val);
2463 return gen_float_const_Store(node, val);
2465 return gen_normal_Store(node);
2469 * Transforms a Switch.
2471 * @return the created ia32 SwitchJmp node
2473 static ir_node *create_Switch(ir_node *node)
2475 ir_graph *irg = current_ir_graph;
2476 dbg_info *dbgi = get_irn_dbg_info(node);
2477 ir_node *block = be_transform_node(get_nodes_block(node));
2478 ir_node *sel = get_Cond_selector(node);
2479 ir_node *new_sel = be_transform_node(sel);
2480 int switch_min = INT_MAX;
2481 int switch_max = INT_MIN;
2482 long default_pn = get_Cond_defaultProj(node);
2484 const ir_edge_t *edge;
2486 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2488 /* determine the smallest switch case value */
2489 foreach_out_edge(node, edge) {
2490 ir_node *proj = get_edge_src_irn(edge);
2491 long pn = get_Proj_proj(proj);
2492 if (pn == default_pn)
2495 if (pn < switch_min)
2497 if (pn > switch_max)
2501 if ((unsigned) (switch_max - switch_min) > 256000) {
2502 panic("Size of switch %+F bigger than 256000", node);
2505 if (switch_min != 0) {
2506 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2508 /* if smallest switch case is not 0 we need an additional sub */
2509 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2510 add_ia32_am_offs_int(new_sel, -switch_min);
2511 set_ia32_op_type(new_sel, ia32_AddrModeS);
2513 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2516 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2517 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2523 * Transform a Cond node.
2525 static ir_node *gen_Cond(ir_node *node)
2527 ir_node *block = get_nodes_block(node);
2528 ir_node *new_block = be_transform_node(block);
2529 ir_graph *irg = current_ir_graph;
2530 dbg_info *dbgi = get_irn_dbg_info(node);
2531 ir_node *sel = get_Cond_selector(node);
2532 ir_mode *sel_mode = get_irn_mode(sel);
2533 ir_node *flags = NULL;
2537 if (sel_mode != mode_b) {
2538 return create_Switch(node);
2541 /* we get flags from a Cmp */
2542 flags = get_flags_node(sel, &pnc);
2544 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2545 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2550 static ir_node *gen_be_Copy(ir_node *node)
2552 ir_node *new_node = be_duplicate_node(node);
2553 ir_mode *mode = get_irn_mode(new_node);
2555 if (ia32_mode_needs_gp_reg(mode)) {
2556 set_irn_mode(new_node, mode_Iu);
2562 static ir_node *create_Fucom(ir_node *node)
2564 ir_graph *irg = current_ir_graph;
2565 dbg_info *dbgi = get_irn_dbg_info(node);
2566 ir_node *block = get_nodes_block(node);
2567 ir_node *new_block = be_transform_node(block);
2568 ir_node *left = get_Cmp_left(node);
2569 ir_node *new_left = be_transform_node(left);
2570 ir_node *right = get_Cmp_right(node);
2574 if (ia32_cg_config.use_fucomi) {
2575 new_right = be_transform_node(right);
2576 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2578 set_ia32_commutative(new_node);
2579 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2581 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2582 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2585 new_right = be_transform_node(right);
2586 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2590 set_ia32_commutative(new_node);
2592 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2594 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2595 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2601 static ir_node *create_Ucomi(ir_node *node)
2603 ir_graph *irg = current_ir_graph;
2604 dbg_info *dbgi = get_irn_dbg_info(node);
2605 ir_node *src_block = get_nodes_block(node);
2606 ir_node *new_block = be_transform_node(src_block);
2607 ir_node *left = get_Cmp_left(node);
2608 ir_node *right = get_Cmp_right(node);
2610 ia32_address_mode_t am;
2611 ia32_address_t *addr = &am.addr;
2613 match_arguments(&am, src_block, left, right, NULL,
2614 match_commutative | match_am);
2616 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2617 addr->mem, am.new_op1, am.new_op2,
2619 set_am_attributes(new_node, &am);
2621 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2623 new_node = fix_mem_proj(new_node, &am);
2629 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2630 * to fold an and into a test node
2632 static bool can_fold_test_and(ir_node *node)
2634 const ir_edge_t *edge;
2636 /** we can only have eq and lg projs */
2637 foreach_out_edge(node, edge) {
2638 ir_node *proj = get_edge_src_irn(edge);
2639 pn_Cmp pnc = get_Proj_proj(proj);
2640 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2648 * returns true if it is assured, that the upper bits of a node are "clean"
2649 * which means for a 16 or 8 bit value, that the upper bits in the register
2650 * are 0 for unsigned and a copy of the last significant bit for signed
2653 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2655 assert(ia32_mode_needs_gp_reg(mode));
2656 if (get_mode_size_bits(mode) >= 32)
2659 if (is_Proj(transformed_node))
2660 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2662 if (is_ia32_Conv_I2I(transformed_node)
2663 || is_ia32_Conv_I2I8Bit(transformed_node)) {
2664 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2665 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2667 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2673 if (is_ia32_Shr(transformed_node) && !mode_is_signed(mode)) {
2674 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2675 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2676 const ia32_immediate_attr_t *attr
2677 = get_ia32_immediate_attr_const(right);
2678 if (attr->symconst == 0
2679 && (unsigned) attr->offset >= (32 - get_mode_size_bits(mode))) {
2683 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2686 if (is_ia32_And(transformed_node) && !mode_is_signed(mode)) {
2687 ir_node *right = get_irn_n(transformed_node, n_ia32_And_right);
2688 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2689 const ia32_immediate_attr_t *attr
2690 = get_ia32_immediate_attr_const(right);
2691 if (attr->symconst == 0
2692 && (unsigned) attr->offset
2693 <= (0xffffffff >> (32 - get_mode_size_bits(mode)))) {
2700 /* TODO recurse on Or, Xor, ... if appropriate? */
2702 if (is_ia32_Immediate(transformed_node)
2703 || is_ia32_Const(transformed_node)) {
2704 const ia32_immediate_attr_t *attr
2705 = get_ia32_immediate_attr_const(transformed_node);
2706 if (mode_is_signed(mode)) {
2707 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2708 if (shifted == 0 || shifted == -1)
2711 unsigned long shifted = (unsigned long) attr->offset;
2712 shifted >>= get_mode_size_bits(mode);
2722 * Generate code for a Cmp.
2724 static ir_node *gen_Cmp(ir_node *node)
2726 ir_graph *irg = current_ir_graph;
2727 dbg_info *dbgi = get_irn_dbg_info(node);
2728 ir_node *block = get_nodes_block(node);
2729 ir_node *new_block = be_transform_node(block);
2730 ir_node *left = get_Cmp_left(node);
2731 ir_node *right = get_Cmp_right(node);
2732 ir_mode *cmp_mode = get_irn_mode(left);
2734 ia32_address_mode_t am;
2735 ia32_address_t *addr = &am.addr;
2738 if (mode_is_float(cmp_mode)) {
2739 if (ia32_cg_config.use_sse2) {
2740 return create_Ucomi(node);
2742 return create_Fucom(node);
2746 assert(ia32_mode_needs_gp_reg(cmp_mode));
2748 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2749 cmp_unsigned = !mode_is_signed(cmp_mode);
2750 if (is_Const_0(right) &&
2752 get_irn_n_edges(left) == 1 &&
2753 can_fold_test_and(node)) {
2754 /* Test(and_left, and_right) */
2755 ir_node *and_left = get_And_left(left);
2756 ir_node *and_right = get_And_right(left);
2758 /* matze: code here used mode instead of cmd_mode, I think it is always
2759 * the same as cmp_mode, but I leave this here to see if this is really
2762 assert(get_irn_mode(and_left) == cmp_mode);
2764 match_arguments(&am, block, and_left, and_right, NULL,
2766 match_am | match_8bit_am | match_16bit_am |
2767 match_am_and_immediates | match_immediate |
2768 match_8bit | match_16bit);
2770 /* use 32bit compare mode if possible since the opcode is smaller */
2771 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2772 upper_bits_clean(am.new_op2, cmp_mode)) {
2773 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2776 if (get_mode_size_bits(cmp_mode) == 8) {
2777 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2778 addr->index, addr->mem, am.new_op1,
2779 am.new_op2, am.ins_permuted,
2782 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2783 addr->index, addr->mem, am.new_op1,
2784 am.new_op2, am.ins_permuted,
2788 /* Cmp(left, right) */
2789 match_arguments(&am, block, left, right, NULL,
2790 match_commutative | match_am | match_8bit_am |
2791 match_16bit_am | match_am_and_immediates |
2792 match_immediate | match_8bit | match_16bit);
2793 /* use 32bit compare mode if possible since the opcode is smaller */
2794 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2795 upper_bits_clean(am.new_op2, cmp_mode)) {
2796 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2799 if (get_mode_size_bits(cmp_mode) == 8) {
2800 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2801 addr->index, addr->mem, am.new_op1,
2802 am.new_op2, am.ins_permuted,
2805 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2806 addr->index, addr->mem, am.new_op1,
2807 am.new_op2, am.ins_permuted, cmp_unsigned);
2810 set_am_attributes(new_node, &am);
2811 set_ia32_ls_mode(new_node, cmp_mode);
2813 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2815 new_node = fix_mem_proj(new_node, &am);
2820 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2823 ir_graph *irg = current_ir_graph;
2824 dbg_info *dbgi = get_irn_dbg_info(node);
2825 ir_node *block = get_nodes_block(node);
2826 ir_node *new_block = be_transform_node(block);
2827 ir_node *val_true = get_Mux_true(node);
2828 ir_node *val_false = get_Mux_false(node);
2830 match_flags_t match_flags;
2831 ia32_address_mode_t am;
2832 ia32_address_t *addr;
2834 assert(ia32_cg_config.use_cmov);
2835 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2839 match_flags = match_commutative | match_am | match_16bit_am |
2842 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2844 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2845 addr->mem, am.new_op1, am.new_op2, new_flags,
2846 am.ins_permuted, pnc);
2847 set_am_attributes(new_node, &am);
2849 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2851 new_node = fix_mem_proj(new_node, &am);
2857 * Creates a ia32 Setcc instruction.
2859 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2860 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2863 ir_graph *irg = current_ir_graph;
2864 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2865 ir_node *nomem = new_NoMem();
2866 ir_mode *mode = get_irn_mode(orig_node);
2869 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2870 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2872 /* we might need to conv the result up */
2873 if (get_mode_size_bits(mode) > 8) {
2874 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2875 nomem, new_node, mode_Bu);
2876 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2883 * Create instruction for an unsigned Difference or Zero.
2885 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2887 ir_graph *irg = current_ir_graph;
2888 ir_mode *mode = get_irn_mode(psi);
2889 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2892 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2893 match_mode_neutral | match_am | match_immediate | match_two_users);
2895 block = get_nodes_block(new_node);
2897 if (is_Proj(new_node)) {
2898 sub = get_Proj_pred(new_node);
2899 assert(is_ia32_Sub(sub));
2902 set_irn_mode(sub, mode_T);
2903 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2905 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2907 dbgi = get_irn_dbg_info(psi);
2908 noreg = ia32_new_NoReg_gp(env_cg);
2909 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2910 nomem = new_NoMem();
2911 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2913 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2914 set_ia32_commutative(new_node);
2919 * Transforms a Mux node into CMov.
2921 * @return The transformed node.
2923 static ir_node *gen_Mux(ir_node *node)
2925 dbg_info *dbgi = get_irn_dbg_info(node);
2926 ir_node *block = get_nodes_block(node);
2927 ir_node *new_block = be_transform_node(block);
2928 ir_node *mux_true = get_Mux_true(node);
2929 ir_node *mux_false = get_Mux_false(node);
2930 ir_node *cond = get_Mux_sel(node);
2931 ir_mode *mode = get_irn_mode(node);
2934 assert(get_irn_mode(cond) == mode_b);
2936 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2937 if (mode_is_float(mode)) {
2938 ir_node *cmp = get_Proj_pred(cond);
2939 ir_node *cmp_left = get_Cmp_left(cmp);
2940 ir_node *cmp_right = get_Cmp_right(cmp);
2941 pn_Cmp pnc = get_Proj_proj(cond);
2943 if (ia32_cg_config.use_sse2) {
2944 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2945 if (cmp_left == mux_true && cmp_right == mux_false) {
2946 /* Mux(a <= b, a, b) => MIN */
2947 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2948 match_commutative | match_am | match_two_users);
2949 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2950 /* Mux(a <= b, b, a) => MAX */
2951 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2952 match_commutative | match_am | match_two_users);
2954 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2955 if (cmp_left == mux_true && cmp_right == mux_false) {
2956 /* Mux(a >= b, a, b) => MAX */
2957 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2958 match_commutative | match_am | match_two_users);
2959 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2960 /* Mux(a >= b, b, a) => MIN */
2961 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2962 match_commutative | match_am | match_two_users);
2966 panic("cannot transform floating point Mux");
2972 assert(ia32_mode_needs_gp_reg(mode));
2974 if (is_Proj(cond)) {
2975 ir_node *cmp = get_Proj_pred(cond);
2977 ir_node *cmp_left = get_Cmp_left(cmp);
2978 ir_node *cmp_right = get_Cmp_right(cmp);
2979 pn_Cmp pnc = get_Proj_proj(cond);
2981 /* check for unsigned Doz first */
2982 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2983 is_Const_0(mux_false) && is_Sub(mux_true) &&
2984 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2985 /* Mux(a >=u b, a - b, 0) unsigned Doz */
2986 return create_Doz(node, cmp_left, cmp_right);
2987 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2988 is_Const_0(mux_true) && is_Sub(mux_false) &&
2989 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2990 /* Mux(a <=u b, 0, a - b) unsigned Doz */
2991 return create_Doz(node, cmp_left, cmp_right);
2996 flags = get_flags_node(cond, &pnc);
2998 if (is_Const(mux_true) && is_Const(mux_false)) {
2999 /* both are const, good */
3000 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3001 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3002 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3003 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3005 /* Not that simple. */
3010 new_node = create_CMov(node, cond, flags, pnc);
3018 * Create a conversion from x87 state register to general purpose.
3020 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3022 ir_node *block = be_transform_node(get_nodes_block(node));
3023 ir_node *op = get_Conv_op(node);
3024 ir_node *new_op = be_transform_node(op);
3025 ia32_code_gen_t *cg = env_cg;
3026 ir_graph *irg = current_ir_graph;
3027 dbg_info *dbgi = get_irn_dbg_info(node);
3028 ir_node *noreg = ia32_new_NoReg_gp(cg);
3029 ir_mode *mode = get_irn_mode(node);
3030 ir_node *fist, *load, *mem;
3032 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3033 set_irn_pinned(fist, op_pin_state_floats);
3034 set_ia32_use_frame(fist);
3035 set_ia32_op_type(fist, ia32_AddrModeD);
3037 assert(get_mode_size_bits(mode) <= 32);
3038 /* exception we can only store signed 32 bit integers, so for unsigned
3039 we store a 64bit (signed) integer and load the lower bits */
3040 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3041 set_ia32_ls_mode(fist, mode_Ls);
3043 set_ia32_ls_mode(fist, mode_Is);
3045 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3048 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3050 set_irn_pinned(load, op_pin_state_floats);
3051 set_ia32_use_frame(load);
3052 set_ia32_op_type(load, ia32_AddrModeS);
3053 set_ia32_ls_mode(load, mode_Is);
3054 if (get_ia32_ls_mode(fist) == mode_Ls) {
3055 ia32_attr_t *attr = get_ia32_attr(load);
3056 attr->data.need_64bit_stackent = 1;
3058 ia32_attr_t *attr = get_ia32_attr(load);
3059 attr->data.need_32bit_stackent = 1;
3061 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3063 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3067 * Creates a x87 strict Conv by placing a Store and a Load
3069 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3071 ir_node *block = get_nodes_block(node);
3072 ir_graph *irg = current_ir_graph;
3073 dbg_info *dbgi = get_irn_dbg_info(node);
3074 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3075 ir_node *nomem = new_NoMem();
3076 ir_node *frame = get_irg_frame(irg);
3077 ir_node *store, *load;
3080 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3082 set_ia32_use_frame(store);
3083 set_ia32_op_type(store, ia32_AddrModeD);
3084 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3086 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3088 set_ia32_use_frame(load);
3089 set_ia32_op_type(load, ia32_AddrModeS);
3090 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3092 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3097 * Create a conversion from general purpose to x87 register
3099 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3101 ir_node *src_block = get_nodes_block(node);
3102 ir_node *block = be_transform_node(src_block);
3103 ir_graph *irg = current_ir_graph;
3104 dbg_info *dbgi = get_irn_dbg_info(node);
3105 ir_node *op = get_Conv_op(node);
3106 ir_node *new_op = NULL;
3110 ir_mode *store_mode;
3116 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3117 if (src_mode == mode_Is || src_mode == mode_Hs) {
3118 ia32_address_mode_t am;
3120 match_arguments(&am, src_block, NULL, op, NULL,
3121 match_am | match_try_am | match_16bit | match_16bit_am);
3122 if (am.op_type == ia32_AddrModeS) {
3123 ia32_address_t *addr = &am.addr;
3125 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3126 addr->index, addr->mem);
3127 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3130 set_am_attributes(fild, &am);
3131 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3133 fix_mem_proj(fild, &am);
3138 if (new_op == NULL) {
3139 new_op = be_transform_node(op);
3142 noreg = ia32_new_NoReg_gp(env_cg);
3143 nomem = new_NoMem();
3144 mode = get_irn_mode(op);
3146 /* first convert to 32 bit signed if necessary */
3147 src_bits = get_mode_size_bits(src_mode);
3148 if (src_bits == 8) {
3149 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3151 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3153 } else if (src_bits < 32) {
3154 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3156 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3160 assert(get_mode_size_bits(mode) == 32);
3163 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3166 set_ia32_use_frame(store);
3167 set_ia32_op_type(store, ia32_AddrModeD);
3168 set_ia32_ls_mode(store, mode_Iu);
3170 /* exception for 32bit unsigned, do a 64bit spill+load */
3171 if (!mode_is_signed(mode)) {
3174 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3176 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3177 get_irg_frame(irg), noreg, nomem,
3180 set_ia32_use_frame(zero_store);
3181 set_ia32_op_type(zero_store, ia32_AddrModeD);
3182 add_ia32_am_offs_int(zero_store, 4);
3183 set_ia32_ls_mode(zero_store, mode_Iu);
3188 store = new_rd_Sync(dbgi, irg, block, 2, in);
3189 store_mode = mode_Ls;
3191 store_mode = mode_Is;
3195 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3197 set_ia32_use_frame(fild);
3198 set_ia32_op_type(fild, ia32_AddrModeS);
3199 set_ia32_ls_mode(fild, store_mode);
3201 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3207 * Create a conversion from one integer mode into another one
3209 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3210 dbg_info *dbgi, ir_node *block, ir_node *op,
3213 ir_graph *irg = current_ir_graph;
3214 int src_bits = get_mode_size_bits(src_mode);
3215 int tgt_bits = get_mode_size_bits(tgt_mode);
3216 ir_node *new_block = be_transform_node(block);
3218 ir_mode *smaller_mode;
3220 ia32_address_mode_t am;
3221 ia32_address_t *addr = &am.addr;
3224 if (src_bits < tgt_bits) {
3225 smaller_mode = src_mode;
3226 smaller_bits = src_bits;
3228 smaller_mode = tgt_mode;
3229 smaller_bits = tgt_bits;
3232 #ifdef DEBUG_libfirm
3234 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3239 match_arguments(&am, block, NULL, op, NULL,
3240 match_8bit | match_16bit |
3241 match_am | match_8bit_am | match_16bit_am);
3243 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3244 /* unnecessary conv. in theory it shouldn't have been AM */
3245 assert(is_ia32_NoReg_GP(addr->base));
3246 assert(is_ia32_NoReg_GP(addr->index));
3247 assert(is_NoMem(addr->mem));
3248 assert(am.addr.offset == 0);
3249 assert(am.addr.symconst_ent == NULL);
3253 if (smaller_bits == 8) {
3254 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3255 addr->index, addr->mem, am.new_op2,
3258 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3259 addr->index, addr->mem, am.new_op2,
3262 set_am_attributes(new_node, &am);
3263 /* match_arguments assume that out-mode = in-mode, this isn't true here
3265 set_ia32_ls_mode(new_node, smaller_mode);
3266 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3267 new_node = fix_mem_proj(new_node, &am);
3272 * Transforms a Conv node.
3274 * @return The created ia32 Conv node
3276 static ir_node *gen_Conv(ir_node *node)
3278 ir_node *block = get_nodes_block(node);
3279 ir_node *new_block = be_transform_node(block);
3280 ir_node *op = get_Conv_op(node);
3281 ir_node *new_op = NULL;
3282 ir_graph *irg = current_ir_graph;
3283 dbg_info *dbgi = get_irn_dbg_info(node);
3284 ir_mode *src_mode = get_irn_mode(op);
3285 ir_mode *tgt_mode = get_irn_mode(node);
3286 int src_bits = get_mode_size_bits(src_mode);
3287 int tgt_bits = get_mode_size_bits(tgt_mode);
3288 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3289 ir_node *nomem = new_rd_NoMem(irg);
3290 ir_node *res = NULL;
3292 if (src_mode == mode_b) {
3293 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3294 /* nothing to do, we already model bools as 0/1 ints */
3295 return be_transform_node(op);
3298 if (src_mode == tgt_mode) {
3299 if (get_Conv_strict(node)) {
3300 if (ia32_cg_config.use_sse2) {
3301 /* when we are in SSE mode, we can kill all strict no-op conversion */
3302 return be_transform_node(op);
3305 /* this should be optimized already, but who knows... */
3306 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3307 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3308 return be_transform_node(op);
3312 if (mode_is_float(src_mode)) {
3313 new_op = be_transform_node(op);
3314 /* we convert from float ... */
3315 if (mode_is_float(tgt_mode)) {
3316 if (src_mode == mode_E && tgt_mode == mode_D
3317 && !get_Conv_strict(node)) {
3318 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3323 if (ia32_cg_config.use_sse2) {
3324 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3325 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3327 set_ia32_ls_mode(res, tgt_mode);
3329 if (get_Conv_strict(node)) {
3330 res = gen_x87_strict_conv(tgt_mode, new_op);
3331 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3334 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3339 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3340 if (ia32_cg_config.use_sse2) {
3341 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3343 set_ia32_ls_mode(res, src_mode);
3345 return gen_x87_fp_to_gp(node);
3349 /* we convert from int ... */
3350 if (mode_is_float(tgt_mode)) {
3352 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3353 if (ia32_cg_config.use_sse2) {
3354 new_op = be_transform_node(op);
3355 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3357 set_ia32_ls_mode(res, tgt_mode);
3359 res = gen_x87_gp_to_fp(node, src_mode);
3360 if (get_Conv_strict(node)) {
3361 /* The strict-Conv is only necessary, if the int mode has more bits
3362 * than the float mantissa */
3363 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3364 size_t float_mantissa;
3365 /* FIXME There is no way to get the mantissa size of a mode */
3366 switch (get_mode_size_bits(tgt_mode)) {
3367 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3368 case 64: float_mantissa = 52 + 1; break;
3370 case 96: float_mantissa = 64; break;
3371 default: float_mantissa = 0; break;
3373 if (float_mantissa < int_mantissa) {
3374 res = gen_x87_strict_conv(tgt_mode, res);
3375 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3380 } else if (tgt_mode == mode_b) {
3381 /* mode_b lowering already took care that we only have 0/1 values */
3382 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3383 src_mode, tgt_mode));
3384 return be_transform_node(op);
3387 if (src_bits == tgt_bits) {
3388 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3389 src_mode, tgt_mode));
3390 return be_transform_node(op);
3393 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3401 static ir_node *create_immediate_or_transform(ir_node *node,
3402 char immediate_constraint_type)
3404 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3405 if (new_node == NULL) {
3406 new_node = be_transform_node(node);
3412 * Transforms a FrameAddr into an ia32 Add.
3414 static ir_node *gen_be_FrameAddr(ir_node *node)
3416 ir_node *block = be_transform_node(get_nodes_block(node));
3417 ir_node *op = be_get_FrameAddr_frame(node);
3418 ir_node *new_op = be_transform_node(op);
3419 ir_graph *irg = current_ir_graph;
3420 dbg_info *dbgi = get_irn_dbg_info(node);
3421 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3424 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3425 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3426 set_ia32_use_frame(new_node);
3428 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3434 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3436 static ir_node *gen_be_Return(ir_node *node)
3438 ir_graph *irg = current_ir_graph;
3439 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3440 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3441 ir_entity *ent = get_irg_entity(irg);
3442 ir_type *tp = get_entity_type(ent);
3447 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3448 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3451 int pn_ret_val, pn_ret_mem, arity, i;
3453 assert(ret_val != NULL);
3454 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3455 return be_duplicate_node(node);
3458 res_type = get_method_res_type(tp, 0);
3460 if (! is_Primitive_type(res_type)) {
3461 return be_duplicate_node(node);
3464 mode = get_type_mode(res_type);
3465 if (! mode_is_float(mode)) {
3466 return be_duplicate_node(node);
3469 assert(get_method_n_ress(tp) == 1);
3471 pn_ret_val = get_Proj_proj(ret_val);
3472 pn_ret_mem = get_Proj_proj(ret_mem);
3474 /* get the Barrier */
3475 barrier = get_Proj_pred(ret_val);
3477 /* get result input of the Barrier */
3478 ret_val = get_irn_n(barrier, pn_ret_val);
3479 new_ret_val = be_transform_node(ret_val);
3481 /* get memory input of the Barrier */
3482 ret_mem = get_irn_n(barrier, pn_ret_mem);
3483 new_ret_mem = be_transform_node(ret_mem);
3485 frame = get_irg_frame(irg);
3487 dbgi = get_irn_dbg_info(barrier);
3488 block = be_transform_node(get_nodes_block(barrier));
3490 noreg = ia32_new_NoReg_gp(env_cg);
3492 /* store xmm0 onto stack */
3493 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3494 new_ret_mem, new_ret_val);
3495 set_ia32_ls_mode(sse_store, mode);
3496 set_ia32_op_type(sse_store, ia32_AddrModeD);
3497 set_ia32_use_frame(sse_store);
3499 /* load into x87 register */
3500 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3501 set_ia32_op_type(fld, ia32_AddrModeS);
3502 set_ia32_use_frame(fld);
3504 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3505 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3507 /* create a new barrier */
3508 arity = get_irn_arity(barrier);
3509 in = alloca(arity * sizeof(in[0]));
3510 for (i = 0; i < arity; ++i) {
3513 if (i == pn_ret_val) {
3515 } else if (i == pn_ret_mem) {
3518 ir_node *in = get_irn_n(barrier, i);
3519 new_in = be_transform_node(in);
3524 new_barrier = new_ir_node(dbgi, irg, block,
3525 get_irn_op(barrier), get_irn_mode(barrier),
3527 copy_node_attr(barrier, new_barrier);
3528 be_duplicate_deps(barrier, new_barrier);
3529 be_set_transformed_node(barrier, new_barrier);
3531 /* transform normally */
3532 return be_duplicate_node(node);
3536 * Transform a be_AddSP into an ia32_SubSP.
3538 static ir_node *gen_be_AddSP(ir_node *node)
3540 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3541 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3543 return gen_binop(node, sp, sz, new_rd_ia32_SubSP,
3544 match_am | match_immediate);
3548 * Transform a be_SubSP into an ia32_AddSP
3550 static ir_node *gen_be_SubSP(ir_node *node)
3552 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3553 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3555 return gen_binop(node, sp, sz, new_rd_ia32_AddSP,
3556 match_am | match_immediate);
3560 * Change some phi modes
3562 static ir_node *gen_Phi(ir_node *node)
3564 ir_node *block = be_transform_node(get_nodes_block(node));
3565 ir_graph *irg = current_ir_graph;
3566 dbg_info *dbgi = get_irn_dbg_info(node);
3567 ir_mode *mode = get_irn_mode(node);
3570 if (ia32_mode_needs_gp_reg(mode)) {
3571 /* we shouldn't have any 64bit stuff around anymore */
3572 assert(get_mode_size_bits(mode) <= 32);
3573 /* all integer operations are on 32bit registers now */
3575 } else if (mode_is_float(mode)) {
3576 if (ia32_cg_config.use_sse2) {
3583 /* phi nodes allow loops, so we use the old arguments for now
3584 * and fix this later */
3585 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3586 get_irn_in(node) + 1);
3587 copy_node_attr(node, phi);
3588 be_duplicate_deps(node, phi);
3590 be_enqueue_preds(node);
3598 static ir_node *gen_IJmp(ir_node *node)
3600 ir_node *block = get_nodes_block(node);
3601 ir_node *new_block = be_transform_node(block);
3602 dbg_info *dbgi = get_irn_dbg_info(node);
3603 ir_node *op = get_IJmp_target(node);
3605 ia32_address_mode_t am;
3606 ia32_address_t *addr = &am.addr;
3608 assert(get_irn_mode(op) == mode_P);
3610 match_arguments(&am, block, NULL, op, NULL,
3611 match_am | match_8bit_am | match_16bit_am |
3612 match_immediate | match_8bit | match_16bit);
3614 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3615 addr->base, addr->index, addr->mem,
3617 set_am_attributes(new_node, &am);
3618 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3620 new_node = fix_mem_proj(new_node, &am);
3626 * Transform a Bound node.
3628 static ir_node *gen_Bound(ir_node *node)
3631 ir_node *lower = get_Bound_lower(node);
3632 dbg_info *dbgi = get_irn_dbg_info(node);
3634 if (is_Const_0(lower)) {
3635 /* typical case for Java */
3636 ir_node *sub, *res, *flags, *block;
3637 ir_graph *irg = current_ir_graph;
3639 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3640 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3642 block = get_nodes_block(res);
3643 if (! is_Proj(res)) {
3645 set_irn_mode(sub, mode_T);
3646 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3648 sub = get_Proj_pred(res);
3650 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3651 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3652 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3654 panic("generic Bound not supported in ia32 Backend");
3660 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3662 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3663 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3665 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3666 match_immediate | match_mode_neutral);
3669 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3671 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3672 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3673 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3677 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3679 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3680 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3681 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3685 static ir_node *gen_ia32_l_Add(ir_node *node)
3687 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3688 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3689 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3690 match_commutative | match_am | match_immediate |
3691 match_mode_neutral);
3693 if (is_Proj(lowered)) {
3694 lowered = get_Proj_pred(lowered);
3696 assert(is_ia32_Add(lowered));
3697 set_irn_mode(lowered, mode_T);
3703 static ir_node *gen_ia32_l_Adc(ir_node *node)
3705 return gen_binop_flags(node, new_rd_ia32_Adc,
3706 match_commutative | match_am | match_immediate |
3707 match_mode_neutral);
3711 * Transforms a l_MulS into a "real" MulS node.
3713 * @return the created ia32 Mul node
3715 static ir_node *gen_ia32_l_Mul(ir_node *node)
3717 ir_node *left = get_binop_left(node);
3718 ir_node *right = get_binop_right(node);
3720 return gen_binop(node, left, right, new_rd_ia32_Mul,
3721 match_commutative | match_am | match_mode_neutral);
3725 * Transforms a l_IMulS into a "real" IMul1OPS node.
3727 * @return the created ia32 IMul1OP node
3729 static ir_node *gen_ia32_l_IMul(ir_node *node)
3731 ir_node *left = get_binop_left(node);
3732 ir_node *right = get_binop_right(node);
3734 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3735 match_commutative | match_am | match_mode_neutral);
3738 static ir_node *gen_ia32_l_Sub(ir_node *node)
3740 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3741 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3742 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3743 match_am | match_immediate | match_mode_neutral);
3745 if (is_Proj(lowered)) {
3746 lowered = get_Proj_pred(lowered);
3748 assert(is_ia32_Sub(lowered));
3749 set_irn_mode(lowered, mode_T);
3755 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3757 return gen_binop_flags(node, new_rd_ia32_Sbb,
3758 match_am | match_immediate | match_mode_neutral);
3762 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3763 * op1 - target to be shifted
3764 * op2 - contains bits to be shifted into target
3766 * Only op3 can be an immediate.
3768 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3769 ir_node *low, ir_node *count)
3771 ir_node *block = get_nodes_block(node);
3772 ir_node *new_block = be_transform_node(block);
3773 ir_graph *irg = current_ir_graph;
3774 dbg_info *dbgi = get_irn_dbg_info(node);
3775 ir_node *new_high = be_transform_node(high);
3776 ir_node *new_low = be_transform_node(low);
3780 /* the shift amount can be any mode that is bigger than 5 bits, since all
3781 * other bits are ignored anyway */
3782 while (is_Conv(count) &&
3783 get_irn_n_edges(count) == 1 &&
3784 mode_is_int(get_irn_mode(count))) {
3785 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3786 count = get_Conv_op(count);
3788 new_count = create_immediate_or_transform(count, 0);
3790 if (is_ia32_l_ShlD(node)) {
3791 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3794 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3797 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3802 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3804 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3805 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3806 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3807 return gen_lowered_64bit_shifts(node, high, low, count);
3810 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3812 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3813 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3814 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3815 return gen_lowered_64bit_shifts(node, high, low, count);
3818 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3820 ir_node *src_block = get_nodes_block(node);
3821 ir_node *block = be_transform_node(src_block);
3822 ir_graph *irg = current_ir_graph;
3823 dbg_info *dbgi = get_irn_dbg_info(node);
3824 ir_node *frame = get_irg_frame(irg);
3825 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3826 ir_node *nomem = new_NoMem();
3827 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3828 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3829 ir_node *new_val_low = be_transform_node(val_low);
3830 ir_node *new_val_high = be_transform_node(val_high);
3835 ir_node *store_high;
3837 if (!mode_is_signed(get_irn_mode(val_high))) {
3838 panic("unsigned long long -> float not supported yet (%+F)", node);
3842 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3844 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3846 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3847 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3849 set_ia32_use_frame(store_low);
3850 set_ia32_use_frame(store_high);
3851 set_ia32_op_type(store_low, ia32_AddrModeD);
3852 set_ia32_op_type(store_high, ia32_AddrModeD);
3853 set_ia32_ls_mode(store_low, mode_Iu);
3854 set_ia32_ls_mode(store_high, mode_Is);
3855 add_ia32_am_offs_int(store_high, 4);
3859 sync = new_rd_Sync(dbgi, irg, block, 2, in);
3862 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3864 set_ia32_use_frame(fild);
3865 set_ia32_op_type(fild, ia32_AddrModeS);
3866 set_ia32_ls_mode(fild, mode_Ls);
3868 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3870 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3873 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3875 ir_node *src_block = get_nodes_block(node);
3876 ir_node *block = be_transform_node(src_block);
3877 ir_graph *irg = current_ir_graph;
3878 dbg_info *dbgi = get_irn_dbg_info(node);
3879 ir_node *frame = get_irg_frame(irg);
3880 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3881 ir_node *nomem = new_NoMem();
3882 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
3883 ir_node *new_val = be_transform_node(val);
3884 ir_node *fist, *mem;
3886 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3887 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3888 set_ia32_use_frame(fist);
3889 set_ia32_op_type(fist, ia32_AddrModeD);
3890 set_ia32_ls_mode(fist, mode_Ls);
3896 * the BAD transformer.
3898 static ir_node *bad_transform(ir_node *node)
3900 panic("No transform function for %+F available.", node);
3904 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3906 ir_graph *irg = current_ir_graph;
3907 ir_node *block = be_transform_node(get_nodes_block(node));
3908 ir_node *pred = get_Proj_pred(node);
3909 ir_node *new_pred = be_transform_node(pred);
3910 ir_node *frame = get_irg_frame(irg);
3911 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3912 dbg_info *dbgi = get_irn_dbg_info(node);
3913 long pn = get_Proj_proj(node);
3918 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3919 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3920 set_ia32_use_frame(load);
3921 set_ia32_op_type(load, ia32_AddrModeS);
3922 set_ia32_ls_mode(load, mode_Iu);
3923 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3924 * 32 bit from it with this particular load */
3925 attr = get_ia32_attr(load);
3926 attr->data.need_64bit_stackent = 1;
3928 if (pn == pn_ia32_l_FloattoLL_res_high) {
3929 add_ia32_am_offs_int(load, 4);
3931 assert(pn == pn_ia32_l_FloattoLL_res_low);
3934 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3940 * Transform the Projs of an AddSP.
3942 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3944 ir_node *block = be_transform_node(get_nodes_block(node));
3945 ir_node *pred = get_Proj_pred(node);
3946 ir_node *new_pred = be_transform_node(pred);
3947 ir_graph *irg = current_ir_graph;
3948 dbg_info *dbgi = get_irn_dbg_info(node);
3949 long proj = get_Proj_proj(node);
3951 if (proj == pn_be_AddSP_sp) {
3952 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3953 pn_ia32_SubSP_stack);
3954 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3956 } else if (proj == pn_be_AddSP_res) {
3957 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3958 pn_ia32_SubSP_addr);
3959 } else if (proj == pn_be_AddSP_M) {
3960 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3963 panic("No idea how to transform proj->AddSP");
3967 * Transform the Projs of a SubSP.
3969 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3971 ir_node *block = be_transform_node(get_nodes_block(node));
3972 ir_node *pred = get_Proj_pred(node);
3973 ir_node *new_pred = be_transform_node(pred);
3974 ir_graph *irg = current_ir_graph;
3975 dbg_info *dbgi = get_irn_dbg_info(node);
3976 long proj = get_Proj_proj(node);
3978 if (proj == pn_be_SubSP_sp) {
3979 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3980 pn_ia32_AddSP_stack);
3981 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3983 } else if (proj == pn_be_SubSP_M) {
3984 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3987 panic("No idea how to transform proj->SubSP");
3991 * Transform and renumber the Projs from a Load.
3993 static ir_node *gen_Proj_Load(ir_node *node)
3996 ir_node *block = be_transform_node(get_nodes_block(node));
3997 ir_node *pred = get_Proj_pred(node);
3998 ir_graph *irg = current_ir_graph;
3999 dbg_info *dbgi = get_irn_dbg_info(node);
4000 long proj = get_Proj_proj(node);
4002 /* loads might be part of source address mode matches, so we don't
4003 * transform the ProjMs yet (with the exception of loads whose result is
4006 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4009 /* this is needed, because sometimes we have loops that are only
4010 reachable through the ProjM */
4011 be_enqueue_preds(node);
4012 /* do it in 2 steps, to silence firm verifier */
4013 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4014 set_Proj_proj(res, pn_ia32_mem);
4018 /* renumber the proj */
4019 new_pred = be_transform_node(pred);
4020 if (is_ia32_Load(new_pred)) {
4023 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4025 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4026 case pn_Load_X_regular:
4027 return new_rd_Jmp(dbgi, irg, block);
4028 case pn_Load_X_except:
4029 /* This Load might raise an exception. Mark it. */
4030 set_ia32_exc_label(new_pred, 1);
4031 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4035 } else if (is_ia32_Conv_I2I(new_pred) ||
4036 is_ia32_Conv_I2I8Bit(new_pred)) {
4037 set_irn_mode(new_pred, mode_T);
4038 if (proj == pn_Load_res) {
4039 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4040 } else if (proj == pn_Load_M) {
4041 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4043 } else if (is_ia32_xLoad(new_pred)) {
4046 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4048 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4049 case pn_Load_X_regular:
4050 return new_rd_Jmp(dbgi, irg, block);
4051 case pn_Load_X_except:
4052 /* This Load might raise an exception. Mark it. */
4053 set_ia32_exc_label(new_pred, 1);
4054 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4058 } else if (is_ia32_vfld(new_pred)) {
4061 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4063 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4064 case pn_Load_X_regular:
4065 return new_rd_Jmp(dbgi, irg, block);
4066 case pn_Load_X_except:
4067 /* This Load might raise an exception. Mark it. */
4068 set_ia32_exc_label(new_pred, 1);
4069 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4074 /* can happen for ProJMs when source address mode happened for the
4077 /* however it should not be the result proj, as that would mean the
4078 load had multiple users and should not have been used for
4080 if (proj != pn_Load_M) {
4081 panic("internal error: transformed node not a Load");
4083 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4086 panic("No idea how to transform proj");
4090 * Transform and renumber the Projs from a DivMod like instruction.
4092 static ir_node *gen_Proj_DivMod(ir_node *node)
4094 ir_node *block = be_transform_node(get_nodes_block(node));
4095 ir_node *pred = get_Proj_pred(node);
4096 ir_node *new_pred = be_transform_node(pred);
4097 ir_graph *irg = current_ir_graph;
4098 dbg_info *dbgi = get_irn_dbg_info(node);
4099 long proj = get_Proj_proj(node);
4101 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4103 switch (get_irn_opcode(pred)) {
4107 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4109 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4110 case pn_Div_X_regular:
4111 return new_rd_Jmp(dbgi, irg, block);
4112 case pn_Div_X_except:
4113 set_ia32_exc_label(new_pred, 1);
4114 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4122 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4124 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4125 case pn_Mod_X_except:
4126 set_ia32_exc_label(new_pred, 1);
4127 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4135 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4136 case pn_DivMod_res_div:
4137 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4138 case pn_DivMod_res_mod:
4139 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4140 case pn_DivMod_X_regular:
4141 return new_rd_Jmp(dbgi, irg, block);
4142 case pn_DivMod_X_except:
4143 set_ia32_exc_label(new_pred, 1);
4144 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4153 panic("No idea how to transform proj->DivMod");
4157 * Transform and renumber the Projs from a CopyB.
4159 static ir_node *gen_Proj_CopyB(ir_node *node)
4161 ir_node *block = be_transform_node(get_nodes_block(node));
4162 ir_node *pred = get_Proj_pred(node);
4163 ir_node *new_pred = be_transform_node(pred);
4164 ir_graph *irg = current_ir_graph;
4165 dbg_info *dbgi = get_irn_dbg_info(node);
4166 long proj = get_Proj_proj(node);
4169 case pn_CopyB_M_regular:
4170 if (is_ia32_CopyB_i(new_pred)) {
4171 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4172 } else if (is_ia32_CopyB(new_pred)) {
4173 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4180 panic("No idea how to transform proj->CopyB");
4184 * Transform and renumber the Projs from a Quot.
4186 static ir_node *gen_Proj_Quot(ir_node *node)
4188 ir_node *block = be_transform_node(get_nodes_block(node));
4189 ir_node *pred = get_Proj_pred(node);
4190 ir_node *new_pred = be_transform_node(pred);
4191 ir_graph *irg = current_ir_graph;
4192 dbg_info *dbgi = get_irn_dbg_info(node);
4193 long proj = get_Proj_proj(node);
4197 if (is_ia32_xDiv(new_pred)) {
4198 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4199 } else if (is_ia32_vfdiv(new_pred)) {
4200 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4204 if (is_ia32_xDiv(new_pred)) {
4205 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4206 } else if (is_ia32_vfdiv(new_pred)) {
4207 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4210 case pn_Quot_X_regular:
4211 case pn_Quot_X_except:
4216 panic("No idea how to transform proj->Quot");
4219 static ir_node *gen_be_Call(ir_node *node)
4221 dbg_info *const dbgi = get_irn_dbg_info(node);
4222 ir_graph *const irg = current_ir_graph;
4223 ir_node *const src_block = get_nodes_block(node);
4224 ir_node *const block = be_transform_node(src_block);
4225 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4226 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4227 ir_node *const sp = be_transform_node(src_sp);
4228 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4229 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4230 ia32_address_mode_t am;
4231 ia32_address_t *const addr = &am.addr;
4236 ir_node * eax = noreg;
4237 ir_node * ecx = noreg;
4238 ir_node * edx = noreg;
4239 unsigned const pop = be_Call_get_pop(node);
4240 ir_type *const call_tp = be_Call_get_type(node);
4242 /* Run the x87 simulator if the call returns a float value */
4243 if (get_method_n_ress(call_tp) > 0) {
4244 ir_type *const res_type = get_method_res_type(call_tp, 0);
4245 ir_mode *const res_mode = get_type_mode(res_type);
4247 if (res_mode != NULL && mode_is_float(res_mode)) {
4248 env_cg->do_x87_sim = 1;
4252 /* We do not want be_Call direct calls */
4253 assert(be_Call_get_entity(node) == NULL);
4255 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4256 match_am | match_immediate);
4258 i = get_irn_arity(node) - 1;
4259 fpcw = be_transform_node(get_irn_n(node, i--));
4260 for (; i >= be_pos_Call_first_arg; --i) {
4261 arch_register_req_t const *const req = arch_get_register_req(node, i);
4262 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4264 assert(req->type == arch_register_req_type_limited);
4265 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4267 switch (*req->limited) {
4268 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4269 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4270 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4271 default: panic("Invalid GP register for register parameter");
4275 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4276 call = new_rd_ia32_Call(dbgi, irg, block, addr->base, addr->index, mem,
4277 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4278 set_am_attributes(call, &am);
4279 call = fix_mem_proj(call, &am);
4281 if (get_irn_pinned(node) == op_pin_state_pinned)
4282 set_irn_pinned(call, op_pin_state_pinned);
4284 SET_IA32_ORIG_NODE(call, ia32_get_old_node_name(env_cg, node));
4288 static ir_node *gen_be_IncSP(ir_node *node)
4290 ir_node *res = be_duplicate_node(node);
4291 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4297 * Transform the Projs from a be_Call.
4299 static ir_node *gen_Proj_be_Call(ir_node *node)
4301 ir_node *block = be_transform_node(get_nodes_block(node));
4302 ir_node *call = get_Proj_pred(node);
4303 ir_node *new_call = be_transform_node(call);
4304 ir_graph *irg = current_ir_graph;
4305 dbg_info *dbgi = get_irn_dbg_info(node);
4306 ir_type *method_type = be_Call_get_type(call);
4307 int n_res = get_method_n_ress(method_type);
4308 long proj = get_Proj_proj(node);
4309 ir_mode *mode = get_irn_mode(node);
4311 const arch_register_class_t *cls;
4314 /* The following is kinda tricky: If we're using SSE, then we have to
4315 * move the result value of the call in floating point registers to an
4316 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4317 * after the call, we have to make sure to correctly make the
4318 * MemProj and the result Proj use these 2 nodes
4320 if (proj == pn_be_Call_M_regular) {
4321 // get new node for result, are we doing the sse load/store hack?
4322 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4323 ir_node *call_res_new;
4324 ir_node *call_res_pred = NULL;
4326 if (call_res != NULL) {
4327 call_res_new = be_transform_node(call_res);
4328 call_res_pred = get_Proj_pred(call_res_new);
4331 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4332 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4335 assert(is_ia32_xLoad(call_res_pred));
4336 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4340 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4341 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4343 ir_node *frame = get_irg_frame(irg);
4344 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4346 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4349 /* in case there is no memory output: create one to serialize the copy
4351 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4352 pn_be_Call_M_regular);
4353 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4354 pn_be_Call_first_res);
4356 /* store st(0) onto stack */
4357 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4359 set_ia32_op_type(fstp, ia32_AddrModeD);
4360 set_ia32_use_frame(fstp);
4362 /* load into SSE register */
4363 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4365 set_ia32_op_type(sse_load, ia32_AddrModeS);
4366 set_ia32_use_frame(sse_load);
4368 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4374 /* transform call modes */
4375 if (mode_is_data(mode)) {
4376 cls = arch_get_irn_reg_class(node, -1);
4380 /* Map from be_Call to ia32_Call proj number */
4381 if (proj == pn_be_Call_sp) {
4382 proj = pn_ia32_Call_stack;
4383 } else if (proj == pn_be_Call_M_regular) {
4384 proj = pn_ia32_Call_M;
4386 arch_register_req_t const *const req = arch_get_register_req(node, BE_OUT_POS(proj));
4387 int const n_outs = get_ia32_n_res(new_call);
4390 assert(proj >= pn_be_Call_first_res);
4391 assert(req->type == arch_register_req_type_limited);
4393 for (i = 0; i < n_outs; ++i) {
4394 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4396 if (new_req->type != arch_register_req_type_limited ||
4397 new_req->cls != req->cls ||
4398 *new_req->limited != *req->limited)
4407 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4409 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4411 case pn_ia32_Call_stack:
4412 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4415 case pn_ia32_Call_fpcw:
4416 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4424 * Transform the Projs from a Cmp.
4426 static ir_node *gen_Proj_Cmp(ir_node *node)
4428 /* this probably means not all mode_b nodes were lowered... */
4429 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4434 * Transform the Projs from a Bound.
4436 static ir_node *gen_Proj_Bound(ir_node *node)
4438 ir_node *new_node, *block;
4439 ir_node *pred = get_Proj_pred(node);
4441 switch (get_Proj_proj(node)) {
4443 return be_transform_node(get_Bound_mem(pred));
4444 case pn_Bound_X_regular:
4445 new_node = be_transform_node(pred);
4446 block = get_nodes_block(new_node);
4447 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4448 case pn_Bound_X_except:
4449 new_node = be_transform_node(pred);
4450 block = get_nodes_block(new_node);
4451 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4453 return be_transform_node(get_Bound_index(pred));
4455 panic("unsupported Proj from Bound");
4459 static ir_node *gen_Proj_ASM(ir_node *node)
4465 if (get_irn_mode(node) != mode_M)
4466 return be_duplicate_node(node);
4468 pred = get_Proj_pred(node);
4469 new_pred = be_transform_node(pred);
4470 block = get_nodes_block(new_pred);
4471 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4472 get_ia32_n_res(new_pred) + 1);
4476 * Transform and potentially renumber Proj nodes.
4478 static ir_node *gen_Proj(ir_node *node)
4480 ir_node *pred = get_Proj_pred(node);
4483 switch (get_irn_opcode(pred)) {
4485 proj = get_Proj_proj(node);
4486 if (proj == pn_Store_M) {
4487 return be_transform_node(pred);
4489 panic("No idea how to transform proj->Store");
4492 return gen_Proj_Load(node);
4494 return gen_Proj_ASM(node);
4498 return gen_Proj_DivMod(node);
4500 return gen_Proj_CopyB(node);
4502 return gen_Proj_Quot(node);
4504 return gen_Proj_be_SubSP(node);
4506 return gen_Proj_be_AddSP(node);
4508 return gen_Proj_be_Call(node);
4510 return gen_Proj_Cmp(node);
4512 return gen_Proj_Bound(node);
4514 proj = get_Proj_proj(node);
4516 case pn_Start_X_initial_exec: {
4517 ir_node *block = get_nodes_block(pred);
4518 ir_node *new_block = be_transform_node(block);
4519 dbg_info *dbgi = get_irn_dbg_info(node);
4520 /* we exchange the ProjX with a jump */
4521 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4526 case pn_Start_P_tls:
4527 return gen_Proj_tls(node);
4532 if (is_ia32_l_FloattoLL(pred)) {
4533 return gen_Proj_l_FloattoLL(node);
4535 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4539 ir_mode *mode = get_irn_mode(node);
4540 if (ia32_mode_needs_gp_reg(mode)) {
4541 ir_node *new_pred = be_transform_node(pred);
4542 ir_node *block = be_transform_node(get_nodes_block(node));
4543 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4544 mode_Iu, get_Proj_proj(node));
4545 #ifdef DEBUG_libfirm
4546 new_proj->node_nr = node->node_nr;
4552 return be_duplicate_node(node);
4556 * Enters all transform functions into the generic pointer
4558 static void register_transformers(void)
4562 /* first clear the generic function pointer for all ops */
4563 clear_irp_opcodes_generic_func();
4565 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4566 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4604 /* transform ops from intrinsic lowering */
4616 GEN(ia32_l_LLtoFloat);
4617 GEN(ia32_l_FloattoLL);
4623 /* we should never see these nodes */
4638 /* handle generic backend nodes */
4647 op_Mulh = get_op_Mulh();
4656 * Pre-transform all unknown and noreg nodes.
4658 static void ia32_pretransform_node(void)
4660 ia32_code_gen_t *cg = env_cg;
4662 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4663 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4664 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4665 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4666 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4667 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4672 * Walker, checks if all ia32 nodes producing more than one result have their
4673 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4675 static void add_missing_keep_walker(ir_node *node, void *data)
4678 unsigned found_projs = 0;
4679 const ir_edge_t *edge;
4680 ir_mode *mode = get_irn_mode(node);
4685 if (!is_ia32_irn(node))
4688 n_outs = get_ia32_n_res(node);
4691 if (is_ia32_SwitchJmp(node))
4694 assert(n_outs < (int) sizeof(unsigned) * 8);
4695 foreach_out_edge(node, edge) {
4696 ir_node *proj = get_edge_src_irn(edge);
4699 /* The node could be kept */
4703 if (get_irn_mode(proj) == mode_M)
4706 pn = get_Proj_proj(proj);
4707 assert(pn < n_outs);
4708 found_projs |= 1 << pn;
4712 /* are keeps missing? */
4714 for (i = 0; i < n_outs; ++i) {
4717 const arch_register_req_t *req;
4718 const arch_register_class_t *cls;
4720 if (found_projs & (1 << i)) {
4724 req = get_ia32_out_req(node, i);
4729 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4733 block = get_nodes_block(node);
4734 in[0] = new_r_Proj(current_ir_graph, block, node,
4735 arch_register_class_mode(cls), i);
4736 if (last_keep != NULL) {
4737 be_Keep_add_node(last_keep, cls, in[0]);
4739 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4740 if (sched_is_scheduled(node)) {
4741 sched_add_after(node, last_keep);
4748 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4751 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4753 ir_graph *irg = be_get_birg_irg(cg->birg);
4754 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4757 /* do the transformation */
4758 void ia32_transform_graph(ia32_code_gen_t *cg)
4762 register_transformers();
4764 initial_fpcw = NULL;
4766 BE_TIMER_PUSH(t_heights);
4767 heights = heights_new(cg->irg);
4768 BE_TIMER_POP(t_heights);
4769 ia32_calculate_non_address_mode_nodes(cg->birg);
4771 /* the transform phase is not safe for CSE (yet) because several nodes get
4772 * attributes set after their creation */
4773 cse_last = get_opt_cse();
4776 be_transform_graph(cg->birg, ia32_pretransform_node);
4778 set_opt_cse(cse_last);
4780 ia32_free_non_address_mode_nodes();
4781 heights_free(heights);
4785 void ia32_init_transform(void)
4787 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");