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
35 #include "irgraph_t.h"
40 #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_nodes_attr.h"
62 #include "ia32_transform.h"
63 #include "ia32_new_nodes.h"
64 #include "ia32_map_regs.h"
65 #include "ia32_dbg_stat.h"
66 #include "ia32_optimize.h"
67 #include "ia32_util.h"
68 #include "ia32_address_mode.h"
69 #include "ia32_architecture.h"
71 #include "gen_ia32_regalloc_if.h"
73 #define SFP_SIGN "0x80000000"
74 #define DFP_SIGN "0x8000000000000000"
75 #define SFP_ABS "0x7FFFFFFF"
76 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
77 #define DFP_INTMAX "9223372036854775807"
79 #define TP_SFP_SIGN "ia32_sfp_sign"
80 #define TP_DFP_SIGN "ia32_dfp_sign"
81 #define TP_SFP_ABS "ia32_sfp_abs"
82 #define TP_DFP_ABS "ia32_dfp_abs"
83 #define TP_INT_MAX "ia32_int_max"
85 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
86 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
87 #define ENT_SFP_ABS "IA32_SFP_ABS"
88 #define ENT_DFP_ABS "IA32_DFP_ABS"
89 #define ENT_INT_MAX "IA32_INT_MAX"
91 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
92 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
94 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
96 /** hold the current code generator during transformation */
97 static ia32_code_gen_t *env_cg = NULL;
98 static ir_node *initial_fpcw = NULL;
99 static heights_t *heights = NULL;
101 extern ir_op *get_op_Mulh(void);
103 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
104 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
105 ir_node *op1, ir_node *op2);
107 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
108 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
109 ir_node *op1, ir_node *op2, ir_node *flags);
111 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
112 ir_node *block, ir_node *op1, ir_node *op2);
114 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
115 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
118 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
119 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
121 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
122 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
123 ir_node *op1, ir_node *op2, ir_node *fpcw);
125 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
126 ir_node *block, ir_node *op);
128 static ir_node *try_create_Immediate(ir_node *node,
129 char immediate_constraint_type);
131 static ir_node *create_immediate_or_transform(ir_node *node,
132 char immediate_constraint_type);
134 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
135 dbg_info *dbgi, ir_node *block,
136 ir_node *op, ir_node *orig_node);
139 * Return true if a mode can be stored in the GP register set
141 static INLINE int mode_needs_gp_reg(ir_mode *mode) {
142 if(mode == mode_fpcw)
144 if(get_mode_size_bits(mode) > 32)
146 return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b;
150 * creates a unique ident by adding a number to a tag
152 * @param tag the tag string, must contain a %d if a number
155 static ident *unique_id(const char *tag)
157 static unsigned id = 0;
160 snprintf(str, sizeof(str), tag, ++id);
161 return new_id_from_str(str);
165 * Get a primitive type for a mode.
167 static ir_type *get_prim_type(pmap *types, ir_mode *mode)
169 pmap_entry *e = pmap_find(types, mode);
174 snprintf(buf, sizeof(buf), "prim_type_%s", get_mode_name(mode));
175 res = new_type_primitive(new_id_from_str(buf), mode);
176 set_type_alignment_bytes(res, 16);
177 pmap_insert(types, mode, res);
185 * Get an atomic entity that is initialized with a tarval
187 static ir_entity *create_float_const_entity(ir_node *cnst)
189 ia32_isa_t *isa = env_cg->isa;
190 tarval *tv = get_Const_tarval(cnst);
191 pmap_entry *e = pmap_find(isa->tv_ent, tv);
196 ir_mode *mode = get_irn_mode(cnst);
197 ir_type *tp = get_Const_type(cnst);
198 if (tp == firm_unknown_type)
199 tp = get_prim_type(isa->types, mode);
201 res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);
203 set_entity_ld_ident(res, get_entity_ident(res));
204 set_entity_visibility(res, visibility_local);
205 set_entity_variability(res, variability_constant);
206 set_entity_allocation(res, allocation_static);
208 /* we create a new entity here: It's initialization must resist on the
210 rem = current_ir_graph;
211 current_ir_graph = get_const_code_irg();
212 set_atomic_ent_value(res, new_Const_type(tv, tp));
213 current_ir_graph = rem;
215 pmap_insert(isa->tv_ent, tv, res);
223 static int is_Const_0(ir_node *node) {
224 return is_Const(node) && is_Const_null(node);
227 static int is_Const_1(ir_node *node) {
228 return is_Const(node) && is_Const_one(node);
231 static int is_Const_Minus_1(ir_node *node) {
232 return is_Const(node) && is_Const_all_one(node);
236 * returns true if constant can be created with a simple float command
238 static int is_simple_x87_Const(ir_node *node)
240 tarval *tv = get_Const_tarval(node);
242 if(tarval_is_null(tv) || tarval_is_one(tv))
245 /* TODO: match all the other float constants */
250 * Transforms a Const.
252 static ir_node *gen_Const(ir_node *node) {
253 ir_graph *irg = current_ir_graph;
254 ir_node *old_block = get_nodes_block(node);
255 ir_node *block = be_transform_node(old_block);
256 dbg_info *dbgi = get_irn_dbg_info(node);
257 ir_mode *mode = get_irn_mode(node);
259 assert(is_Const(node));
261 if (mode_is_float(mode)) {
263 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
264 ir_node *nomem = new_NoMem();
268 if (ia32_cg_config.use_sse2) {
269 if (is_Const_null(node)) {
270 load = new_rd_ia32_xZero(dbgi, irg, block);
271 set_ia32_ls_mode(load, mode);
274 floatent = create_float_const_entity(node);
276 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
278 set_ia32_op_type(load, ia32_AddrModeS);
279 set_ia32_am_sc(load, floatent);
280 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
281 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
284 if (is_Const_null(node)) {
285 load = new_rd_ia32_vfldz(dbgi, irg, block);
287 } else if (is_Const_one(node)) {
288 load = new_rd_ia32_vfld1(dbgi, irg, block);
291 floatent = create_float_const_entity(node);
293 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
294 set_ia32_op_type(load, ia32_AddrModeS);
295 set_ia32_am_sc(load, floatent);
296 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
297 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
299 set_ia32_ls_mode(load, mode);
302 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
304 /* Const Nodes before the initial IncSP are a bad idea, because
305 * they could be spilled and we have no SP ready at that point yet.
306 * So add a dependency to the initial frame pointer calculation to
307 * avoid that situation.
309 if (get_irg_start_block(irg) == block) {
310 add_irn_dep(load, get_irg_frame(irg));
313 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
317 tarval *tv = get_Const_tarval(node);
320 tv = tarval_convert_to(tv, mode_Iu);
322 if(tv == get_tarval_bad() || tv == get_tarval_undefined()
324 panic("couldn't convert constant tarval (%+F)", node);
326 val = get_tarval_long(tv);
328 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
329 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
332 if (get_irg_start_block(irg) == block) {
333 add_irn_dep(cnst, get_irg_frame(irg));
341 * Transforms a SymConst.
343 static ir_node *gen_SymConst(ir_node *node) {
344 ir_graph *irg = current_ir_graph;
345 ir_node *old_block = get_nodes_block(node);
346 ir_node *block = be_transform_node(old_block);
347 dbg_info *dbgi = get_irn_dbg_info(node);
348 ir_mode *mode = get_irn_mode(node);
351 if (mode_is_float(mode)) {
352 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
353 ir_node *nomem = new_NoMem();
355 if (ia32_cg_config.use_sse2)
356 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
358 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
359 set_ia32_am_sc(cnst, get_SymConst_entity(node));
360 set_ia32_use_frame(cnst);
364 if(get_SymConst_kind(node) != symconst_addr_ent) {
365 panic("backend only support symconst_addr_ent (at %+F)", node);
367 entity = get_SymConst_entity(node);
368 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
371 /* Const Nodes before the initial IncSP are a bad idea, because
372 * they could be spilled and we have no SP ready at that point yet
374 if (get_irg_start_block(irg) == block) {
375 add_irn_dep(cnst, get_irg_frame(irg));
378 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
383 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
384 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
385 static const struct {
387 const char *ent_name;
388 const char *cnst_str;
391 } names [ia32_known_const_max] = {
392 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
393 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
394 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
395 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
396 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
398 static ir_entity *ent_cache[ia32_known_const_max];
400 const char *tp_name, *ent_name, *cnst_str;
408 ent_name = names[kct].ent_name;
409 if (! ent_cache[kct]) {
410 tp_name = names[kct].tp_name;
411 cnst_str = names[kct].cnst_str;
413 switch (names[kct].mode) {
414 case 0: mode = mode_Iu; break;
415 case 1: mode = mode_Lu; break;
416 default: mode = mode_F; break;
418 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
419 tp = new_type_primitive(new_id_from_str(tp_name), mode);
420 /* set the specified alignment */
421 set_type_alignment_bytes(tp, names[kct].align);
423 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
425 set_entity_ld_ident(ent, get_entity_ident(ent));
426 set_entity_visibility(ent, visibility_local);
427 set_entity_variability(ent, variability_constant);
428 set_entity_allocation(ent, allocation_static);
430 /* we create a new entity here: It's initialization must resist on the
432 rem = current_ir_graph;
433 current_ir_graph = get_const_code_irg();
434 cnst = new_Const(mode, tv);
435 current_ir_graph = rem;
437 set_atomic_ent_value(ent, cnst);
439 /* cache the entry */
440 ent_cache[kct] = ent;
443 return ent_cache[kct];
448 * Prints the old node name on cg obst and returns a pointer to it.
450 const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
451 ia32_isa_t *isa = (ia32_isa_t *)cg->arch_env->isa;
453 lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
454 obstack_1grow(isa->name_obst, 0);
455 return obstack_finish(isa->name_obst);
460 * return true if the node is a Proj(Load) and could be used in source address
461 * mode for another node. Will return only true if the @p other node is not
462 * dependent on the memory of the Load (for binary operations use the other
463 * input here, for unary operations use NULL).
465 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
466 ir_node *other, ir_node *other2)
468 ir_mode *mode = get_irn_mode(node);
472 /* float constants are always available */
473 if(is_Const(node) && mode_is_float(mode)) {
474 if(!is_simple_x87_Const(node))
476 if(get_irn_n_edges(node) > 1)
483 load = get_Proj_pred(node);
484 pn = get_Proj_proj(node);
485 if(!is_Load(load) || pn != pn_Load_res)
487 if(get_nodes_block(load) != block)
489 /* we only use address mode if we're the only user of the load */
490 if(get_irn_n_edges(node) > 1)
492 /* in some edge cases with address mode we might reach the load normally
493 * and through some AM sequence, if it is already materialized then we
494 * can't create an AM node from it */
495 if(be_is_transformed(node))
498 /* don't do AM if other node inputs depend on the load (via mem-proj) */
499 if(other != NULL && get_nodes_block(other) == block
500 && heights_reachable_in_block(heights, other, load))
502 if(other2 != NULL && get_nodes_block(other2) == block
503 && heights_reachable_in_block(heights, other2, load))
509 typedef struct ia32_address_mode_t ia32_address_mode_t;
510 struct ia32_address_mode_t {
514 ia32_op_type_t op_type;
518 unsigned commutative : 1;
519 unsigned ins_permuted : 1;
522 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
524 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
526 /* construct load address */
527 memset(addr, 0, sizeof(addr[0]));
528 ia32_create_address_mode(addr, ptr, /*force=*/0);
530 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
531 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
532 addr->mem = be_transform_node(mem);
535 static void build_address(ia32_address_mode_t *am, ir_node *node)
537 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
538 ia32_address_t *addr = &am->addr;
545 ir_entity *entity = create_float_const_entity(node);
546 addr->base = noreg_gp;
547 addr->index = noreg_gp;
548 addr->mem = new_NoMem();
549 addr->symconst_ent = entity;
551 am->ls_mode = get_irn_mode(node);
552 am->pinned = op_pin_state_floats;
556 load = get_Proj_pred(node);
557 ptr = get_Load_ptr(load);
558 mem = get_Load_mem(load);
559 new_mem = be_transform_node(mem);
560 am->pinned = get_irn_pinned(load);
561 am->ls_mode = get_Load_mode(load);
562 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
564 /* construct load address */
565 ia32_create_address_mode(addr, ptr, /*force=*/0);
567 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
568 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
572 static void set_address(ir_node *node, const ia32_address_t *addr)
574 set_ia32_am_scale(node, addr->scale);
575 set_ia32_am_sc(node, addr->symconst_ent);
576 set_ia32_am_offs_int(node, addr->offset);
577 if(addr->symconst_sign)
578 set_ia32_am_sc_sign(node);
580 set_ia32_use_frame(node);
581 set_ia32_frame_ent(node, addr->frame_entity);
584 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
586 set_address(node, &am->addr);
588 set_ia32_op_type(node, am->op_type);
589 set_ia32_ls_mode(node, am->ls_mode);
590 if(am->pinned == op_pin_state_pinned && get_irn_pinned(node) != op_pin_state_pinned) {
591 set_irn_pinned(node, am->pinned);
594 set_ia32_commutative(node);
598 * Check, if a given node is a Down-Conv, ie. a integer Conv
599 * from a mode with a mode with more bits to a mode with lesser bits.
600 * Moreover, we return only true if the node has not more than 1 user.
602 * @param node the node
603 * @return non-zero if node is a Down-Conv
605 static int is_downconv(const ir_node *node)
613 /* we only want to skip the conv when we're the only user
614 * (not optimal but for now...)
616 if(get_irn_n_edges(node) > 1)
619 src_mode = get_irn_mode(get_Conv_op(node));
620 dest_mode = get_irn_mode(node);
621 return mode_needs_gp_reg(src_mode)
622 && mode_needs_gp_reg(dest_mode)
623 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
626 /* Skip all Down-Conv's on a given node and return the resulting node. */
627 ir_node *ia32_skip_downconv(ir_node *node) {
628 while (is_downconv(node))
629 node = get_Conv_op(node);
635 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
637 ir_mode *mode = get_irn_mode(node);
642 if(mode_is_signed(mode)) {
647 block = get_nodes_block(node);
648 dbgi = get_irn_dbg_info(node);
650 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
655 * matches operands of a node into ia32 addressing/operand modes. This covers
656 * usage of source address mode, immediates, operations with non 32-bit modes,
658 * The resulting data is filled into the @p am struct. block is the block
659 * of the node whose arguments are matched. op1, op2 are the first and second
660 * input that are matched (op1 may be NULL). other_op is another unrelated
661 * input that is not matched! but which is needed sometimes to check if AM
662 * for op1/op2 is legal.
663 * @p flags describes the supported modes of the operation in detail.
665 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
666 ir_node *op1, ir_node *op2, ir_node *other_op,
669 ia32_address_t *addr = &am->addr;
670 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
673 ir_mode *mode = get_irn_mode(op2);
675 unsigned commutative;
676 int use_am_and_immediates;
678 int mode_bits = get_mode_size_bits(mode);
680 memset(am, 0, sizeof(am[0]));
682 commutative = (flags & match_commutative) != 0;
683 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
684 use_am = (flags & match_am) != 0;
685 use_immediate = (flags & match_immediate) != 0;
686 assert(!use_am_and_immediates || use_immediate);
689 assert(!commutative || op1 != NULL);
690 assert(use_am || !(flags & match_8bit_am));
691 assert(use_am || !(flags & match_16bit_am));
694 if (! (flags & match_8bit_am))
696 /* we don't automatically add upconvs yet */
697 assert((flags & match_mode_neutral) || (flags & match_8bit));
698 } else if(mode_bits == 16) {
699 if(! (flags & match_16bit_am))
701 /* we don't automatically add upconvs yet */
702 assert((flags & match_mode_neutral) || (flags & match_16bit));
705 /* we can simply skip downconvs for mode neutral nodes: the upper bits
706 * can be random for these operations */
707 if(flags & match_mode_neutral) {
708 op2 = ia32_skip_downconv(op2);
710 op1 = ia32_skip_downconv(op1);
714 /* match immediates. firm nodes are normalized: constants are always on the
717 if(! (flags & match_try_am) && use_immediate) {
718 new_op2 = try_create_Immediate(op2, 0);
722 && use_am && ia32_use_source_address_mode(block, op2, op1, other_op)) {
723 build_address(am, op2);
724 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
725 if(mode_is_float(mode)) {
726 new_op2 = ia32_new_NoReg_vfp(env_cg);
730 am->op_type = ia32_AddrModeS;
731 } else if(commutative && (new_op2 == NULL || use_am_and_immediates) &&
733 && ia32_use_source_address_mode(block, op1, op2, other_op)) {
735 build_address(am, op1);
737 if(mode_is_float(mode)) {
738 noreg = ia32_new_NoReg_vfp(env_cg);
743 if(new_op2 != NULL) {
746 new_op1 = be_transform_node(op2);
748 am->ins_permuted = 1;
750 am->op_type = ia32_AddrModeS;
752 if(flags & match_try_am) {
755 am->op_type = ia32_Normal;
759 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
761 new_op2 = be_transform_node(op2);
762 am->op_type = ia32_Normal;
763 am->ls_mode = get_irn_mode(op2);
764 if(flags & match_mode_neutral)
765 am->ls_mode = mode_Iu;
767 if(addr->base == NULL)
768 addr->base = noreg_gp;
769 if(addr->index == NULL)
770 addr->index = noreg_gp;
771 if(addr->mem == NULL)
772 addr->mem = new_NoMem();
774 am->new_op1 = new_op1;
775 am->new_op2 = new_op2;
776 am->commutative = commutative;
779 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
781 ir_graph *irg = current_ir_graph;
785 if(am->mem_proj == NULL)
788 /* we have to create a mode_T so the old MemProj can attach to us */
789 mode = get_irn_mode(node);
790 load = get_Proj_pred(am->mem_proj);
792 mark_irn_visited(load);
793 be_set_transformed_node(load, node);
796 set_irn_mode(node, mode_T);
797 return new_rd_Proj(NULL, irg, get_nodes_block(node), node, mode, pn_ia32_res);
804 * Construct a standard binary operation, set AM and immediate if required.
806 * @param op1 The first operand
807 * @param op2 The second operand
808 * @param func The node constructor function
809 * @return The constructed ia32 node.
811 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
812 construct_binop_func *func, match_flags_t flags)
814 ir_node *block = get_nodes_block(node);
815 ir_node *new_block = be_transform_node(block);
816 ir_graph *irg = current_ir_graph;
817 dbg_info *dbgi = get_irn_dbg_info(node);
819 ia32_address_mode_t am;
820 ia32_address_t *addr = &am.addr;
822 match_arguments(&am, block, op1, op2, NULL, flags);
824 new_node = func(dbgi, irg, new_block, addr->base, addr->index, addr->mem,
825 am.new_op1, am.new_op2);
826 set_am_attributes(new_node, &am);
827 /* we can't use source address mode anymore when using immediates */
828 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
829 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
830 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
832 new_node = fix_mem_proj(new_node, &am);
839 n_ia32_l_binop_right,
840 n_ia32_l_binop_eflags
842 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
843 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
844 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
845 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_left, n_Sbb_left)
846 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_right, n_Sbb_right)
847 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
850 * Construct a binary operation which also consumes the eflags.
852 * @param node The node to transform
853 * @param func The node constructor function
854 * @param flags The match flags
855 * @return The constructor ia32 node
857 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
860 ir_node *src_block = get_nodes_block(node);
861 ir_node *block = be_transform_node(src_block);
862 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
863 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
864 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
865 ir_node *new_eflags = be_transform_node(eflags);
866 ir_graph *irg = current_ir_graph;
867 dbg_info *dbgi = get_irn_dbg_info(node);
869 ia32_address_mode_t am;
870 ia32_address_t *addr = &am.addr;
872 match_arguments(&am, src_block, op1, op2, NULL, flags);
874 new_node = func(dbgi, irg, block, addr->base, addr->index,
875 addr->mem, am.new_op1, am.new_op2, new_eflags);
876 set_am_attributes(new_node, &am);
877 /* we can't use source address mode anymore when using immediates */
878 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
879 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
880 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
882 new_node = fix_mem_proj(new_node, &am);
887 static ir_node *get_fpcw(void)
890 if(initial_fpcw != NULL)
893 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
894 &ia32_fp_cw_regs[REG_FPCW]);
895 initial_fpcw = be_transform_node(fpcw);
901 * Construct a standard binary operation, set AM and immediate if required.
903 * @param op1 The first operand
904 * @param op2 The second operand
905 * @param func The node constructor function
906 * @return The constructed ia32 node.
908 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
909 construct_binop_float_func *func,
912 ir_graph *irg = current_ir_graph;
913 dbg_info *dbgi = get_irn_dbg_info(node);
914 ir_node *block = get_nodes_block(node);
915 ir_node *new_block = be_transform_node(block);
916 ir_mode *mode = get_irn_mode(node);
918 ia32_address_mode_t am;
919 ia32_address_t *addr = &am.addr;
921 /* cannot use addresmode with long double on x87 */
922 if (get_mode_size_bits(mode) > 64)
925 match_arguments(&am, block, op1, op2, NULL, flags);
927 new_node = func(dbgi, irg, new_block, addr->base, addr->index, addr->mem,
928 am.new_op1, am.new_op2, get_fpcw());
929 set_am_attributes(new_node, &am);
931 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
933 new_node = fix_mem_proj(new_node, &am);
939 * Construct a shift/rotate binary operation, sets AM and immediate if required.
941 * @param op1 The first operand
942 * @param op2 The second operand
943 * @param func The node constructor function
944 * @return The constructed ia32 node.
946 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
947 construct_shift_func *func,
950 dbg_info *dbgi = get_irn_dbg_info(node);
951 ir_graph *irg = current_ir_graph;
952 ir_node *block = get_nodes_block(node);
953 ir_node *new_block = be_transform_node(block);
958 assert(! mode_is_float(get_irn_mode(node)));
959 assert(flags & match_immediate);
960 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
962 if(flags & match_mode_neutral) {
963 op1 = ia32_skip_downconv(op1);
965 new_op1 = be_transform_node(op1);
967 /* the shift amount can be any mode that is bigger than 5 bits, since all
968 * other bits are ignored anyway */
969 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
970 op2 = get_Conv_op(op2);
971 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
973 new_op2 = create_immediate_or_transform(op2, 0);
975 new_node = func(dbgi, irg, new_block, new_op1, new_op2);
976 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
978 /* lowered shift instruction may have a dependency operand, handle it here */
979 if (get_irn_arity(node) == 3) {
980 /* we have a dependency */
981 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
982 add_irn_dep(new_node, new_dep);
990 * Construct a standard unary operation, set AM and immediate if required.
992 * @param op The operand
993 * @param func The node constructor function
994 * @return The constructed ia32 node.
996 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
999 ir_graph *irg = current_ir_graph;
1000 dbg_info *dbgi = get_irn_dbg_info(node);
1001 ir_node *block = get_nodes_block(node);
1002 ir_node *new_block = be_transform_node(block);
1006 assert(flags == 0 || flags == match_mode_neutral);
1007 if(flags & match_mode_neutral) {
1008 op = ia32_skip_downconv(op);
1011 new_op = be_transform_node(op);
1012 new_node = func(dbgi, irg, new_block, new_op);
1014 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1019 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1020 ia32_address_t *addr)
1022 ir_graph *irg = current_ir_graph;
1023 ir_node *base = addr->base;
1024 ir_node *index = addr->index;
1028 base = ia32_new_NoReg_gp(env_cg);
1030 base = be_transform_node(base);
1034 index = ia32_new_NoReg_gp(env_cg);
1036 index = be_transform_node(index);
1039 res = new_rd_ia32_Lea(dbgi, irg, block, base, index);
1040 set_address(res, addr);
1045 static int am_has_immediates(const ia32_address_t *addr)
1047 return addr->offset != 0 || addr->symconst_ent != NULL
1048 || addr->frame_entity || addr->use_frame;
1052 * Creates an ia32 Add.
1054 * @return the created ia32 Add node
1056 static ir_node *gen_Add(ir_node *node) {
1057 ir_graph *irg = current_ir_graph;
1058 dbg_info *dbgi = get_irn_dbg_info(node);
1059 ir_node *block = get_nodes_block(node);
1060 ir_node *new_block = be_transform_node(block);
1061 ir_node *op1 = get_Add_left(node);
1062 ir_node *op2 = get_Add_right(node);
1063 ir_mode *mode = get_irn_mode(node);
1065 ir_node *add_immediate_op;
1066 ia32_address_t addr;
1067 ia32_address_mode_t am;
1069 if (mode_is_float(mode)) {
1070 if (ia32_cg_config.use_sse2)
1071 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1072 match_commutative | match_am);
1074 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1075 match_commutative | match_am);
1078 ia32_mark_non_am(node);
1080 op2 = ia32_skip_downconv(op2);
1081 op1 = ia32_skip_downconv(op1);
1085 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1086 * 1. Add with immediate -> Lea
1087 * 2. Add with possible source address mode -> Add
1088 * 3. Otherwise -> Lea
1090 memset(&addr, 0, sizeof(addr));
1091 ia32_create_address_mode(&addr, node, /*force=*/1);
1092 add_immediate_op = NULL;
1094 if(addr.base == NULL && addr.index == NULL) {
1095 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1096 addr.symconst_sign, addr.offset);
1097 add_irn_dep(new_node, get_irg_frame(irg));
1098 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1101 /* add with immediate? */
1102 if(addr.index == NULL) {
1103 add_immediate_op = addr.base;
1104 } else if(addr.base == NULL && addr.scale == 0) {
1105 add_immediate_op = addr.index;
1108 if(add_immediate_op != NULL) {
1109 if(!am_has_immediates(&addr)) {
1110 #ifdef DEBUG_libfirm
1111 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1114 return be_transform_node(add_immediate_op);
1117 new_node = create_lea_from_address(dbgi, new_block, &addr);
1118 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1122 /* test if we can use source address mode */
1123 match_arguments(&am, block, op1, op2, NULL, match_commutative
1124 | match_mode_neutral | match_am | match_immediate | match_try_am);
1126 /* construct an Add with source address mode */
1127 if (am.op_type == ia32_AddrModeS) {
1128 ia32_address_t *am_addr = &am.addr;
1129 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1130 am_addr->index, am_addr->mem, am.new_op1,
1132 set_am_attributes(new_node, &am);
1133 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1135 new_node = fix_mem_proj(new_node, &am);
1140 /* otherwise construct a lea */
1141 new_node = create_lea_from_address(dbgi, new_block, &addr);
1142 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1147 * Creates an ia32 Mul.
1149 * @return the created ia32 Mul node
1151 static ir_node *gen_Mul(ir_node *node) {
1152 ir_node *op1 = get_Mul_left(node);
1153 ir_node *op2 = get_Mul_right(node);
1154 ir_mode *mode = get_irn_mode(node);
1157 if (mode_is_float(mode)) {
1158 if (ia32_cg_config.use_sse2)
1159 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1160 match_commutative | match_am);
1162 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1163 match_commutative | match_am);
1166 /* for the lower 32bit of the result it doesn't matter whether we use
1167 * signed or unsigned multiplication so we use IMul as it has fewer
1169 flags = match_commutative | match_am | match_mode_neutral | match_immediate;
1170 if (ia32_cg_config.use_imul_mem_imm32)
1171 flags |= match_am_and_immediates;
1172 return gen_binop(node, op1, op2, new_rd_ia32_IMul, flags);
1176 * Creates an ia32 Mulh.
1177 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1178 * this result while Mul returns the lower 32 bit.
1180 * @return the created ia32 Mulh node
1182 static ir_node *gen_Mulh(ir_node *node)
1184 ir_node *block = get_nodes_block(node);
1185 ir_node *new_block = be_transform_node(block);
1186 ir_graph *irg = current_ir_graph;
1187 dbg_info *dbgi = get_irn_dbg_info(node);
1188 ir_mode *mode = get_irn_mode(node);
1189 ir_node *op1 = get_Mulh_left(node);
1190 ir_node *op2 = get_Mulh_right(node);
1191 ir_node *proj_res_high;
1193 ia32_address_mode_t am;
1194 ia32_address_t *addr = &am.addr;
1196 assert(!mode_is_float(mode) && "Mulh with float not supported");
1197 assert(get_mode_size_bits(mode) == 32);
1199 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1201 if (mode_is_signed(mode)) {
1202 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1203 addr->index, addr->mem, am.new_op1,
1206 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1207 addr->index, addr->mem, am.new_op1,
1211 set_am_attributes(new_node, &am);
1212 /* we can't use source address mode anymore when using immediates */
1213 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1214 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1215 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1217 assert(get_irn_mode(new_node) == mode_T);
1219 fix_mem_proj(new_node, &am);
1221 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1222 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1223 mode_Iu, pn_ia32_IMul1OP_res_high);
1225 return proj_res_high;
1231 * Creates an ia32 And.
1233 * @return The created ia32 And node
1235 static ir_node *gen_And(ir_node *node) {
1236 ir_node *op1 = get_And_left(node);
1237 ir_node *op2 = get_And_right(node);
1238 assert(! mode_is_float(get_irn_mode(node)));
1240 /* is it a zero extension? */
1241 if (is_Const(op2)) {
1242 tarval *tv = get_Const_tarval(op2);
1243 long v = get_tarval_long(tv);
1245 if (v == 0xFF || v == 0xFFFF) {
1246 dbg_info *dbgi = get_irn_dbg_info(node);
1247 ir_node *block = get_nodes_block(node);
1254 assert(v == 0xFFFF);
1257 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1263 return gen_binop(node, op1, op2, new_rd_ia32_And,
1264 match_commutative | match_mode_neutral | match_am
1271 * Creates an ia32 Or.
1273 * @return The created ia32 Or node
1275 static ir_node *gen_Or(ir_node *node) {
1276 ir_node *op1 = get_Or_left(node);
1277 ir_node *op2 = get_Or_right(node);
1279 assert (! mode_is_float(get_irn_mode(node)));
1280 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1281 | match_mode_neutral | match_am | match_immediate);
1287 * Creates an ia32 Eor.
1289 * @return The created ia32 Eor node
1291 static ir_node *gen_Eor(ir_node *node) {
1292 ir_node *op1 = get_Eor_left(node);
1293 ir_node *op2 = get_Eor_right(node);
1295 assert(! mode_is_float(get_irn_mode(node)));
1296 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1297 | match_mode_neutral | match_am | match_immediate);
1302 * Creates an ia32 Sub.
1304 * @return The created ia32 Sub node
1306 static ir_node *gen_Sub(ir_node *node) {
1307 ir_node *op1 = get_Sub_left(node);
1308 ir_node *op2 = get_Sub_right(node);
1309 ir_mode *mode = get_irn_mode(node);
1311 if (mode_is_float(mode)) {
1312 if (ia32_cg_config.use_sse2)
1313 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1315 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1320 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1324 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1325 | match_am | match_immediate);
1329 * Generates an ia32 DivMod with additional infrastructure for the
1330 * register allocator if needed.
1332 static ir_node *create_Div(ir_node *node)
1334 ir_graph *irg = current_ir_graph;
1335 dbg_info *dbgi = get_irn_dbg_info(node);
1336 ir_node *block = get_nodes_block(node);
1337 ir_node *new_block = be_transform_node(block);
1344 ir_node *sign_extension;
1345 ia32_address_mode_t am;
1346 ia32_address_t *addr = &am.addr;
1348 /* the upper bits have random contents for smaller modes */
1349 switch (get_irn_opcode(node)) {
1351 op1 = get_Div_left(node);
1352 op2 = get_Div_right(node);
1353 mem = get_Div_mem(node);
1354 mode = get_Div_resmode(node);
1357 op1 = get_Mod_left(node);
1358 op2 = get_Mod_right(node);
1359 mem = get_Mod_mem(node);
1360 mode = get_Mod_resmode(node);
1363 op1 = get_DivMod_left(node);
1364 op2 = get_DivMod_right(node);
1365 mem = get_DivMod_mem(node);
1366 mode = get_DivMod_resmode(node);
1369 panic("invalid divmod node %+F", node);
1372 match_arguments(&am, block, op1, op2, NULL, match_am);
1374 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1375 is the memory of the consumed address. We can have only the second op as address
1376 in Div nodes, so check only op2. */
1377 if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1378 new_mem = be_transform_node(mem);
1379 if(!is_NoMem(addr->mem)) {
1383 new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1386 new_mem = addr->mem;
1389 if (mode_is_signed(mode)) {
1390 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1391 add_irn_dep(produceval, get_irg_frame(irg));
1392 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1395 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1396 addr->index, new_mem, am.new_op1,
1397 sign_extension, am.new_op2);
1399 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1400 add_irn_dep(sign_extension, get_irg_frame(irg));
1402 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1403 addr->index, new_mem, am.new_op1,
1404 sign_extension, am.new_op2);
1407 set_irn_pinned(new_node, get_irn_pinned(node));
1409 set_am_attributes(new_node, &am);
1410 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1412 new_node = fix_mem_proj(new_node, &am);
1418 static ir_node *gen_Mod(ir_node *node) {
1419 return create_Div(node);
1422 static ir_node *gen_Div(ir_node *node) {
1423 return create_Div(node);
1426 static ir_node *gen_DivMod(ir_node *node) {
1427 return create_Div(node);
1433 * Creates an ia32 floating Div.
1435 * @return The created ia32 xDiv node
1437 static ir_node *gen_Quot(ir_node *node)
1439 ir_node *op1 = get_Quot_left(node);
1440 ir_node *op2 = get_Quot_right(node);
1442 if (ia32_cg_config.use_sse2) {
1443 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1445 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1451 * Creates an ia32 Shl.
1453 * @return The created ia32 Shl node
1455 static ir_node *gen_Shl(ir_node *node) {
1456 ir_node *left = get_Shl_left(node);
1457 ir_node *right = get_Shl_right(node);
1459 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1460 match_mode_neutral | match_immediate);
1464 * Creates an ia32 Shr.
1466 * @return The created ia32 Shr node
1468 static ir_node *gen_Shr(ir_node *node) {
1469 ir_node *left = get_Shr_left(node);
1470 ir_node *right = get_Shr_right(node);
1472 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1478 * Creates an ia32 Sar.
1480 * @return The created ia32 Shrs node
1482 static ir_node *gen_Shrs(ir_node *node) {
1483 ir_node *left = get_Shrs_left(node);
1484 ir_node *right = get_Shrs_right(node);
1485 ir_mode *mode = get_irn_mode(node);
1487 if(is_Const(right) && mode == mode_Is) {
1488 tarval *tv = get_Const_tarval(right);
1489 long val = get_tarval_long(tv);
1491 /* this is a sign extension */
1492 ir_graph *irg = current_ir_graph;
1493 dbg_info *dbgi = get_irn_dbg_info(node);
1494 ir_node *block = be_transform_node(get_nodes_block(node));
1496 ir_node *new_op = be_transform_node(op);
1497 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1498 add_irn_dep(pval, get_irg_frame(irg));
1500 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1504 /* 8 or 16 bit sign extension? */
1505 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1506 ir_node *shl_left = get_Shl_left(left);
1507 ir_node *shl_right = get_Shl_right(left);
1508 if(is_Const(shl_right)) {
1509 tarval *tv1 = get_Const_tarval(right);
1510 tarval *tv2 = get_Const_tarval(shl_right);
1511 if(tv1 == tv2 && tarval_is_long(tv1)) {
1512 long val = get_tarval_long(tv1);
1513 if(val == 16 || val == 24) {
1514 dbg_info *dbgi = get_irn_dbg_info(node);
1515 ir_node *block = get_nodes_block(node);
1525 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1534 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1540 * Creates an ia32 RotL.
1542 * @param op1 The first operator
1543 * @param op2 The second operator
1544 * @return The created ia32 RotL node
1546 static ir_node *gen_RotL(ir_node *node, ir_node *op1, ir_node *op2) {
1547 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1553 * Creates an ia32 RotR.
1554 * NOTE: There is no RotR with immediate because this would always be a RotL
1555 * "imm-mode_size_bits" which can be pre-calculated.
1557 * @param op1 The first operator
1558 * @param op2 The second operator
1559 * @return The created ia32 RotR node
1561 static ir_node *gen_RotR(ir_node *node, ir_node *op1, ir_node *op2) {
1562 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1568 * Creates an ia32 RotR or RotL (depending on the found pattern).
1570 * @return The created ia32 RotL or RotR node
1572 static ir_node *gen_Rot(ir_node *node) {
1573 ir_node *rotate = NULL;
1574 ir_node *op1 = get_Rot_left(node);
1575 ir_node *op2 = get_Rot_right(node);
1577 /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
1578 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1579 that means we can create a RotR instead of an Add and a RotL */
1581 if (get_irn_op(op2) == op_Add) {
1583 ir_node *left = get_Add_left(add);
1584 ir_node *right = get_Add_right(add);
1585 if (is_Const(right)) {
1586 tarval *tv = get_Const_tarval(right);
1587 ir_mode *mode = get_irn_mode(node);
1588 long bits = get_mode_size_bits(mode);
1590 if (get_irn_op(left) == op_Minus &&
1591 tarval_is_long(tv) &&
1592 get_tarval_long(tv) == bits &&
1595 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1596 rotate = gen_RotR(node, op1, get_Minus_op(left));
1601 if (rotate == NULL) {
1602 rotate = gen_RotL(node, op1, op2);
1611 * Transforms a Minus node.
1613 * @return The created ia32 Minus node
1615 static ir_node *gen_Minus(ir_node *node)
1617 ir_node *op = get_Minus_op(node);
1618 ir_node *block = be_transform_node(get_nodes_block(node));
1619 ir_graph *irg = current_ir_graph;
1620 dbg_info *dbgi = get_irn_dbg_info(node);
1621 ir_mode *mode = get_irn_mode(node);
1626 if (mode_is_float(mode)) {
1627 ir_node *new_op = be_transform_node(op);
1628 if (ia32_cg_config.use_sse2) {
1629 /* TODO: non-optimal... if we have many xXors, then we should
1630 * rather create a load for the const and use that instead of
1631 * several AM nodes... */
1632 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1633 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1634 ir_node *nomem = new_rd_NoMem(irg);
1636 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1637 nomem, new_op, noreg_xmm);
1639 size = get_mode_size_bits(mode);
1640 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1642 set_ia32_am_sc(new_node, ent);
1643 set_ia32_op_type(new_node, ia32_AddrModeS);
1644 set_ia32_ls_mode(new_node, mode);
1646 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1649 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1652 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1658 * Transforms a Not node.
1660 * @return The created ia32 Not node
1662 static ir_node *gen_Not(ir_node *node) {
1663 ir_node *op = get_Not_op(node);
1665 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1666 assert (! mode_is_float(get_irn_mode(node)));
1668 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1674 * Transforms an Abs node.
1676 * @return The created ia32 Abs node
1678 static ir_node *gen_Abs(ir_node *node)
1680 ir_node *block = get_nodes_block(node);
1681 ir_node *new_block = be_transform_node(block);
1682 ir_node *op = get_Abs_op(node);
1683 ir_graph *irg = current_ir_graph;
1684 dbg_info *dbgi = get_irn_dbg_info(node);
1685 ir_mode *mode = get_irn_mode(node);
1686 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1687 ir_node *nomem = new_NoMem();
1693 if (mode_is_float(mode)) {
1694 new_op = be_transform_node(op);
1696 if (ia32_cg_config.use_sse2) {
1697 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1698 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1699 nomem, new_op, noreg_fp);
1701 size = get_mode_size_bits(mode);
1702 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1704 set_ia32_am_sc(new_node, ent);
1706 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1708 set_ia32_op_type(new_node, ia32_AddrModeS);
1709 set_ia32_ls_mode(new_node, mode);
1711 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1712 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1715 ir_node *xor, *pval, *sign_extension;
1717 if (get_mode_size_bits(mode) == 32) {
1718 new_op = be_transform_node(op);
1720 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1723 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1724 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1727 add_irn_dep(pval, get_irg_frame(irg));
1728 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1730 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1731 nomem, new_op, sign_extension);
1732 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1734 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1735 nomem, xor, sign_extension);
1736 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1742 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1744 ir_graph *irg = current_ir_graph;
1752 /* we have a Cmp as input */
1754 ir_node *pred = get_Proj_pred(node);
1756 flags = be_transform_node(pred);
1757 *pnc_out = get_Proj_proj(node);
1762 /* a mode_b value, we have to compare it against 0 */
1763 dbgi = get_irn_dbg_info(node);
1764 new_block = be_transform_node(get_nodes_block(node));
1765 new_op = be_transform_node(node);
1766 noreg = ia32_new_NoReg_gp(env_cg);
1767 nomem = new_NoMem();
1768 flags = new_rd_ia32_Test(dbgi, irg, new_block, noreg, noreg, nomem,
1769 new_op, new_op, 0, 0);
1770 *pnc_out = pn_Cmp_Lg;
1775 * Transforms a Load.
1777 * @return the created ia32 Load node
1779 static ir_node *gen_Load(ir_node *node) {
1780 ir_node *old_block = get_nodes_block(node);
1781 ir_node *block = be_transform_node(old_block);
1782 ir_node *ptr = get_Load_ptr(node);
1783 ir_node *mem = get_Load_mem(node);
1784 ir_node *new_mem = be_transform_node(mem);
1787 ir_graph *irg = current_ir_graph;
1788 dbg_info *dbgi = get_irn_dbg_info(node);
1789 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1790 ir_mode *mode = get_Load_mode(node);
1793 ia32_address_t addr;
1795 /* construct load address */
1796 memset(&addr, 0, sizeof(addr));
1797 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1804 base = be_transform_node(base);
1810 index = be_transform_node(index);
1813 if (mode_is_float(mode)) {
1814 if (ia32_cg_config.use_sse2) {
1815 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1817 res_mode = mode_xmm;
1819 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1821 res_mode = mode_vfp;
1824 assert(mode != mode_b);
1826 /* create a conv node with address mode for smaller modes */
1827 if(get_mode_size_bits(mode) < 32) {
1828 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1829 new_mem, noreg, mode);
1831 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1836 set_irn_pinned(new_node, get_irn_pinned(node));
1837 set_ia32_op_type(new_node, ia32_AddrModeS);
1838 set_ia32_ls_mode(new_node, mode);
1839 set_address(new_node, &addr);
1841 if(get_irn_pinned(node) == op_pin_state_floats) {
1842 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1845 /* make sure we are scheduled behind the initial IncSP/Barrier
1846 * to avoid spills being placed before it
1848 if (block == get_irg_start_block(irg)) {
1849 add_irn_dep(new_node, get_irg_frame(irg));
1852 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1857 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1858 ir_node *ptr, ir_node *other)
1865 /* we only use address mode if we're the only user of the load */
1866 if(get_irn_n_edges(node) > 1)
1869 load = get_Proj_pred(node);
1872 if(get_nodes_block(load) != block)
1875 /* Store should be attached to the load */
1876 if(!is_Proj(mem) || get_Proj_pred(mem) != load)
1878 /* store should have the same pointer as the load */
1879 if(get_Load_ptr(load) != ptr)
1882 /* don't do AM if other node inputs depend on the load (via mem-proj) */
1883 if(other != NULL && get_nodes_block(other) == block
1884 && heights_reachable_in_block(heights, other, load))
1890 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1891 ir_node *mem, ir_node *ptr, ir_mode *mode,
1892 construct_binop_dest_func *func,
1893 construct_binop_dest_func *func8bit,
1894 match_flags_t flags)
1896 ir_node *src_block = get_nodes_block(node);
1898 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1899 ir_graph *irg = current_ir_graph;
1904 ia32_address_mode_t am;
1905 ia32_address_t *addr = &am.addr;
1906 memset(&am, 0, sizeof(am));
1908 assert(flags & match_dest_am);
1909 assert(flags & match_immediate); /* there is no destam node without... */
1910 commutative = (flags & match_commutative) != 0;
1912 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
1913 build_address(&am, op1);
1914 new_op = create_immediate_or_transform(op2, 0);
1915 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1916 build_address(&am, op2);
1917 new_op = create_immediate_or_transform(op1, 0);
1922 if(addr->base == NULL)
1923 addr->base = noreg_gp;
1924 if(addr->index == NULL)
1925 addr->index = noreg_gp;
1926 if(addr->mem == NULL)
1927 addr->mem = new_NoMem();
1929 dbgi = get_irn_dbg_info(node);
1930 block = be_transform_node(src_block);
1931 if(get_mode_size_bits(mode) == 8) {
1932 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
1935 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
1938 set_address(new_node, addr);
1939 set_ia32_op_type(new_node, ia32_AddrModeD);
1940 set_ia32_ls_mode(new_node, mode);
1941 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1946 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
1947 ir_node *ptr, ir_mode *mode,
1948 construct_unop_dest_func *func)
1950 ir_graph *irg = current_ir_graph;
1951 ir_node *src_block = get_nodes_block(node);
1955 ia32_address_mode_t am;
1956 ia32_address_t *addr = &am.addr;
1957 memset(&am, 0, sizeof(am));
1959 if(!use_dest_am(src_block, op, mem, ptr, NULL))
1962 build_address(&am, op);
1964 dbgi = get_irn_dbg_info(node);
1965 block = be_transform_node(src_block);
1966 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
1967 set_address(new_node, addr);
1968 set_ia32_op_type(new_node, ia32_AddrModeD);
1969 set_ia32_ls_mode(new_node, mode);
1970 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1975 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
1976 ir_mode *mode = get_irn_mode(node);
1977 ir_node *psi_true = get_Psi_val(node, 0);
1978 ir_node *psi_default = get_Psi_default(node);
1989 ia32_address_t addr;
1991 if(get_mode_size_bits(mode) != 8)
1994 if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
1996 } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2002 build_address_ptr(&addr, ptr, mem);
2004 irg = current_ir_graph;
2005 dbgi = get_irn_dbg_info(node);
2006 block = get_nodes_block(node);
2007 new_block = be_transform_node(block);
2008 cond = get_Psi_cond(node, 0);
2009 flags = get_flags_node(cond, &pnc);
2010 new_mem = be_transform_node(mem);
2011 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2012 addr.index, addr.mem, flags, pnc, negated);
2013 set_address(new_node, &addr);
2014 set_ia32_op_type(new_node, ia32_AddrModeD);
2015 set_ia32_ls_mode(new_node, mode);
2016 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2021 static ir_node *try_create_dest_am(ir_node *node) {
2022 ir_node *val = get_Store_value(node);
2023 ir_node *mem = get_Store_mem(node);
2024 ir_node *ptr = get_Store_ptr(node);
2025 ir_mode *mode = get_irn_mode(val);
2026 unsigned bits = get_mode_size_bits(mode);
2031 /* handle only GP modes for now... */
2032 if(!mode_needs_gp_reg(mode))
2036 /* store must be the only user of the val node */
2037 if(get_irn_n_edges(val) > 1)
2039 /* skip pointless convs */
2041 ir_node *conv_op = get_Conv_op(val);
2042 ir_mode *pred_mode = get_irn_mode(conv_op);
2043 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2051 /* value must be in the same block */
2052 if(get_nodes_block(node) != get_nodes_block(val))
2055 switch(get_irn_opcode(val)) {
2057 op1 = get_Add_left(val);
2058 op2 = get_Add_right(val);
2059 if(is_Const_1(op2)) {
2060 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2061 new_rd_ia32_IncMem);
2063 } else if(is_Const_Minus_1(op2)) {
2064 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2065 new_rd_ia32_DecMem);
2068 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2069 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2070 match_dest_am | match_commutative |
2074 op1 = get_Sub_left(val);
2075 op2 = get_Sub_right(val);
2077 ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2080 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2081 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2082 match_dest_am | match_immediate |
2086 op1 = get_And_left(val);
2087 op2 = get_And_right(val);
2088 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2089 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2090 match_dest_am | match_commutative |
2094 op1 = get_Or_left(val);
2095 op2 = get_Or_right(val);
2096 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2097 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2098 match_dest_am | match_commutative |
2102 op1 = get_Eor_left(val);
2103 op2 = get_Eor_right(val);
2104 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2105 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2106 match_dest_am | match_commutative |
2110 op1 = get_Shl_left(val);
2111 op2 = get_Shl_right(val);
2112 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2113 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2114 match_dest_am | match_immediate);
2117 op1 = get_Shr_left(val);
2118 op2 = get_Shr_right(val);
2119 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2120 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2121 match_dest_am | match_immediate);
2124 op1 = get_Shrs_left(val);
2125 op2 = get_Shrs_right(val);
2126 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2127 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2128 match_dest_am | match_immediate);
2131 op1 = get_Rot_left(val);
2132 op2 = get_Rot_right(val);
2133 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2134 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2135 match_dest_am | match_immediate);
2137 /* TODO: match ROR patterns... */
2139 new_node = try_create_SetMem(val, ptr, mem);
2142 op1 = get_Minus_op(val);
2143 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2146 /* should be lowered already */
2147 assert(mode != mode_b);
2148 op1 = get_Not_op(val);
2149 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2155 if(new_node != NULL) {
2156 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2157 get_irn_pinned(node) == op_pin_state_pinned) {
2158 set_irn_pinned(new_node, op_pin_state_pinned);
2165 static int is_float_to_int32_conv(const ir_node *node)
2167 ir_mode *mode = get_irn_mode(node);
2171 if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode))
2176 conv_op = get_Conv_op(node);
2177 conv_mode = get_irn_mode(conv_op);
2179 if(!mode_is_float(conv_mode))
2186 * Transforms a Store.
2188 * @return the created ia32 Store node
2190 static ir_node *gen_Store(ir_node *node)
2192 ir_node *block = get_nodes_block(node);
2193 ir_node *new_block = be_transform_node(block);
2194 ir_node *ptr = get_Store_ptr(node);
2195 ir_node *val = get_Store_value(node);
2196 ir_node *mem = get_Store_mem(node);
2197 ir_graph *irg = current_ir_graph;
2198 dbg_info *dbgi = get_irn_dbg_info(node);
2199 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2200 ir_mode *mode = get_irn_mode(val);
2203 ia32_address_t addr;
2205 /* check for destination address mode */
2206 new_node = try_create_dest_am(node);
2207 if(new_node != NULL)
2210 /* construct store address */
2211 memset(&addr, 0, sizeof(addr));
2212 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2214 if(addr.base == NULL) {
2217 addr.base = be_transform_node(addr.base);
2220 if(addr.index == NULL) {
2223 addr.index = be_transform_node(addr.index);
2225 addr.mem = be_transform_node(mem);
2227 if (mode_is_float(mode)) {
2228 /* convs (and strict-convs) before stores are unnecessary if the mode
2230 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2231 val = get_Conv_op(val);
2233 new_val = be_transform_node(val);
2234 if (ia32_cg_config.use_sse2) {
2235 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2236 addr.index, addr.mem, new_val);
2238 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2239 addr.index, addr.mem, new_val, mode);
2241 } else if(is_float_to_int32_conv(val)) {
2242 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2243 val = get_Conv_op(val);
2245 /* convs (and strict-convs) before stores are unnecessary if the mode
2247 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2248 val = get_Conv_op(val);
2250 new_val = be_transform_node(val);
2252 new_node = new_rd_ia32_vfist(dbgi, irg, new_block, addr.base,
2253 addr.index, addr.mem, new_val, trunc_mode);
2255 new_val = create_immediate_or_transform(val, 0);
2256 assert(mode != mode_b);
2258 if (get_mode_size_bits(mode) == 8) {
2259 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2260 addr.index, addr.mem, new_val);
2262 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2263 addr.index, addr.mem, new_val);
2267 set_irn_pinned(new_node, get_irn_pinned(node));
2268 set_ia32_op_type(new_node, ia32_AddrModeD);
2269 set_ia32_ls_mode(new_node, mode);
2271 set_address(new_node, &addr);
2272 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2277 static ir_node *create_Switch(ir_node *node)
2279 ir_graph *irg = current_ir_graph;
2280 dbg_info *dbgi = get_irn_dbg_info(node);
2281 ir_node *block = be_transform_node(get_nodes_block(node));
2282 ir_node *sel = get_Cond_selector(node);
2283 ir_node *new_sel = be_transform_node(sel);
2284 int switch_min = INT_MAX;
2285 int switch_max = INT_MIN;
2286 long default_pn = get_Cond_defaultProj(node);
2288 const ir_edge_t *edge;
2290 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2292 /* determine the smallest switch case value */
2293 foreach_out_edge(node, edge) {
2294 ir_node *proj = get_edge_src_irn(edge);
2295 long pn = get_Proj_proj(proj);
2296 if(pn == default_pn)
2305 if((unsigned) (switch_max - switch_min) > 256000) {
2306 panic("Size of switch %+F bigger than 256000", node);
2309 if (switch_min != 0) {
2310 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2312 /* if smallest switch case is not 0 we need an additional sub */
2313 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2314 add_ia32_am_offs_int(new_sel, -switch_min);
2315 set_ia32_op_type(new_sel, ia32_AddrModeS);
2317 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2320 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2321 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2326 static ir_node *gen_Cond(ir_node *node) {
2327 ir_node *block = get_nodes_block(node);
2328 ir_node *new_block = be_transform_node(block);
2329 ir_graph *irg = current_ir_graph;
2330 dbg_info *dbgi = get_irn_dbg_info(node);
2331 ir_node *sel = get_Cond_selector(node);
2332 ir_mode *sel_mode = get_irn_mode(sel);
2333 ir_node *flags = NULL;
2337 if (sel_mode != mode_b) {
2338 return create_Switch(node);
2341 /* we get flags from a cmp */
2342 flags = get_flags_node(sel, &pnc);
2344 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2345 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2353 * Transforms a CopyB node.
2355 * @return The transformed node.
2357 static ir_node *gen_CopyB(ir_node *node) {
2358 ir_node *block = be_transform_node(get_nodes_block(node));
2359 ir_node *src = get_CopyB_src(node);
2360 ir_node *new_src = be_transform_node(src);
2361 ir_node *dst = get_CopyB_dst(node);
2362 ir_node *new_dst = be_transform_node(dst);
2363 ir_node *mem = get_CopyB_mem(node);
2364 ir_node *new_mem = be_transform_node(mem);
2365 ir_node *res = NULL;
2366 ir_graph *irg = current_ir_graph;
2367 dbg_info *dbgi = get_irn_dbg_info(node);
2368 int size = get_type_size_bytes(get_CopyB_type(node));
2371 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2372 /* then we need the size explicitly in ECX. */
2373 if (size >= 32 * 4) {
2374 rem = size & 0x3; /* size % 4 */
2377 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2378 add_irn_dep(res, get_irg_frame(irg));
2380 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2383 ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2386 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2389 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2394 static ir_node *gen_be_Copy(ir_node *node)
2396 ir_node *new_node = be_duplicate_node(node);
2397 ir_mode *mode = get_irn_mode(new_node);
2399 if (mode_needs_gp_reg(mode)) {
2400 set_irn_mode(new_node, mode_Iu);
2406 static ir_node *create_Fucom(ir_node *node)
2408 ir_graph *irg = current_ir_graph;
2409 dbg_info *dbgi = get_irn_dbg_info(node);
2410 ir_node *block = get_nodes_block(node);
2411 ir_node *new_block = be_transform_node(block);
2412 ir_node *left = get_Cmp_left(node);
2413 ir_node *new_left = be_transform_node(left);
2414 ir_node *right = get_Cmp_right(node);
2418 if(ia32_cg_config.use_fucomi) {
2419 new_right = be_transform_node(right);
2420 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2422 set_ia32_commutative(new_node);
2423 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2425 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2426 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2429 new_right = be_transform_node(right);
2430 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2434 set_ia32_commutative(new_node);
2436 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2438 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2439 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2445 static ir_node *create_Ucomi(ir_node *node)
2447 ir_graph *irg = current_ir_graph;
2448 dbg_info *dbgi = get_irn_dbg_info(node);
2449 ir_node *src_block = get_nodes_block(node);
2450 ir_node *new_block = be_transform_node(src_block);
2451 ir_node *left = get_Cmp_left(node);
2452 ir_node *right = get_Cmp_right(node);
2454 ia32_address_mode_t am;
2455 ia32_address_t *addr = &am.addr;
2457 match_arguments(&am, src_block, left, right, NULL,
2458 match_commutative | match_am);
2460 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2461 addr->mem, am.new_op1, am.new_op2,
2463 set_am_attributes(new_node, &am);
2465 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2467 new_node = fix_mem_proj(new_node, &am);
2473 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2474 * to fold an and into a test node
2476 static int can_fold_test_and(ir_node *node)
2478 const ir_edge_t *edge;
2480 /** we can only have eq and lg projs */
2481 foreach_out_edge(node, edge) {
2482 ir_node *proj = get_edge_src_irn(edge);
2483 pn_Cmp pnc = get_Proj_proj(proj);
2484 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2491 static ir_node *gen_Cmp(ir_node *node)
2493 ir_graph *irg = current_ir_graph;
2494 dbg_info *dbgi = get_irn_dbg_info(node);
2495 ir_node *block = get_nodes_block(node);
2496 ir_node *new_block = be_transform_node(block);
2497 ir_node *left = get_Cmp_left(node);
2498 ir_node *right = get_Cmp_right(node);
2499 ir_mode *cmp_mode = get_irn_mode(left);
2501 ia32_address_mode_t am;
2502 ia32_address_t *addr = &am.addr;
2505 if(mode_is_float(cmp_mode)) {
2506 if (ia32_cg_config.use_sse2) {
2507 return create_Ucomi(node);
2509 return create_Fucom(node);
2513 assert(mode_needs_gp_reg(cmp_mode));
2515 /* we prefer the Test instruction where possible except cases where
2516 * we can use SourceAM */
2517 cmp_unsigned = !mode_is_signed(cmp_mode);
2518 if (is_Const_0(right)) {
2520 get_irn_n_edges(left) == 1 &&
2521 can_fold_test_and(node)) {
2522 /* Test(and_left, and_right) */
2523 ir_node *and_left = get_And_left(left);
2524 ir_node *and_right = get_And_right(left);
2525 ir_mode *mode = get_irn_mode(and_left);
2527 match_arguments(&am, block, and_left, and_right, NULL,
2529 match_am | match_8bit_am | match_16bit_am |
2530 match_am_and_immediates | match_immediate |
2531 match_8bit | match_16bit);
2532 if (get_mode_size_bits(mode) == 8) {
2533 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2534 addr->index, addr->mem, am.new_op1,
2535 am.new_op2, am.ins_permuted,
2538 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2539 addr->index, addr->mem, am.new_op1,
2540 am.new_op2, am.ins_permuted, cmp_unsigned);
2543 match_arguments(&am, block, NULL, left, NULL,
2544 match_am | match_8bit_am | match_16bit_am |
2545 match_8bit | match_16bit);
2546 if (am.op_type == ia32_AddrModeS) {
2548 ir_node *imm_zero = try_create_Immediate(right, 0);
2549 if (get_mode_size_bits(cmp_mode) == 8) {
2550 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2551 addr->index, addr->mem, am.new_op2,
2552 imm_zero, am.ins_permuted,
2555 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2556 addr->index, addr->mem, am.new_op2,
2557 imm_zero, am.ins_permuted, cmp_unsigned);
2560 /* Test(left, left) */
2561 if (get_mode_size_bits(cmp_mode) == 8) {
2562 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2563 addr->index, addr->mem, am.new_op2,
2564 am.new_op2, am.ins_permuted,
2567 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2568 addr->index, addr->mem, am.new_op2,
2569 am.new_op2, am.ins_permuted,
2575 /* Cmp(left, right) */
2576 match_arguments(&am, block, left, right, NULL,
2577 match_commutative | match_am | match_8bit_am |
2578 match_16bit_am | match_am_and_immediates |
2579 match_immediate | match_8bit | match_16bit);
2580 if (get_mode_size_bits(cmp_mode) == 8) {
2581 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2582 addr->index, addr->mem, am.new_op1,
2583 am.new_op2, am.ins_permuted,
2586 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2587 addr->index, addr->mem, am.new_op1,
2588 am.new_op2, am.ins_permuted, cmp_unsigned);
2591 set_am_attributes(new_node, &am);
2592 assert(cmp_mode != NULL);
2593 set_ia32_ls_mode(new_node, cmp_mode);
2595 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2597 new_node = fix_mem_proj(new_node, &am);
2602 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2605 ir_graph *irg = current_ir_graph;
2606 dbg_info *dbgi = get_irn_dbg_info(node);
2607 ir_node *block = get_nodes_block(node);
2608 ir_node *new_block = be_transform_node(block);
2609 ir_node *val_true = get_Psi_val(node, 0);
2610 ir_node *val_false = get_Psi_default(node);
2612 match_flags_t match_flags;
2613 ia32_address_mode_t am;
2614 ia32_address_t *addr;
2616 assert(ia32_cg_config.use_cmov);
2617 assert(mode_needs_gp_reg(get_irn_mode(val_true)));
2621 match_flags = match_commutative | match_am | match_16bit_am |
2624 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2626 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2627 addr->mem, am.new_op1, am.new_op2, new_flags,
2628 am.ins_permuted, pnc);
2629 set_am_attributes(new_node, &am);
2631 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2633 new_node = fix_mem_proj(new_node, &am);
2640 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2641 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2644 ir_graph *irg = current_ir_graph;
2645 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2646 ir_node *nomem = new_NoMem();
2647 ir_mode *mode = get_irn_mode(orig_node);
2650 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2651 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2653 /* we might need to conv the result up */
2654 if(get_mode_size_bits(mode) > 8) {
2655 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2656 nomem, new_node, mode_Bu);
2657 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2664 * Transforms a Psi node into CMov.
2666 * @return The transformed node.
2668 static ir_node *gen_Psi(ir_node *node)
2670 dbg_info *dbgi = get_irn_dbg_info(node);
2671 ir_node *block = get_nodes_block(node);
2672 ir_node *new_block = be_transform_node(block);
2673 ir_node *psi_true = get_Psi_val(node, 0);
2674 ir_node *psi_default = get_Psi_default(node);
2675 ir_node *cond = get_Psi_cond(node, 0);
2676 ir_node *flags = NULL;
2680 assert(get_Psi_n_conds(node) == 1);
2681 assert(get_irn_mode(cond) == mode_b);
2682 assert(mode_needs_gp_reg(get_irn_mode(node)));
2684 flags = get_flags_node(cond, &pnc);
2686 if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2687 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 0);
2688 } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2689 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 1);
2691 new_node = create_CMov(node, cond, flags, pnc);
2698 * Create a conversion from x87 state register to general purpose.
2700 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
2701 ir_node *block = be_transform_node(get_nodes_block(node));
2702 ir_node *op = get_Conv_op(node);
2703 ir_node *new_op = be_transform_node(op);
2704 ia32_code_gen_t *cg = env_cg;
2705 ir_graph *irg = current_ir_graph;
2706 dbg_info *dbgi = get_irn_dbg_info(node);
2707 ir_node *noreg = ia32_new_NoReg_gp(cg);
2708 ir_node *trunc_mode = ia32_new_Fpu_truncate(cg);
2709 ir_mode *mode = get_irn_mode(node);
2710 ir_node *fist, *load;
2713 fist = new_rd_ia32_vfist(dbgi, irg, block, get_irg_frame(irg), noreg,
2714 new_NoMem(), new_op, trunc_mode);
2716 set_irn_pinned(fist, op_pin_state_floats);
2717 set_ia32_use_frame(fist);
2718 set_ia32_op_type(fist, ia32_AddrModeD);
2720 assert(get_mode_size_bits(mode) <= 32);
2721 /* exception we can only store signed 32 bit integers, so for unsigned
2722 we store a 64bit (signed) integer and load the lower bits */
2723 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
2724 set_ia32_ls_mode(fist, mode_Ls);
2726 set_ia32_ls_mode(fist, mode_Is);
2728 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
2731 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, fist);
2733 set_irn_pinned(load, op_pin_state_floats);
2734 set_ia32_use_frame(load);
2735 set_ia32_op_type(load, ia32_AddrModeS);
2736 set_ia32_ls_mode(load, mode_Is);
2737 if(get_ia32_ls_mode(fist) == mode_Ls) {
2738 ia32_attr_t *attr = get_ia32_attr(load);
2739 attr->data.need_64bit_stackent = 1;
2741 ia32_attr_t *attr = get_ia32_attr(load);
2742 attr->data.need_32bit_stackent = 1;
2744 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
2746 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
2750 * Creates a x87 strict Conv by placing a Sore and a Load
2752 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
2754 ir_node *block = get_nodes_block(node);
2755 ir_graph *irg = current_ir_graph;
2756 dbg_info *dbgi = get_irn_dbg_info(node);
2757 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2758 ir_node *nomem = new_NoMem();
2759 ir_node *frame = get_irg_frame(irg);
2760 ir_node *store, *load;
2763 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
2765 set_ia32_use_frame(store);
2766 set_ia32_op_type(store, ia32_AddrModeD);
2767 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2769 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
2771 set_ia32_use_frame(load);
2772 set_ia32_op_type(load, ia32_AddrModeS);
2773 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
2775 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
2779 static ir_node *create_Immediate(ir_entity *symconst, int symconst_sign, long val)
2781 ir_graph *irg = current_ir_graph;
2782 ir_node *start_block = get_irg_start_block(irg);
2783 ir_node *immediate = new_rd_ia32_Immediate(NULL, irg, start_block,
2784 symconst, symconst_sign, val);
2785 arch_set_irn_register(env_cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]);
2791 * Create a conversion from general purpose to x87 register
2793 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
2794 ir_node *src_block = get_nodes_block(node);
2795 ir_node *block = be_transform_node(src_block);
2796 ir_graph *irg = current_ir_graph;
2797 dbg_info *dbgi = get_irn_dbg_info(node);
2798 ir_node *op = get_Conv_op(node);
2799 ir_node *new_op = NULL;
2803 ir_mode *store_mode;
2809 /* fild can use source AM if the operand is a signed 32bit integer */
2810 if (src_mode == mode_Is) {
2811 ia32_address_mode_t am;
2813 match_arguments(&am, src_block, NULL, op, NULL,
2814 match_am | match_try_am);
2815 if (am.op_type == ia32_AddrModeS) {
2816 ia32_address_t *addr = &am.addr;
2818 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
2819 addr->index, addr->mem);
2820 new_node = new_r_Proj(irg, block, fild, mode_vfp,
2823 set_am_attributes(fild, &am);
2824 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
2826 fix_mem_proj(fild, &am);
2831 if(new_op == NULL) {
2832 new_op = be_transform_node(op);
2835 noreg = ia32_new_NoReg_gp(env_cg);
2836 nomem = new_NoMem();
2837 mode = get_irn_mode(op);
2839 /* first convert to 32 bit signed if necessary */
2840 src_bits = get_mode_size_bits(src_mode);
2841 if (src_bits == 8) {
2842 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
2844 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
2846 } else if (src_bits < 32) {
2847 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
2849 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
2853 assert(get_mode_size_bits(mode) == 32);
2856 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
2859 set_ia32_use_frame(store);
2860 set_ia32_op_type(store, ia32_AddrModeD);
2861 set_ia32_ls_mode(store, mode_Iu);
2863 /* exception for 32bit unsigned, do a 64bit spill+load */
2864 if(!mode_is_signed(mode)) {
2867 ir_node *zero_const = create_Immediate(NULL, 0, 0);
2869 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
2870 get_irg_frame(irg), noreg, nomem,
2873 set_ia32_use_frame(zero_store);
2874 set_ia32_op_type(zero_store, ia32_AddrModeD);
2875 add_ia32_am_offs_int(zero_store, 4);
2876 set_ia32_ls_mode(zero_store, mode_Iu);
2881 store = new_rd_Sync(dbgi, irg, block, 2, in);
2882 store_mode = mode_Ls;
2884 store_mode = mode_Is;
2888 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
2890 set_ia32_use_frame(fild);
2891 set_ia32_op_type(fild, ia32_AddrModeS);
2892 set_ia32_ls_mode(fild, store_mode);
2894 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
2900 * Create a conversion from one integer mode into another one
2902 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
2903 dbg_info *dbgi, ir_node *block, ir_node *op,
2906 ir_graph *irg = current_ir_graph;
2907 int src_bits = get_mode_size_bits(src_mode);
2908 int tgt_bits = get_mode_size_bits(tgt_mode);
2909 ir_node *new_block = be_transform_node(block);
2911 ir_mode *smaller_mode;
2913 ia32_address_mode_t am;
2914 ia32_address_t *addr = &am.addr;
2917 if (src_bits < tgt_bits) {
2918 smaller_mode = src_mode;
2919 smaller_bits = src_bits;
2921 smaller_mode = tgt_mode;
2922 smaller_bits = tgt_bits;
2925 #ifdef DEBUG_libfirm
2927 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
2932 match_arguments(&am, block, NULL, op, NULL,
2933 match_8bit | match_16bit |
2934 match_am | match_8bit_am | match_16bit_am);
2935 if (smaller_bits == 8) {
2936 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
2937 addr->index, addr->mem, am.new_op2,
2940 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
2941 addr->index, addr->mem, am.new_op2,
2944 set_am_attributes(new_node, &am);
2945 /* match_arguments assume that out-mode = in-mode, this isn't true here
2947 set_ia32_ls_mode(new_node, smaller_mode);
2948 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2949 new_node = fix_mem_proj(new_node, &am);
2954 * Transforms a Conv node.
2956 * @return The created ia32 Conv node
2958 static ir_node *gen_Conv(ir_node *node) {
2959 ir_node *block = get_nodes_block(node);
2960 ir_node *new_block = be_transform_node(block);
2961 ir_node *op = get_Conv_op(node);
2962 ir_node *new_op = NULL;
2963 ir_graph *irg = current_ir_graph;
2964 dbg_info *dbgi = get_irn_dbg_info(node);
2965 ir_mode *src_mode = get_irn_mode(op);
2966 ir_mode *tgt_mode = get_irn_mode(node);
2967 int src_bits = get_mode_size_bits(src_mode);
2968 int tgt_bits = get_mode_size_bits(tgt_mode);
2969 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2970 ir_node *nomem = new_rd_NoMem(irg);
2971 ir_node *res = NULL;
2973 if (src_mode == mode_b) {
2974 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
2975 /* nothing to do, we already model bools as 0/1 ints */
2976 return be_transform_node(op);
2979 if (src_mode == tgt_mode) {
2980 if (get_Conv_strict(node)) {
2981 if (ia32_cg_config.use_sse2) {
2982 /* when we are in SSE mode, we can kill all strict no-op conversion */
2983 return be_transform_node(op);
2986 /* this should be optimized already, but who knows... */
2987 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
2988 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
2989 return be_transform_node(op);
2993 if (mode_is_float(src_mode)) {
2994 new_op = be_transform_node(op);
2995 /* we convert from float ... */
2996 if (mode_is_float(tgt_mode)) {
2997 if(src_mode == mode_E && tgt_mode == mode_D
2998 && !get_Conv_strict(node)) {
2999 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3004 if (ia32_cg_config.use_sse2) {
3005 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3006 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3008 set_ia32_ls_mode(res, tgt_mode);
3010 if(get_Conv_strict(node)) {
3011 res = gen_x87_strict_conv(tgt_mode, new_op);
3012 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3015 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3020 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3021 if (ia32_cg_config.use_sse2) {
3022 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3024 set_ia32_ls_mode(res, src_mode);
3026 return gen_x87_fp_to_gp(node);
3030 /* we convert from int ... */
3031 if (mode_is_float(tgt_mode)) {
3033 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3034 if (ia32_cg_config.use_sse2) {
3035 new_op = be_transform_node(op);
3036 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3038 set_ia32_ls_mode(res, tgt_mode);
3040 res = gen_x87_gp_to_fp(node, src_mode);
3041 if(get_Conv_strict(node)) {
3042 res = gen_x87_strict_conv(tgt_mode, res);
3043 SET_IA32_ORIG_NODE(get_Proj_pred(res),
3044 ia32_get_old_node_name(env_cg, node));
3048 } else if(tgt_mode == mode_b) {
3049 /* mode_b lowering already took care that we only have 0/1 values */
3050 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3051 src_mode, tgt_mode));
3052 return be_transform_node(op);
3055 if (src_bits == tgt_bits) {
3056 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3057 src_mode, tgt_mode));
3058 return be_transform_node(op);
3061 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3069 static int check_immediate_constraint(long val, char immediate_constraint_type)
3071 switch (immediate_constraint_type) {
3075 return val >= 0 && val <= 32;
3077 return val >= 0 && val <= 63;
3079 return val >= -128 && val <= 127;
3081 return val == 0xff || val == 0xffff;
3083 return val >= 0 && val <= 3;
3085 return val >= 0 && val <= 255;
3087 return val >= 0 && val <= 127;
3091 panic("Invalid immediate constraint found");
3095 static ir_node *try_create_Immediate(ir_node *node,
3096 char immediate_constraint_type)
3099 tarval *offset = NULL;
3100 int offset_sign = 0;
3102 ir_entity *symconst_ent = NULL;
3103 int symconst_sign = 0;
3105 ir_node *cnst = NULL;
3106 ir_node *symconst = NULL;
3109 mode = get_irn_mode(node);
3110 if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3114 if(is_Minus(node)) {
3116 node = get_Minus_op(node);
3119 if(is_Const(node)) {
3122 offset_sign = minus;
3123 } else if(is_SymConst(node)) {
3126 symconst_sign = minus;
3127 } else if(is_Add(node)) {
3128 ir_node *left = get_Add_left(node);
3129 ir_node *right = get_Add_right(node);
3130 if(is_Const(left) && is_SymConst(right)) {
3133 symconst_sign = minus;
3134 offset_sign = minus;
3135 } else if(is_SymConst(left) && is_Const(right)) {
3138 symconst_sign = minus;
3139 offset_sign = minus;
3141 } else if(is_Sub(node)) {
3142 ir_node *left = get_Sub_left(node);
3143 ir_node *right = get_Sub_right(node);
3144 if(is_Const(left) && is_SymConst(right)) {
3147 symconst_sign = !minus;
3148 offset_sign = minus;
3149 } else if(is_SymConst(left) && is_Const(right)) {
3152 symconst_sign = minus;
3153 offset_sign = !minus;
3160 offset = get_Const_tarval(cnst);
3161 if(tarval_is_long(offset)) {
3162 val = get_tarval_long(offset);
3164 ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3169 if(!check_immediate_constraint(val, immediate_constraint_type))
3172 if(symconst != NULL) {
3173 if(immediate_constraint_type != 0) {
3174 /* we need full 32bits for symconsts */
3178 /* unfortunately the assembler/linker doesn't support -symconst */
3182 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3184 symconst_ent = get_SymConst_entity(symconst);
3186 if(cnst == NULL && symconst == NULL)
3189 if(offset_sign && offset != NULL) {
3190 offset = tarval_neg(offset);
3193 new_node = create_Immediate(symconst_ent, symconst_sign, val);
3198 static ir_node *create_immediate_or_transform(ir_node *node,
3199 char immediate_constraint_type)
3201 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3202 if (new_node == NULL) {
3203 new_node = be_transform_node(node);
3208 static const arch_register_req_t no_register_req = {
3209 arch_register_req_type_none,
3210 NULL, /* regclass */
3211 NULL, /* limit bitset */
3213 0 /* different pos */
3217 * An assembler constraint.
3219 typedef struct constraint_t constraint_t;
3220 struct constraint_t {
3223 const arch_register_req_t **out_reqs;
3225 const arch_register_req_t *req;
3226 unsigned immediate_possible;
3227 char immediate_type;
3230 static void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
3232 int immediate_possible = 0;
3233 char immediate_type = 0;
3234 unsigned limited = 0;
3235 const arch_register_class_t *cls = NULL;
3236 ir_graph *irg = current_ir_graph;
3237 struct obstack *obst = get_irg_obstack(irg);
3238 arch_register_req_t *req;
3239 unsigned *limited_ptr = NULL;
3243 /* TODO: replace all the asserts with nice error messages */
3246 /* a memory constraint: no need to do anything in backend about it
3247 * (the dependencies are already respected by the memory edge of
3249 constraint->req = &no_register_req;
3261 assert(cls == NULL ||
3262 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3263 cls = &ia32_reg_classes[CLASS_ia32_gp];
3264 limited |= 1 << REG_EAX;
3267 assert(cls == NULL ||
3268 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3269 cls = &ia32_reg_classes[CLASS_ia32_gp];
3270 limited |= 1 << REG_EBX;
3273 assert(cls == NULL ||
3274 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3275 cls = &ia32_reg_classes[CLASS_ia32_gp];
3276 limited |= 1 << REG_ECX;
3279 assert(cls == NULL ||
3280 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3281 cls = &ia32_reg_classes[CLASS_ia32_gp];
3282 limited |= 1 << REG_EDX;
3285 assert(cls == NULL ||
3286 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3287 cls = &ia32_reg_classes[CLASS_ia32_gp];
3288 limited |= 1 << REG_EDI;
3291 assert(cls == NULL ||
3292 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3293 cls = &ia32_reg_classes[CLASS_ia32_gp];
3294 limited |= 1 << REG_ESI;
3297 case 'q': /* q means lower part of the regs only, this makes no
3298 * difference to Q for us (we only assigne whole registers) */
3299 assert(cls == NULL ||
3300 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3301 cls = &ia32_reg_classes[CLASS_ia32_gp];
3302 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3306 assert(cls == NULL ||
3307 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3308 cls = &ia32_reg_classes[CLASS_ia32_gp];
3309 limited |= 1 << REG_EAX | 1 << REG_EDX;
3312 assert(cls == NULL ||
3313 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3314 cls = &ia32_reg_classes[CLASS_ia32_gp];
3315 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3316 1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3323 assert(cls == NULL);
3324 cls = &ia32_reg_classes[CLASS_ia32_gp];
3330 /* TODO: mark values so the x87 simulator knows about t and u */
3331 assert(cls == NULL);
3332 cls = &ia32_reg_classes[CLASS_ia32_vfp];
3337 assert(cls == NULL);
3338 /* TODO: check that sse2 is supported */
3339 cls = &ia32_reg_classes[CLASS_ia32_xmm];
3349 assert(!immediate_possible);
3350 immediate_possible = 1;
3351 immediate_type = *c;
3355 assert(!immediate_possible);
3356 immediate_possible = 1;
3360 assert(!immediate_possible && cls == NULL);
3361 immediate_possible = 1;
3362 cls = &ia32_reg_classes[CLASS_ia32_gp];
3375 assert(constraint->is_in && "can only specify same constraint "
3378 sscanf(c, "%d%n", &same_as, &p);
3386 /* memory constraint no need to do anything in backend about it
3387 * (the dependencies are already respected by the memory edge of
3389 constraint->req = &no_register_req;
3392 case 'E': /* no float consts yet */
3393 case 'F': /* no float consts yet */
3394 case 's': /* makes no sense on x86 */
3395 case 'X': /* we can't support that in firm */
3398 case '<': /* no autodecrement on x86 */
3399 case '>': /* no autoincrement on x86 */
3400 case 'C': /* sse constant not supported yet */
3401 case 'G': /* 80387 constant not supported yet */
3402 case 'y': /* we don't support mmx registers yet */
3403 case 'Z': /* not available in 32 bit mode */
3404 case 'e': /* not available in 32 bit mode */
3405 panic("unsupported asm constraint '%c' found in (%+F)",
3406 *c, current_ir_graph);
3409 panic("unknown asm constraint '%c' found in (%+F)", *c,
3417 const arch_register_req_t *other_constr;
3419 assert(cls == NULL && "same as and register constraint not supported");
3420 assert(!immediate_possible && "same as and immediate constraint not "
3422 assert(same_as < constraint->n_outs && "wrong constraint number in "
3423 "same_as constraint");
3425 other_constr = constraint->out_reqs[same_as];
3427 req = obstack_alloc(obst, sizeof(req[0]));
3428 req->cls = other_constr->cls;
3429 req->type = arch_register_req_type_should_be_same;
3430 req->limited = NULL;
3431 req->other_same = 1U << pos;
3432 req->other_different = 0;
3434 /* switch constraints. This is because in firm we have same_as
3435 * constraints on the output constraints while in the gcc asm syntax
3436 * they are specified on the input constraints */
3437 constraint->req = other_constr;
3438 constraint->out_reqs[same_as] = req;
3439 constraint->immediate_possible = 0;
3443 if(immediate_possible && cls == NULL) {
3444 cls = &ia32_reg_classes[CLASS_ia32_gp];
3446 assert(!immediate_possible || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3447 assert(cls != NULL);
3449 if(immediate_possible) {
3450 assert(constraint->is_in
3451 && "immediate make no sense for output constraints");
3453 /* todo: check types (no float input on 'r' constrained in and such... */
3456 req = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3457 limited_ptr = (unsigned*) (req+1);
3459 req = obstack_alloc(obst, sizeof(req[0]));
3461 memset(req, 0, sizeof(req[0]));
3464 req->type = arch_register_req_type_limited;
3465 *limited_ptr = limited;
3466 req->limited = limited_ptr;
3468 req->type = arch_register_req_type_normal;
3472 constraint->req = req;
3473 constraint->immediate_possible = immediate_possible;
3474 constraint->immediate_type = immediate_type;
3477 static void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
3478 const char *clobber)
3480 ir_graph *irg = get_irn_irg(node);
3481 struct obstack *obst = get_irg_obstack(irg);
3482 const arch_register_t *reg = NULL;
3485 arch_register_req_t *req;
3486 const arch_register_class_t *cls;
3491 /* TODO: construct a hashmap instead of doing linear search for clobber
3493 for(c = 0; c < N_CLASSES; ++c) {
3494 cls = & ia32_reg_classes[c];
3495 for(r = 0; r < cls->n_regs; ++r) {
3496 const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3497 if(strcmp(temp_reg->name, clobber) == 0
3498 || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3507 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3511 assert(reg->index < 32);
3513 limited = obstack_alloc(obst, sizeof(limited[0]));
3514 *limited = 1 << reg->index;
3516 req = obstack_alloc(obst, sizeof(req[0]));
3517 memset(req, 0, sizeof(req[0]));
3518 req->type = arch_register_req_type_limited;
3520 req->limited = limited;
3522 constraint->req = req;
3523 constraint->immediate_possible = 0;
3524 constraint->immediate_type = 0;
3527 static int is_memory_op(const ir_asm_constraint *constraint)
3529 ident *id = constraint->constraint;
3530 const char *str = get_id_str(id);
3533 for(c = str; *c != '\0'; ++c) {
3542 * generates code for a ASM node
3544 static ir_node *gen_ASM(ir_node *node)
3547 ir_graph *irg = current_ir_graph;
3548 ir_node *block = get_nodes_block(node);
3549 ir_node *new_block = be_transform_node(block);
3550 dbg_info *dbgi = get_irn_dbg_info(node);
3554 int n_out_constraints;
3556 const arch_register_req_t **out_reg_reqs;
3557 const arch_register_req_t **in_reg_reqs;
3558 ia32_asm_reg_t *register_map;
3559 unsigned reg_map_size = 0;
3560 struct obstack *obst;
3561 const ir_asm_constraint *in_constraints;
3562 const ir_asm_constraint *out_constraints;
3564 constraint_t parsed_constraint;
3566 arity = get_irn_arity(node);
3567 in = alloca(arity * sizeof(in[0]));
3568 memset(in, 0, arity * sizeof(in[0]));
3570 n_out_constraints = get_ASM_n_output_constraints(node);
3571 n_clobbers = get_ASM_n_clobbers(node);
3572 out_arity = n_out_constraints + n_clobbers;
3573 /* hack to keep space for mem proj */
3577 in_constraints = get_ASM_input_constraints(node);
3578 out_constraints = get_ASM_output_constraints(node);
3579 clobbers = get_ASM_clobbers(node);
3581 /* construct output constraints */
3582 obst = get_irg_obstack(irg);
3583 out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
3584 parsed_constraint.out_reqs = out_reg_reqs;
3585 parsed_constraint.n_outs = n_out_constraints;
3586 parsed_constraint.is_in = 0;
3588 for(i = 0; i < out_arity; ++i) {
3591 if(i < n_out_constraints) {
3592 const ir_asm_constraint *constraint = &out_constraints[i];
3593 c = get_id_str(constraint->constraint);
3594 parse_asm_constraint(i, &parsed_constraint, c);
3596 if(constraint->pos > reg_map_size)
3597 reg_map_size = constraint->pos;
3599 out_reg_reqs[i] = parsed_constraint.req;
3600 } else if(i < out_arity - 1) {
3601 ident *glob_id = clobbers [i - n_out_constraints];
3602 assert(glob_id != NULL);
3603 c = get_id_str(glob_id);
3604 parse_clobber(node, i, &parsed_constraint, c);
3606 out_reg_reqs[i+1] = parsed_constraint.req;
3610 out_reg_reqs[n_out_constraints] = &no_register_req;
3612 /* construct input constraints */
3613 in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
3614 parsed_constraint.is_in = 1;
3615 for(i = 0; i < arity; ++i) {
3616 const ir_asm_constraint *constraint = &in_constraints[i];
3617 ident *constr_id = constraint->constraint;
3618 const char *c = get_id_str(constr_id);
3620 parse_asm_constraint(i, &parsed_constraint, c);
3621 in_reg_reqs[i] = parsed_constraint.req;
3623 if(constraint->pos > reg_map_size)
3624 reg_map_size = constraint->pos;
3626 if(parsed_constraint.immediate_possible) {
3627 ir_node *pred = get_irn_n(node, i);
3628 char imm_type = parsed_constraint.immediate_type;
3629 ir_node *immediate = try_create_Immediate(pred, imm_type);
3631 if(immediate != NULL) {
3638 register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
3639 memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
3641 for(i = 0; i < n_out_constraints; ++i) {
3642 const ir_asm_constraint *constraint = &out_constraints[i];
3643 unsigned pos = constraint->pos;
3645 assert(pos < reg_map_size);
3646 register_map[pos].use_input = 0;
3647 register_map[pos].valid = 1;
3648 register_map[pos].memory = is_memory_op(constraint);
3649 register_map[pos].inout_pos = i;
3650 register_map[pos].mode = constraint->mode;
3653 /* transform inputs */
3654 for(i = 0; i < arity; ++i) {
3655 const ir_asm_constraint *constraint = &in_constraints[i];
3656 unsigned pos = constraint->pos;
3657 ir_node *pred = get_irn_n(node, i);
3658 ir_node *transformed;
3660 assert(pos < reg_map_size);
3661 register_map[pos].use_input = 1;
3662 register_map[pos].valid = 1;
3663 register_map[pos].memory = is_memory_op(constraint);
3664 register_map[pos].inout_pos = i;
3665 register_map[pos].mode = constraint->mode;
3670 transformed = be_transform_node(pred);
3671 in[i] = transformed;
3674 new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
3675 get_ASM_text(node), register_map);
3677 set_ia32_out_req_all(new_node, out_reg_reqs);
3678 set_ia32_in_req_all(new_node, in_reg_reqs);
3680 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3686 * Transforms a FrameAddr into an ia32 Add.
3688 static ir_node *gen_be_FrameAddr(ir_node *node) {
3689 ir_node *block = be_transform_node(get_nodes_block(node));
3690 ir_node *op = be_get_FrameAddr_frame(node);
3691 ir_node *new_op = be_transform_node(op);
3692 ir_graph *irg = current_ir_graph;
3693 dbg_info *dbgi = get_irn_dbg_info(node);
3694 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3697 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3698 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3699 set_ia32_use_frame(new_node);
3701 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3707 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3709 static ir_node *gen_be_Return(ir_node *node) {
3710 ir_graph *irg = current_ir_graph;
3711 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3712 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3713 ir_entity *ent = get_irg_entity(irg);
3714 ir_type *tp = get_entity_type(ent);
3719 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3720 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3723 int pn_ret_val, pn_ret_mem, arity, i;
3725 assert(ret_val != NULL);
3726 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3727 return be_duplicate_node(node);
3730 res_type = get_method_res_type(tp, 0);
3732 if (! is_Primitive_type(res_type)) {
3733 return be_duplicate_node(node);
3736 mode = get_type_mode(res_type);
3737 if (! mode_is_float(mode)) {
3738 return be_duplicate_node(node);
3741 assert(get_method_n_ress(tp) == 1);
3743 pn_ret_val = get_Proj_proj(ret_val);
3744 pn_ret_mem = get_Proj_proj(ret_mem);
3746 /* get the Barrier */
3747 barrier = get_Proj_pred(ret_val);
3749 /* get result input of the Barrier */
3750 ret_val = get_irn_n(barrier, pn_ret_val);
3751 new_ret_val = be_transform_node(ret_val);
3753 /* get memory input of the Barrier */
3754 ret_mem = get_irn_n(barrier, pn_ret_mem);
3755 new_ret_mem = be_transform_node(ret_mem);
3757 frame = get_irg_frame(irg);
3759 dbgi = get_irn_dbg_info(barrier);
3760 block = be_transform_node(get_nodes_block(barrier));
3762 noreg = ia32_new_NoReg_gp(env_cg);
3764 /* store xmm0 onto stack */
3765 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3766 new_ret_mem, new_ret_val);
3767 set_ia32_ls_mode(sse_store, mode);
3768 set_ia32_op_type(sse_store, ia32_AddrModeD);
3769 set_ia32_use_frame(sse_store);
3771 /* load into x87 register */
3772 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3773 set_ia32_op_type(fld, ia32_AddrModeS);
3774 set_ia32_use_frame(fld);
3776 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3777 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3779 /* create a new barrier */
3780 arity = get_irn_arity(barrier);
3781 in = alloca(arity * sizeof(in[0]));
3782 for (i = 0; i < arity; ++i) {
3785 if (i == pn_ret_val) {
3787 } else if (i == pn_ret_mem) {
3790 ir_node *in = get_irn_n(barrier, i);
3791 new_in = be_transform_node(in);
3796 new_barrier = new_ir_node(dbgi, irg, block,
3797 get_irn_op(barrier), get_irn_mode(barrier),
3799 copy_node_attr(barrier, new_barrier);
3800 be_duplicate_deps(barrier, new_barrier);
3801 be_set_transformed_node(barrier, new_barrier);
3802 mark_irn_visited(barrier);
3804 /* transform normally */
3805 return be_duplicate_node(node);
3809 * Transform a be_AddSP into an ia32_SubSP.
3811 static ir_node *gen_be_AddSP(ir_node *node)
3813 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3814 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3816 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
3820 * Transform a be_SubSP into an ia32_AddSP
3822 static ir_node *gen_be_SubSP(ir_node *node)
3824 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3825 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3827 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
3831 * This function just sets the register for the Unknown node
3832 * as this is not done during register allocation because Unknown
3833 * is an "ignore" node.
3835 static ir_node *gen_Unknown(ir_node *node) {
3836 ir_mode *mode = get_irn_mode(node);
3838 if (mode_is_float(mode)) {
3839 if (ia32_cg_config.use_sse2) {
3840 return ia32_new_Unknown_xmm(env_cg);
3842 /* Unknown nodes are buggy in x87 sim, use zero for now... */
3843 ir_graph *irg = current_ir_graph;
3844 dbg_info *dbgi = get_irn_dbg_info(node);
3845 ir_node *block = get_irg_start_block(irg);
3846 return new_rd_ia32_vfldz(dbgi, irg, block);
3848 } else if (mode_needs_gp_reg(mode)) {
3849 return ia32_new_Unknown_gp(env_cg);
3851 panic("unsupported Unknown-Mode");
3857 * Change some phi modes
3859 static ir_node *gen_Phi(ir_node *node) {
3860 ir_node *block = be_transform_node(get_nodes_block(node));
3861 ir_graph *irg = current_ir_graph;
3862 dbg_info *dbgi = get_irn_dbg_info(node);
3863 ir_mode *mode = get_irn_mode(node);
3866 if(mode_needs_gp_reg(mode)) {
3867 /* we shouldn't have any 64bit stuff around anymore */
3868 assert(get_mode_size_bits(mode) <= 32);
3869 /* all integer operations are on 32bit registers now */
3871 } else if(mode_is_float(mode)) {
3872 if (ia32_cg_config.use_sse2) {
3879 /* phi nodes allow loops, so we use the old arguments for now
3880 * and fix this later */
3881 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3882 get_irn_in(node) + 1);
3883 copy_node_attr(node, phi);
3884 be_duplicate_deps(node, phi);
3886 be_set_transformed_node(node, phi);
3887 be_enqueue_preds(node);
3895 static ir_node *gen_IJmp(ir_node *node)
3897 ir_node *block = get_nodes_block(node);
3898 ir_node *new_block = be_transform_node(block);
3899 ir_graph *irg = current_ir_graph;
3900 dbg_info *dbgi = get_irn_dbg_info(node);
3901 ir_node *op = get_IJmp_target(node);
3903 ia32_address_mode_t am;
3904 ia32_address_t *addr = &am.addr;
3906 assert(get_irn_mode(op) == mode_P);
3908 match_arguments(&am, block, NULL, op, NULL,
3909 match_am | match_8bit_am | match_16bit_am |
3910 match_immediate | match_8bit | match_16bit);
3912 new_node = new_rd_ia32_IJmp(dbgi, irg, new_block, addr->base, addr->index,
3913 addr->mem, am.new_op2);
3914 set_am_attributes(new_node, &am);
3915 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3917 new_node = fix_mem_proj(new_node, &am);
3922 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3925 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3926 ir_node *val, ir_node *mem);
3929 * Transforms a lowered Load into a "real" one.
3931 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
3933 ir_node *block = be_transform_node(get_nodes_block(node));
3934 ir_node *ptr = get_irn_n(node, 0);
3935 ir_node *new_ptr = be_transform_node(ptr);
3936 ir_node *mem = get_irn_n(node, 1);
3937 ir_node *new_mem = be_transform_node(mem);
3938 ir_graph *irg = current_ir_graph;
3939 dbg_info *dbgi = get_irn_dbg_info(node);
3940 ir_mode *mode = get_ia32_ls_mode(node);
3941 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3944 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
3946 set_ia32_op_type(new_op, ia32_AddrModeS);
3947 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
3948 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
3949 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
3950 if (is_ia32_am_sc_sign(node))
3951 set_ia32_am_sc_sign(new_op);
3952 set_ia32_ls_mode(new_op, mode);
3953 if (is_ia32_use_frame(node)) {
3954 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3955 set_ia32_use_frame(new_op);
3958 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3964 * Transforms a lowered Store into a "real" one.
3966 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
3968 ir_node *block = be_transform_node(get_nodes_block(node));
3969 ir_node *ptr = get_irn_n(node, 0);
3970 ir_node *new_ptr = be_transform_node(ptr);
3971 ir_node *val = get_irn_n(node, 1);
3972 ir_node *new_val = be_transform_node(val);
3973 ir_node *mem = get_irn_n(node, 2);
3974 ir_node *new_mem = be_transform_node(mem);
3975 ir_graph *irg = current_ir_graph;
3976 dbg_info *dbgi = get_irn_dbg_info(node);
3977 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3978 ir_mode *mode = get_ia32_ls_mode(node);
3982 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
3984 am_offs = get_ia32_am_offs_int(node);
3985 add_ia32_am_offs_int(new_op, am_offs);
3987 set_ia32_op_type(new_op, ia32_AddrModeD);
3988 set_ia32_ls_mode(new_op, mode);
3989 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3990 set_ia32_use_frame(new_op);
3992 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3997 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3999 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4000 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4002 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4003 match_immediate | match_mode_neutral);
4006 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4008 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4009 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4010 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4014 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4016 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4017 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4018 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4022 static ir_node *gen_ia32_l_Add(ir_node *node) {
4023 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4024 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4025 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4026 match_commutative | match_am | match_immediate |
4027 match_mode_neutral);
4029 if(is_Proj(lowered)) {
4030 lowered = get_Proj_pred(lowered);
4032 assert(is_ia32_Add(lowered));
4033 set_irn_mode(lowered, mode_T);
4039 static ir_node *gen_ia32_l_Adc(ir_node *node)
4041 return gen_binop_flags(node, new_rd_ia32_Adc,
4042 match_commutative | match_am | match_immediate |
4043 match_mode_neutral);
4047 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4049 * @param node The node to transform
4050 * @return the created ia32 vfild node
4052 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4053 return gen_lowered_Load(node, new_rd_ia32_vfild);
4057 * Transforms an ia32_l_Load into a "real" ia32_Load node
4059 * @param node The node to transform
4060 * @return the created ia32 Load node
4062 static ir_node *gen_ia32_l_Load(ir_node *node) {
4063 return gen_lowered_Load(node, new_rd_ia32_Load);
4067 * Transforms an ia32_l_Store into a "real" ia32_Store node
4069 * @param node The node to transform
4070 * @return the created ia32 Store node
4072 static ir_node *gen_ia32_l_Store(ir_node *node) {
4073 return gen_lowered_Store(node, new_rd_ia32_Store);
4077 * Transforms a l_vfist into a "real" vfist node.
4079 * @param node The node to transform
4080 * @return the created ia32 vfist node
4082 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4083 ir_node *block = be_transform_node(get_nodes_block(node));
4084 ir_node *ptr = get_irn_n(node, 0);
4085 ir_node *new_ptr = be_transform_node(ptr);
4086 ir_node *val = get_irn_n(node, 1);
4087 ir_node *new_val = be_transform_node(val);
4088 ir_node *mem = get_irn_n(node, 2);
4089 ir_node *new_mem = be_transform_node(mem);
4090 ir_graph *irg = current_ir_graph;
4091 dbg_info *dbgi = get_irn_dbg_info(node);
4092 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4093 ir_mode *mode = get_ia32_ls_mode(node);
4094 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
4098 new_op = new_rd_ia32_vfist(dbgi, irg, block, new_ptr, noreg, new_mem,
4099 new_val, trunc_mode);
4101 am_offs = get_ia32_am_offs_int(node);
4102 add_ia32_am_offs_int(new_op, am_offs);
4104 set_ia32_op_type(new_op, ia32_AddrModeD);
4105 set_ia32_ls_mode(new_op, mode);
4106 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4107 set_ia32_use_frame(new_op);
4109 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4115 * Transforms a l_MulS into a "real" MulS node.
4117 * @return the created ia32 Mul node
4119 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4120 ir_node *left = get_binop_left(node);
4121 ir_node *right = get_binop_right(node);
4123 return gen_binop(node, left, right, new_rd_ia32_Mul,
4124 match_commutative | match_am | match_mode_neutral);
4128 * Transforms a l_IMulS into a "real" IMul1OPS node.
4130 * @return the created ia32 IMul1OP node
4132 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4133 ir_node *left = get_binop_left(node);
4134 ir_node *right = get_binop_right(node);
4136 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4137 match_commutative | match_am | match_mode_neutral);
4140 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4141 ir_node *left = get_irn_n(node, n_ia32_l_Sub_left);
4142 ir_node *right = get_irn_n(node, n_ia32_l_Sub_right);
4143 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4144 match_am | match_immediate | match_mode_neutral);
4146 if(is_Proj(lowered)) {
4147 lowered = get_Proj_pred(lowered);
4149 assert(is_ia32_Sub(lowered));
4150 set_irn_mode(lowered, mode_T);
4156 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4157 return gen_binop_flags(node, new_rd_ia32_Sbb,
4158 match_am | match_immediate | match_mode_neutral);
4162 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4163 * op1 - target to be shifted
4164 * op2 - contains bits to be shifted into target
4166 * Only op3 can be an immediate.
4168 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4169 ir_node *low, ir_node *count)
4171 ir_node *block = get_nodes_block(node);
4172 ir_node *new_block = be_transform_node(block);
4173 ir_graph *irg = current_ir_graph;
4174 dbg_info *dbgi = get_irn_dbg_info(node);
4175 ir_node *new_high = be_transform_node(high);
4176 ir_node *new_low = be_transform_node(low);
4180 /* the shift amount can be any mode that is bigger than 5 bits, since all
4181 * other bits are ignored anyway */
4182 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4183 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4184 count = get_Conv_op(count);
4186 new_count = create_immediate_or_transform(count, 0);
4188 if (is_ia32_l_ShlD(node)) {
4189 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4192 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4195 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4200 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4202 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4203 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4204 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4205 return gen_lowered_64bit_shifts(node, high, low, count);
4208 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4210 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4211 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4212 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4213 return gen_lowered_64bit_shifts(node, high, low, count);
4216 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4217 ir_node *src_block = get_nodes_block(node);
4218 ir_node *block = be_transform_node(src_block);
4219 ir_graph *irg = current_ir_graph;
4220 dbg_info *dbgi = get_irn_dbg_info(node);
4221 ir_node *frame = get_irg_frame(irg);
4222 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4223 ir_node *nomem = new_NoMem();
4224 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4225 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4226 ir_node *new_val_low = be_transform_node(val_low);
4227 ir_node *new_val_high = be_transform_node(val_high);
4232 ir_node *store_high;
4234 if(!mode_is_signed(get_irn_mode(val_high))) {
4235 panic("unsigned long long -> float not supported yet (%+F)", node);
4239 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4241 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4243 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4244 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4246 set_ia32_use_frame(store_low);
4247 set_ia32_use_frame(store_high);
4248 set_ia32_op_type(store_low, ia32_AddrModeD);
4249 set_ia32_op_type(store_high, ia32_AddrModeD);
4250 set_ia32_ls_mode(store_low, mode_Iu);
4251 set_ia32_ls_mode(store_high, mode_Is);
4252 add_ia32_am_offs_int(store_high, 4);
4256 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4259 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4261 set_ia32_use_frame(fild);
4262 set_ia32_op_type(fild, ia32_AddrModeS);
4263 set_ia32_ls_mode(fild, mode_Ls);
4265 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4267 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4270 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4271 ir_node *src_block = get_nodes_block(node);
4272 ir_node *block = be_transform_node(src_block);
4273 ir_graph *irg = current_ir_graph;
4274 dbg_info *dbgi = get_irn_dbg_info(node);
4275 ir_node *frame = get_irg_frame(irg);
4276 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4277 ir_node *nomem = new_NoMem();
4278 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4279 ir_node *new_val = be_transform_node(val);
4280 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
4285 fist = new_rd_ia32_vfist(dbgi, irg, block, frame, noreg, nomem, new_val,
4287 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4288 set_ia32_use_frame(fist);
4289 set_ia32_op_type(fist, ia32_AddrModeD);
4290 set_ia32_ls_mode(fist, mode_Ls);
4296 * the BAD transformer.
4298 static ir_node *bad_transform(ir_node *node) {
4299 panic("No transform function for %+F available.\n", node);
4303 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4304 ir_graph *irg = current_ir_graph;
4305 ir_node *block = be_transform_node(get_nodes_block(node));
4306 ir_node *pred = get_Proj_pred(node);
4307 ir_node *new_pred = be_transform_node(pred);
4308 ir_node *frame = get_irg_frame(irg);
4309 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4310 dbg_info *dbgi = get_irn_dbg_info(node);
4311 long pn = get_Proj_proj(node);
4316 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4317 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4318 set_ia32_use_frame(load);
4319 set_ia32_op_type(load, ia32_AddrModeS);
4320 set_ia32_ls_mode(load, mode_Iu);
4321 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4322 * 32 bit from it with this particular load */
4323 attr = get_ia32_attr(load);
4324 attr->data.need_64bit_stackent = 1;
4326 if (pn == pn_ia32_l_FloattoLL_res_high) {
4327 add_ia32_am_offs_int(load, 4);
4329 assert(pn == pn_ia32_l_FloattoLL_res_low);
4332 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4338 * Transform the Projs of an AddSP.
4340 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4341 ir_node *block = be_transform_node(get_nodes_block(node));
4342 ir_node *pred = get_Proj_pred(node);
4343 ir_node *new_pred = be_transform_node(pred);
4344 ir_graph *irg = current_ir_graph;
4345 dbg_info *dbgi = get_irn_dbg_info(node);
4346 long proj = get_Proj_proj(node);
4348 if (proj == pn_be_AddSP_sp) {
4349 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4350 pn_ia32_SubSP_stack);
4351 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4353 } else if(proj == pn_be_AddSP_res) {
4354 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4355 pn_ia32_SubSP_addr);
4356 } else if (proj == pn_be_AddSP_M) {
4357 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4361 return new_rd_Unknown(irg, get_irn_mode(node));
4365 * Transform the Projs of a SubSP.
4367 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4368 ir_node *block = be_transform_node(get_nodes_block(node));
4369 ir_node *pred = get_Proj_pred(node);
4370 ir_node *new_pred = be_transform_node(pred);
4371 ir_graph *irg = current_ir_graph;
4372 dbg_info *dbgi = get_irn_dbg_info(node);
4373 long proj = get_Proj_proj(node);
4375 if (proj == pn_be_SubSP_sp) {
4376 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4377 pn_ia32_AddSP_stack);
4378 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4380 } else if (proj == pn_be_SubSP_M) {
4381 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4385 return new_rd_Unknown(irg, get_irn_mode(node));
4389 * Transform and renumber the Projs from a Load.
4391 static ir_node *gen_Proj_Load(ir_node *node) {
4393 ir_node *block = be_transform_node(get_nodes_block(node));
4394 ir_node *pred = get_Proj_pred(node);
4395 ir_graph *irg = current_ir_graph;
4396 dbg_info *dbgi = get_irn_dbg_info(node);
4397 long proj = get_Proj_proj(node);
4400 /* loads might be part of source address mode matches, so we don't
4401 transform the ProjMs yet (with the exception of loads whose result is
4404 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4407 assert(pn_ia32_Load_M == 1); /* convention: mem-result of Source-AM
4409 /* this is needed, because sometimes we have loops that are only
4410 reachable through the ProjM */
4411 be_enqueue_preds(node);
4412 /* do it in 2 steps, to silence firm verifier */
4413 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4414 set_Proj_proj(res, pn_ia32_Load_M);
4418 /* renumber the proj */
4419 new_pred = be_transform_node(pred);
4420 if (is_ia32_Load(new_pred)) {
4423 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4425 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4426 case pn_Load_X_regular:
4427 return new_rd_Jmp(dbgi, irg, block);
4428 case pn_Load_X_except:
4429 /* This Load might raise an exception. Mark it. */
4430 set_ia32_exc_label(new_pred, 1);
4431 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4435 } else if (is_ia32_Conv_I2I(new_pred) ||
4436 is_ia32_Conv_I2I8Bit(new_pred)) {
4437 set_irn_mode(new_pred, mode_T);
4438 if (proj == pn_Load_res) {
4439 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4440 } else if (proj == pn_Load_M) {
4441 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4443 } else if (is_ia32_xLoad(new_pred)) {
4446 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4448 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4449 case pn_Load_X_regular:
4450 return new_rd_Jmp(dbgi, irg, block);
4451 case pn_Load_X_except:
4452 /* This Load might raise an exception. Mark it. */
4453 set_ia32_exc_label(new_pred, 1);
4454 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4458 } else if (is_ia32_vfld(new_pred)) {
4461 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4463 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4464 case pn_Load_X_regular:
4465 return new_rd_Jmp(dbgi, irg, block);
4466 case pn_Load_X_except:
4467 /* This Load might raise an exception. Mark it. */
4468 set_ia32_exc_label(new_pred, 1);
4469 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4474 /* can happen for ProJMs when source address mode happened for the
4477 /* however it should not be the result proj, as that would mean the
4478 load had multiple users and should not have been used for
4480 if (proj != pn_Load_M) {
4481 panic("internal error: transformed node not a Load");
4483 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4487 return new_rd_Unknown(irg, get_irn_mode(node));
4491 * Transform and renumber the Projs from a DivMod like instruction.
4493 static ir_node *gen_Proj_DivMod(ir_node *node) {
4494 ir_node *block = be_transform_node(get_nodes_block(node));
4495 ir_node *pred = get_Proj_pred(node);
4496 ir_node *new_pred = be_transform_node(pred);
4497 ir_graph *irg = current_ir_graph;
4498 dbg_info *dbgi = get_irn_dbg_info(node);
4499 ir_mode *mode = get_irn_mode(node);
4500 long proj = get_Proj_proj(node);
4502 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4504 switch (get_irn_opcode(pred)) {
4508 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4510 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4511 case pn_Div_X_regular:
4512 return new_rd_Jmp(dbgi, irg, block);
4513 case pn_Div_X_except:
4514 set_ia32_exc_label(new_pred, 1);
4515 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4523 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4525 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4526 case pn_Mod_X_except:
4527 set_ia32_exc_label(new_pred, 1);
4528 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4536 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4537 case pn_DivMod_res_div:
4538 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4539 case pn_DivMod_res_mod:
4540 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4541 case pn_DivMod_X_regular:
4542 return new_rd_Jmp(dbgi, irg, block);
4543 case pn_DivMod_X_except:
4544 set_ia32_exc_label(new_pred, 1);
4545 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4555 return new_rd_Unknown(irg, mode);
4559 * Transform and renumber the Projs from a CopyB.
4561 static ir_node *gen_Proj_CopyB(ir_node *node) {
4562 ir_node *block = be_transform_node(get_nodes_block(node));
4563 ir_node *pred = get_Proj_pred(node);
4564 ir_node *new_pred = be_transform_node(pred);
4565 ir_graph *irg = current_ir_graph;
4566 dbg_info *dbgi = get_irn_dbg_info(node);
4567 ir_mode *mode = get_irn_mode(node);
4568 long proj = get_Proj_proj(node);
4571 case pn_CopyB_M_regular:
4572 if (is_ia32_CopyB_i(new_pred)) {
4573 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4574 } else if (is_ia32_CopyB(new_pred)) {
4575 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4583 return new_rd_Unknown(irg, mode);
4587 * Transform and renumber the Projs from a Quot.
4589 static ir_node *gen_Proj_Quot(ir_node *node) {
4590 ir_node *block = be_transform_node(get_nodes_block(node));
4591 ir_node *pred = get_Proj_pred(node);
4592 ir_node *new_pred = be_transform_node(pred);
4593 ir_graph *irg = current_ir_graph;
4594 dbg_info *dbgi = get_irn_dbg_info(node);
4595 ir_mode *mode = get_irn_mode(node);
4596 long proj = get_Proj_proj(node);
4600 if (is_ia32_xDiv(new_pred)) {
4601 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4602 } else if (is_ia32_vfdiv(new_pred)) {
4603 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4607 if (is_ia32_xDiv(new_pred)) {
4608 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4609 } else if (is_ia32_vfdiv(new_pred)) {
4610 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4618 return new_rd_Unknown(irg, mode);
4622 * Transform the Thread Local Storage Proj.
4624 static ir_node *gen_Proj_tls(ir_node *node) {
4625 ir_node *block = be_transform_node(get_nodes_block(node));
4626 ir_graph *irg = current_ir_graph;
4627 dbg_info *dbgi = NULL;
4628 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4633 static ir_node *gen_be_Call(ir_node *node) {
4634 ir_node *res = be_duplicate_node(node);
4635 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4640 static ir_node *gen_be_IncSP(ir_node *node) {
4641 ir_node *res = be_duplicate_node(node);
4642 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4648 * Transform the Projs from a be_Call.
4650 static ir_node *gen_Proj_be_Call(ir_node *node) {
4651 ir_node *block = be_transform_node(get_nodes_block(node));
4652 ir_node *call = get_Proj_pred(node);
4653 ir_node *new_call = be_transform_node(call);
4654 ir_graph *irg = current_ir_graph;
4655 dbg_info *dbgi = get_irn_dbg_info(node);
4656 ir_type *method_type = be_Call_get_type(call);
4657 int n_res = get_method_n_ress(method_type);
4658 long proj = get_Proj_proj(node);
4659 ir_mode *mode = get_irn_mode(node);
4661 const arch_register_class_t *cls;
4663 /* The following is kinda tricky: If we're using SSE, then we have to
4664 * move the result value of the call in floating point registers to an
4665 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4666 * after the call, we have to make sure to correctly make the
4667 * MemProj and the result Proj use these 2 nodes
4669 if (proj == pn_be_Call_M_regular) {
4670 // get new node for result, are we doing the sse load/store hack?
4671 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4672 ir_node *call_res_new;
4673 ir_node *call_res_pred = NULL;
4675 if (call_res != NULL) {
4676 call_res_new = be_transform_node(call_res);
4677 call_res_pred = get_Proj_pred(call_res_new);
4680 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4681 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4682 pn_be_Call_M_regular);
4684 assert(is_ia32_xLoad(call_res_pred));
4685 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4689 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4690 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4692 ir_node *frame = get_irg_frame(irg);
4693 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4695 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4698 /* in case there is no memory output: create one to serialize the copy
4700 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4701 pn_be_Call_M_regular);
4702 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4703 pn_be_Call_first_res);
4705 /* store st(0) onto stack */
4706 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4708 set_ia32_op_type(fstp, ia32_AddrModeD);
4709 set_ia32_use_frame(fstp);
4711 /* load into SSE register */
4712 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4714 set_ia32_op_type(sse_load, ia32_AddrModeS);
4715 set_ia32_use_frame(sse_load);
4717 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4723 /* transform call modes */
4724 if (mode_is_data(mode)) {
4725 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4729 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4733 * Transform the Projs from a Cmp.
4735 static ir_node *gen_Proj_Cmp(ir_node *node)
4737 /* this probably means not all mode_b nodes were lowered... */
4738 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4743 * Transform and potentially renumber Proj nodes.
4745 static ir_node *gen_Proj(ir_node *node) {
4746 ir_graph *irg = current_ir_graph;
4747 dbg_info *dbgi = get_irn_dbg_info(node);
4748 ir_node *pred = get_Proj_pred(node);
4749 long proj = get_Proj_proj(node);
4751 if (is_Store(pred)) {
4752 if (proj == pn_Store_M) {
4753 return be_transform_node(pred);
4756 return new_r_Bad(irg);
4758 } else if (is_Load(pred)) {
4759 return gen_Proj_Load(node);
4760 } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
4761 return gen_Proj_DivMod(node);
4762 } else if (is_CopyB(pred)) {
4763 return gen_Proj_CopyB(node);
4764 } else if (is_Quot(pred)) {
4765 return gen_Proj_Quot(node);
4766 } else if (be_is_SubSP(pred)) {
4767 return gen_Proj_be_SubSP(node);
4768 } else if (be_is_AddSP(pred)) {
4769 return gen_Proj_be_AddSP(node);
4770 } else if (be_is_Call(pred)) {
4771 return gen_Proj_be_Call(node);
4772 } else if (is_Cmp(pred)) {
4773 return gen_Proj_Cmp(node);
4774 } else if (get_irn_op(pred) == op_Start) {
4775 if (proj == pn_Start_X_initial_exec) {
4776 ir_node *block = get_nodes_block(pred);
4779 /* we exchange the ProjX with a jump */
4780 block = be_transform_node(block);
4781 jump = new_rd_Jmp(dbgi, irg, block);
4784 if (node == be_get_old_anchor(anchor_tls)) {
4785 return gen_Proj_tls(node);
4787 } else if (is_ia32_l_FloattoLL(pred)) {
4788 return gen_Proj_l_FloattoLL(node);
4790 } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4794 ir_node *new_pred = be_transform_node(pred);
4795 ir_node *block = be_transform_node(get_nodes_block(node));
4796 ir_mode *mode = get_irn_mode(node);
4797 if (mode_needs_gp_reg(mode)) {
4798 ir_node *new_proj = new_r_Proj(irg, block, new_pred, mode_Iu,
4799 get_Proj_proj(node));
4800 #ifdef DEBUG_libfirm
4801 new_proj->node_nr = node->node_nr;
4807 return be_duplicate_node(node);
4811 * Enters all transform functions into the generic pointer
4813 static void register_transformers(void)
4817 /* first clear the generic function pointer for all ops */
4818 clear_irp_opcodes_generic_func();
4820 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4821 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4859 /* transform ops from intrinsic lowering */
4875 GEN(ia32_l_LLtoFloat);
4876 GEN(ia32_l_FloattoLL);
4882 /* we should never see these nodes */
4897 /* handle generic backend nodes */
4906 op_Mulh = get_op_Mulh();
4915 * Pre-transform all unknown and noreg nodes.
4917 static void ia32_pretransform_node(void *arch_cg) {
4918 ia32_code_gen_t *cg = arch_cg;
4920 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4921 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4922 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4923 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4924 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4925 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4930 * Walker, checks if all ia32 nodes producing more than one result have
4931 * its Projs, other wise creates new projs and keep them using a be_Keep node.
4933 static void add_missing_keep_walker(ir_node *node, void *data)
4936 unsigned found_projs = 0;
4937 const ir_edge_t *edge;
4938 ir_mode *mode = get_irn_mode(node);
4943 if(!is_ia32_irn(node))
4946 n_outs = get_ia32_n_res(node);
4949 if(is_ia32_SwitchJmp(node))
4952 assert(n_outs < (int) sizeof(unsigned) * 8);
4953 foreach_out_edge(node, edge) {
4954 ir_node *proj = get_edge_src_irn(edge);
4955 int pn = get_Proj_proj(proj);
4957 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
4958 found_projs |= 1 << pn;
4962 /* are keeps missing? */
4964 for(i = 0; i < n_outs; ++i) {
4967 const arch_register_req_t *req;
4968 const arch_register_class_t *class;
4970 if(found_projs & (1 << i)) {
4974 req = get_ia32_out_req(node, i);
4979 if(class == &ia32_reg_classes[CLASS_ia32_flags]) {
4983 block = get_nodes_block(node);
4984 in[0] = new_r_Proj(current_ir_graph, block, node,
4985 arch_register_class_mode(class), i);
4986 if(last_keep != NULL) {
4987 be_Keep_add_node(last_keep, class, in[0]);
4989 last_keep = be_new_Keep(class, current_ir_graph, block, 1, in);
4990 if(sched_is_scheduled(node)) {
4991 sched_add_after(node, last_keep);
4998 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5001 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5003 ir_graph *irg = be_get_birg_irg(cg->birg);
5004 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5007 /* do the transformation */
5008 void ia32_transform_graph(ia32_code_gen_t *cg) {
5010 ir_graph *irg = cg->irg;
5012 register_transformers();
5014 initial_fpcw = NULL;
5016 BE_TIMER_PUSH(t_heights);
5017 heights = heights_new(irg);
5018 BE_TIMER_POP(t_heights);
5019 ia32_calculate_non_address_mode_nodes(cg->birg);
5021 /* the transform phase is not safe for CSE (yet) because several nodes get
5022 * attributes set after their creation */
5023 cse_last = get_opt_cse();
5026 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5028 set_opt_cse(cse_last);
5030 ia32_free_non_address_mode_nodes();
5031 heights_free(heights);
5035 void ia32_init_transform(void)
5037 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");