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 * Creates an immediate.
187 * @param symconst if set, create a SymConst immediate
188 * @param symconst_sign sign for the symconst
189 * @param val integer value for the immediate
191 static ir_node *create_Immediate(ir_entity *symconst, int symconst_sign, long val)
193 ir_graph *irg = current_ir_graph;
194 ir_node *start_block = get_irg_start_block(irg);
195 ir_node *immediate = new_rd_ia32_Immediate(NULL, irg, start_block,
196 symconst, symconst_sign, val);
197 arch_set_irn_register(env_cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]);
203 * Get an atomic entity that is initialized with a tarval forming
206 * @param cnst the node representing the constant
208 static ir_entity *create_float_const_entity(ir_node *cnst)
210 ia32_isa_t *isa = env_cg->isa;
211 tarval *key = get_Const_tarval(cnst);
212 pmap_entry *e = pmap_find(isa->tv_ent, key);
218 ir_mode *mode = get_tarval_mode(tv);
221 if (! ia32_cg_config.use_sse2) {
222 /* try to reduce the mode to produce smaller sized entities */
223 if (mode != mode_F) {
224 if (tarval_ieee754_can_conv_lossless(tv, mode_F)) {
226 tv = tarval_convert_to(tv, mode);
227 } else if (mode != mode_D) {
228 if (tarval_ieee754_can_conv_lossless(tv, mode_D)) {
230 tv = tarval_convert_to(tv, mode);
236 if (mode == get_irn_mode(cnst)) {
237 /* mode was not changed */
238 tp = get_Const_type(cnst);
239 if (tp == firm_unknown_type)
240 tp = get_prim_type(isa->types, mode);
242 tp = get_prim_type(isa->types, mode);
244 res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);
246 set_entity_ld_ident(res, get_entity_ident(res));
247 set_entity_visibility(res, visibility_local);
248 set_entity_variability(res, variability_constant);
249 set_entity_allocation(res, allocation_static);
251 /* we create a new entity here: It's initialization must resist on the
253 rem = current_ir_graph;
254 current_ir_graph = get_const_code_irg();
255 set_atomic_ent_value(res, new_Const_type(tv, tp));
256 current_ir_graph = rem;
258 pmap_insert(isa->tv_ent, key, res);
266 static int is_Const_0(ir_node *node) {
267 return is_Const(node) && is_Const_null(node);
270 static int is_Const_1(ir_node *node) {
271 return is_Const(node) && is_Const_one(node);
274 static int is_Const_Minus_1(ir_node *node) {
275 return is_Const(node) && is_Const_all_one(node);
279 * returns true if constant can be created with a simple float command
281 static int is_simple_x87_Const(ir_node *node)
283 tarval *tv = get_Const_tarval(node);
284 if (tarval_is_null(tv) || tarval_is_one(tv))
287 /* TODO: match all the other float constants */
292 * returns true if constant can be created with a simple float command
294 static int is_simple_sse_Const(ir_node *node)
296 tarval *tv = get_Const_tarval(node);
297 ir_mode *mode = get_tarval_mode(tv);
302 if (tarval_is_null(tv) || tarval_is_one(tv))
305 if (mode == mode_D) {
306 unsigned val = get_tarval_sub_bits(tv, 0) |
307 (get_tarval_sub_bits(tv, 1) << 8) |
308 (get_tarval_sub_bits(tv, 2) << 16) |
309 (get_tarval_sub_bits(tv, 3) << 24);
311 /* lower 32bit are zero, really a 32bit constant */
315 /* TODO: match all the other float constants */
320 * Transforms a Const.
322 static ir_node *gen_Const(ir_node *node) {
323 ir_graph *irg = current_ir_graph;
324 ir_node *old_block = get_nodes_block(node);
325 ir_node *block = be_transform_node(old_block);
326 dbg_info *dbgi = get_irn_dbg_info(node);
327 ir_mode *mode = get_irn_mode(node);
329 assert(is_Const(node));
331 if (mode_is_float(mode)) {
333 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
334 ir_node *nomem = new_NoMem();
338 if (ia32_cg_config.use_sse2) {
339 tarval *tv = get_Const_tarval(node);
340 if (tarval_is_null(tv)) {
341 load = new_rd_ia32_xZero(dbgi, irg, block);
342 set_ia32_ls_mode(load, mode);
344 } else if (tarval_is_one(tv)) {
345 int cnst = mode == mode_F ? 26 : 55;
346 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
347 ir_node *imm2 = create_Immediate(NULL, 0, 2);
348 ir_node *pslld, *psrld;
350 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
351 set_ia32_ls_mode(load, mode);
352 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
353 set_ia32_ls_mode(pslld, mode);
354 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
355 set_ia32_ls_mode(psrld, mode);
357 } else if (mode == mode_F) {
358 /* we can place any 32bit constant by using a movd gp, sse */
359 unsigned val = get_tarval_sub_bits(tv, 0) |
360 (get_tarval_sub_bits(tv, 1) << 8) |
361 (get_tarval_sub_bits(tv, 2) << 16) |
362 (get_tarval_sub_bits(tv, 3) << 24);
363 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
364 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
365 set_ia32_ls_mode(load, mode);
368 if (mode == mode_D) {
369 unsigned val = get_tarval_sub_bits(tv, 0) |
370 (get_tarval_sub_bits(tv, 1) << 8) |
371 (get_tarval_sub_bits(tv, 2) << 16) |
372 (get_tarval_sub_bits(tv, 3) << 24);
374 ir_node *imm32 = create_Immediate(NULL, 0, 32);
375 ir_node *cnst, *psllq;
377 /* fine, lower 32bit are zero, produce 32bit value */
378 val = get_tarval_sub_bits(tv, 4) |
379 (get_tarval_sub_bits(tv, 5) << 8) |
380 (get_tarval_sub_bits(tv, 6) << 16) |
381 (get_tarval_sub_bits(tv, 7) << 24);
382 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
383 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
384 set_ia32_ls_mode(load, mode);
385 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
386 set_ia32_ls_mode(psllq, mode);
391 floatent = create_float_const_entity(node);
393 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
395 set_ia32_op_type(load, ia32_AddrModeS);
396 set_ia32_am_sc(load, floatent);
397 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
398 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
401 if (is_Const_null(node)) {
402 load = new_rd_ia32_vfldz(dbgi, irg, block);
404 set_ia32_ls_mode(load, mode);
405 } else if (is_Const_one(node)) {
406 load = new_rd_ia32_vfld1(dbgi, irg, block);
408 set_ia32_ls_mode(load, mode);
410 floatent = create_float_const_entity(node);
412 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
413 set_ia32_op_type(load, ia32_AddrModeS);
414 set_ia32_am_sc(load, floatent);
415 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
416 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
417 /* take the mode from the entity */
418 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
422 /* Const Nodes before the initial IncSP are a bad idea, because
423 * they could be spilled and we have no SP ready at that point yet.
424 * So add a dependency to the initial frame pointer calculation to
425 * avoid that situation.
427 if (get_irg_start_block(irg) == block) {
428 add_irn_dep(load, get_irg_frame(irg));
431 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
433 } else { /* non-float mode */
435 tarval *tv = get_Const_tarval(node);
438 tv = tarval_convert_to(tv, mode_Iu);
440 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
442 panic("couldn't convert constant tarval (%+F)", node);
444 val = get_tarval_long(tv);
446 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
447 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
450 if (get_irg_start_block(irg) == block) {
451 add_irn_dep(cnst, get_irg_frame(irg));
459 * Transforms a SymConst.
461 static ir_node *gen_SymConst(ir_node *node) {
462 ir_graph *irg = current_ir_graph;
463 ir_node *old_block = get_nodes_block(node);
464 ir_node *block = be_transform_node(old_block);
465 dbg_info *dbgi = get_irn_dbg_info(node);
466 ir_mode *mode = get_irn_mode(node);
469 if (mode_is_float(mode)) {
470 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
471 ir_node *nomem = new_NoMem();
473 if (ia32_cg_config.use_sse2)
474 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
476 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
477 set_ia32_am_sc(cnst, get_SymConst_entity(node));
478 set_ia32_use_frame(cnst);
482 if(get_SymConst_kind(node) != symconst_addr_ent) {
483 panic("backend only support symconst_addr_ent (at %+F)", node);
485 entity = get_SymConst_entity(node);
486 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
489 /* Const Nodes before the initial IncSP are a bad idea, because
490 * they could be spilled and we have no SP ready at that point yet
492 if (get_irg_start_block(irg) == block) {
493 add_irn_dep(cnst, get_irg_frame(irg));
496 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
501 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
502 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
503 static const struct {
505 const char *ent_name;
506 const char *cnst_str;
509 } names [ia32_known_const_max] = {
510 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
511 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
512 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
513 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
514 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
516 static ir_entity *ent_cache[ia32_known_const_max];
518 const char *tp_name, *ent_name, *cnst_str;
526 ent_name = names[kct].ent_name;
527 if (! ent_cache[kct]) {
528 tp_name = names[kct].tp_name;
529 cnst_str = names[kct].cnst_str;
531 switch (names[kct].mode) {
532 case 0: mode = mode_Iu; break;
533 case 1: mode = mode_Lu; break;
534 default: mode = mode_F; break;
536 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
537 tp = new_type_primitive(new_id_from_str(tp_name), mode);
538 /* set the specified alignment */
539 set_type_alignment_bytes(tp, names[kct].align);
541 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
543 set_entity_ld_ident(ent, get_entity_ident(ent));
544 set_entity_visibility(ent, visibility_local);
545 set_entity_variability(ent, variability_constant);
546 set_entity_allocation(ent, allocation_static);
548 /* we create a new entity here: It's initialization must resist on the
550 rem = current_ir_graph;
551 current_ir_graph = get_const_code_irg();
552 cnst = new_Const(mode, tv);
553 current_ir_graph = rem;
555 set_atomic_ent_value(ent, cnst);
557 /* cache the entry */
558 ent_cache[kct] = ent;
561 return ent_cache[kct];
566 * Prints the old node name on cg obst and returns a pointer to it.
568 const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
569 ia32_isa_t *isa = (ia32_isa_t *)cg->arch_env->isa;
571 lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
572 obstack_1grow(isa->name_obst, 0);
573 return obstack_finish(isa->name_obst);
578 * return true if the node is a Proj(Load) and could be used in source address
579 * mode for another node. Will return only true if the @p other node is not
580 * dependent on the memory of the Load (for binary operations use the other
581 * input here, for unary operations use NULL).
583 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
584 ir_node *other, ir_node *other2)
589 /* float constants are always available */
590 if (is_Const(node)) {
591 ir_mode *mode = get_irn_mode(node);
592 if (mode_is_float(mode)) {
593 if (ia32_cg_config.use_sse2) {
594 if (is_simple_sse_Const(node))
597 if (is_simple_x87_Const(node))
600 if (get_irn_n_edges(node) > 1)
608 load = get_Proj_pred(node);
609 pn = get_Proj_proj(node);
610 if (!is_Load(load) || pn != pn_Load_res)
612 if (get_nodes_block(load) != block)
614 /* we only use address mode if we're the only user of the load */
615 if (get_irn_n_edges(node) > 1)
617 /* in some edge cases with address mode we might reach the load normally
618 * and through some AM sequence, if it is already materialized then we
619 * can't create an AM node from it */
620 if (be_is_transformed(node))
623 /* don't do AM if other node inputs depend on the load (via mem-proj) */
624 if (other != NULL && get_nodes_block(other) == block &&
625 heights_reachable_in_block(heights, other, load))
627 if (other2 != NULL && get_nodes_block(other2) == block &&
628 heights_reachable_in_block(heights, other2, load))
634 typedef struct ia32_address_mode_t ia32_address_mode_t;
635 struct ia32_address_mode_t {
639 ia32_op_type_t op_type;
643 unsigned commutative : 1;
644 unsigned ins_permuted : 1;
647 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
651 /* construct load address */
652 memset(addr, 0, sizeof(addr[0]));
653 ia32_create_address_mode(addr, ptr, /*force=*/0);
655 noreg_gp = ia32_new_NoReg_gp(env_cg);
656 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
657 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
658 addr->mem = be_transform_node(mem);
661 static void build_address(ia32_address_mode_t *am, ir_node *node)
663 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
664 ia32_address_t *addr = &am->addr;
670 if (is_Const(node)) {
671 ir_entity *entity = create_float_const_entity(node);
672 addr->base = noreg_gp;
673 addr->index = noreg_gp;
674 addr->mem = new_NoMem();
675 addr->symconst_ent = entity;
677 am->ls_mode = get_type_mode(get_entity_type(entity));
678 am->pinned = op_pin_state_floats;
682 load = get_Proj_pred(node);
683 ptr = get_Load_ptr(load);
684 mem = get_Load_mem(load);
685 new_mem = be_transform_node(mem);
686 am->pinned = get_irn_pinned(load);
687 am->ls_mode = get_Load_mode(load);
688 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
690 /* construct load address */
691 ia32_create_address_mode(addr, ptr, /*force=*/0);
693 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
694 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
698 static void set_address(ir_node *node, const ia32_address_t *addr)
700 set_ia32_am_scale(node, addr->scale);
701 set_ia32_am_sc(node, addr->symconst_ent);
702 set_ia32_am_offs_int(node, addr->offset);
703 if(addr->symconst_sign)
704 set_ia32_am_sc_sign(node);
706 set_ia32_use_frame(node);
707 set_ia32_frame_ent(node, addr->frame_entity);
711 * Apply attributes of a given address mode to a node.
713 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
715 set_address(node, &am->addr);
717 set_ia32_op_type(node, am->op_type);
718 set_ia32_ls_mode(node, am->ls_mode);
719 if (am->pinned == op_pin_state_pinned) {
720 set_irn_pinned(node, am->pinned);
723 set_ia32_commutative(node);
727 * Check, if a given node is a Down-Conv, ie. a integer Conv
728 * from a mode with a mode with more bits to a mode with lesser bits.
729 * Moreover, we return only true if the node has not more than 1 user.
731 * @param node the node
732 * @return non-zero if node is a Down-Conv
734 static int is_downconv(const ir_node *node)
742 /* we only want to skip the conv when we're the only user
743 * (not optimal but for now...)
745 if(get_irn_n_edges(node) > 1)
748 src_mode = get_irn_mode(get_Conv_op(node));
749 dest_mode = get_irn_mode(node);
750 return mode_needs_gp_reg(src_mode)
751 && mode_needs_gp_reg(dest_mode)
752 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
755 /* Skip all Down-Conv's on a given node and return the resulting node. */
756 ir_node *ia32_skip_downconv(ir_node *node) {
757 while (is_downconv(node))
758 node = get_Conv_op(node);
764 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
766 ir_mode *mode = get_irn_mode(node);
771 if(mode_is_signed(mode)) {
776 block = get_nodes_block(node);
777 dbgi = get_irn_dbg_info(node);
779 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
784 * matches operands of a node into ia32 addressing/operand modes. This covers
785 * usage of source address mode, immediates, operations with non 32-bit modes,
787 * The resulting data is filled into the @p am struct. block is the block
788 * of the node whose arguments are matched. op1, op2 are the first and second
789 * input that are matched (op1 may be NULL). other_op is another unrelated
790 * input that is not matched! but which is needed sometimes to check if AM
791 * for op1/op2 is legal.
792 * @p flags describes the supported modes of the operation in detail.
794 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
795 ir_node *op1, ir_node *op2, ir_node *other_op,
798 ia32_address_t *addr = &am->addr;
799 ir_mode *mode = get_irn_mode(op2);
800 int mode_bits = get_mode_size_bits(mode);
801 ir_node *noreg_gp, *new_op1, *new_op2;
803 unsigned commutative;
804 int use_am_and_immediates;
807 memset(am, 0, sizeof(am[0]));
809 commutative = (flags & match_commutative) != 0;
810 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
811 use_am = (flags & match_am) != 0;
812 use_immediate = (flags & match_immediate) != 0;
813 assert(!use_am_and_immediates || use_immediate);
816 assert(!commutative || op1 != NULL);
817 assert(use_am || !(flags & match_8bit_am));
818 assert(use_am || !(flags & match_16bit_am));
820 if (mode_bits == 8) {
821 if (!(flags & match_8bit_am))
823 /* we don't automatically add upconvs yet */
824 assert((flags & match_mode_neutral) || (flags & match_8bit));
825 } else if (mode_bits == 16) {
826 if (!(flags & match_16bit_am))
828 /* we don't automatically add upconvs yet */
829 assert((flags & match_mode_neutral) || (flags & match_16bit));
832 /* we can simply skip downconvs for mode neutral nodes: the upper bits
833 * can be random for these operations */
834 if (flags & match_mode_neutral) {
835 op2 = ia32_skip_downconv(op2);
837 op1 = ia32_skip_downconv(op1);
841 /* match immediates. firm nodes are normalized: constants are always on the
844 if (!(flags & match_try_am) && use_immediate) {
845 new_op2 = try_create_Immediate(op2, 0);
848 noreg_gp = ia32_new_NoReg_gp(env_cg);
849 if (new_op2 == NULL &&
850 use_am && ia32_use_source_address_mode(block, op2, op1, other_op)) {
851 build_address(am, op2);
852 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
853 if (mode_is_float(mode)) {
854 new_op2 = ia32_new_NoReg_vfp(env_cg);
858 am->op_type = ia32_AddrModeS;
859 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
861 ia32_use_source_address_mode(block, op1, op2, other_op)) {
863 build_address(am, op1);
865 if (mode_is_float(mode)) {
866 noreg = ia32_new_NoReg_vfp(env_cg);
871 if (new_op2 != NULL) {
874 new_op1 = be_transform_node(op2);
876 am->ins_permuted = 1;
878 am->op_type = ia32_AddrModeS;
880 if (flags & match_try_am) {
883 am->op_type = ia32_Normal;
887 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
889 new_op2 = be_transform_node(op2);
890 am->op_type = ia32_Normal;
891 am->ls_mode = get_irn_mode(op2);
892 if (flags & match_mode_neutral)
893 am->ls_mode = mode_Iu;
895 if (addr->base == NULL)
896 addr->base = noreg_gp;
897 if (addr->index == NULL)
898 addr->index = noreg_gp;
899 if (addr->mem == NULL)
900 addr->mem = new_NoMem();
902 am->new_op1 = new_op1;
903 am->new_op2 = new_op2;
904 am->commutative = commutative;
907 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
912 if (am->mem_proj == NULL)
915 /* we have to create a mode_T so the old MemProj can attach to us */
916 mode = get_irn_mode(node);
917 load = get_Proj_pred(am->mem_proj);
919 mark_irn_visited(load);
920 be_set_transformed_node(load, node);
922 if (mode != mode_T) {
923 set_irn_mode(node, mode_T);
924 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
931 * Construct a standard binary operation, set AM and immediate if required.
933 * @param op1 The first operand
934 * @param op2 The second operand
935 * @param func The node constructor function
936 * @return The constructed ia32 node.
938 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
939 construct_binop_func *func, match_flags_t flags)
942 ir_node *block, *new_block, *new_node;
943 ia32_address_mode_t am;
944 ia32_address_t *addr = &am.addr;
946 block = get_nodes_block(node);
947 match_arguments(&am, block, op1, op2, NULL, flags);
949 dbgi = get_irn_dbg_info(node);
950 new_block = be_transform_node(block);
951 new_node = func(dbgi, current_ir_graph, new_block,
952 addr->base, addr->index, addr->mem,
953 am.new_op1, am.new_op2);
954 set_am_attributes(new_node, &am);
955 /* we can't use source address mode anymore when using immediates */
956 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
957 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
958 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
960 new_node = fix_mem_proj(new_node, &am);
967 n_ia32_l_binop_right,
968 n_ia32_l_binop_eflags
970 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
971 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
972 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
973 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
974 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
975 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
978 * Construct a binary operation which also consumes the eflags.
980 * @param node The node to transform
981 * @param func The node constructor function
982 * @param flags The match flags
983 * @return The constructor ia32 node
985 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
988 ir_node *src_block = get_nodes_block(node);
989 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
990 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
992 ir_node *block, *new_node, *eflags, *new_eflags;
993 ia32_address_mode_t am;
994 ia32_address_t *addr = &am.addr;
996 match_arguments(&am, src_block, op1, op2, NULL, flags);
998 dbgi = get_irn_dbg_info(node);
999 block = be_transform_node(src_block);
1000 eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1001 new_eflags = be_transform_node(eflags);
1002 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
1003 addr->mem, am.new_op1, am.new_op2, new_eflags);
1004 set_am_attributes(new_node, &am);
1005 /* we can't use source address mode anymore when using immediates */
1006 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1007 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1008 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1010 new_node = fix_mem_proj(new_node, &am);
1015 static ir_node *get_fpcw(void)
1018 if (initial_fpcw != NULL)
1019 return initial_fpcw;
1021 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
1022 &ia32_fp_cw_regs[REG_FPCW]);
1023 initial_fpcw = be_transform_node(fpcw);
1025 return initial_fpcw;
1029 * Construct a standard binary operation, set AM and immediate if required.
1031 * @param op1 The first operand
1032 * @param op2 The second operand
1033 * @param func The node constructor function
1034 * @return The constructed ia32 node.
1036 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1037 construct_binop_float_func *func,
1038 match_flags_t flags)
1040 ir_mode *mode = get_irn_mode(node);
1042 ir_node *block, *new_block, *new_node;
1043 ia32_address_mode_t am;
1044 ia32_address_t *addr = &am.addr;
1046 /* cannot use address mode with long double on x87 */
1047 if (get_mode_size_bits(mode) > 64)
1050 block = get_nodes_block(node);
1051 match_arguments(&am, block, op1, op2, NULL, flags);
1053 dbgi = get_irn_dbg_info(node);
1054 new_block = be_transform_node(block);
1055 new_node = func(dbgi, current_ir_graph, new_block,
1056 addr->base, addr->index, addr->mem,
1057 am.new_op1, am.new_op2, get_fpcw());
1058 set_am_attributes(new_node, &am);
1060 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1062 new_node = fix_mem_proj(new_node, &am);
1068 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1070 * @param op1 The first operand
1071 * @param op2 The second operand
1072 * @param func The node constructor function
1073 * @return The constructed ia32 node.
1075 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1076 construct_shift_func *func,
1077 match_flags_t flags)
1080 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1082 assert(! mode_is_float(get_irn_mode(node)));
1083 assert(flags & match_immediate);
1084 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1086 if (flags & match_mode_neutral) {
1087 op1 = ia32_skip_downconv(op1);
1088 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1089 panic("right shifting of non-32bit values not supported, yet");
1091 new_op1 = be_transform_node(op1);
1093 /* the shift amount can be any mode that is bigger than 5 bits, since all
1094 * other bits are ignored anyway */
1095 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1096 op2 = get_Conv_op(op2);
1097 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1099 new_op2 = create_immediate_or_transform(op2, 0);
1101 dbgi = get_irn_dbg_info(node);
1102 block = get_nodes_block(node);
1103 new_block = be_transform_node(block);
1104 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1105 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1107 /* lowered shift instruction may have a dependency operand, handle it here */
1108 if (get_irn_arity(node) == 3) {
1109 /* we have a dependency */
1110 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1111 add_irn_dep(new_node, new_dep);
1119 * Construct a standard unary operation, set AM and immediate if required.
1121 * @param op The operand
1122 * @param func The node constructor function
1123 * @return The constructed ia32 node.
1125 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1126 match_flags_t flags)
1129 ir_node *block, *new_block, *new_op, *new_node;
1131 assert(flags == 0 || flags == match_mode_neutral);
1132 if (flags & match_mode_neutral) {
1133 op = ia32_skip_downconv(op);
1136 new_op = be_transform_node(op);
1137 dbgi = get_irn_dbg_info(node);
1138 block = get_nodes_block(node);
1139 new_block = be_transform_node(block);
1140 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1142 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1147 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1148 ia32_address_t *addr)
1150 ir_node *base, *index, *res;
1154 base = ia32_new_NoReg_gp(env_cg);
1156 base = be_transform_node(base);
1159 index = addr->index;
1160 if (index == NULL) {
1161 index = ia32_new_NoReg_gp(env_cg);
1163 index = be_transform_node(index);
1166 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1167 set_address(res, addr);
1173 * Returns non-zero if a given address mode has a symbolic or
1174 * numerical offset != 0.
1176 static int am_has_immediates(const ia32_address_t *addr)
1178 return addr->offset != 0 || addr->symconst_ent != NULL
1179 || addr->frame_entity || addr->use_frame;
1183 * Creates an ia32 Add.
1185 * @return the created ia32 Add node
1187 static ir_node *gen_Add(ir_node *node) {
1188 ir_mode *mode = get_irn_mode(node);
1189 ir_node *op1 = get_Add_left(node);
1190 ir_node *op2 = get_Add_right(node);
1192 ir_node *block, *new_block, *new_node, *add_immediate_op;
1193 ia32_address_t addr;
1194 ia32_address_mode_t am;
1196 if (mode_is_float(mode)) {
1197 if (ia32_cg_config.use_sse2)
1198 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1199 match_commutative | match_am);
1201 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1202 match_commutative | match_am);
1205 ia32_mark_non_am(node);
1207 op2 = ia32_skip_downconv(op2);
1208 op1 = ia32_skip_downconv(op1);
1212 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1213 * 1. Add with immediate -> Lea
1214 * 2. Add with possible source address mode -> Add
1215 * 3. Otherwise -> Lea
1217 memset(&addr, 0, sizeof(addr));
1218 ia32_create_address_mode(&addr, node, /*force=*/1);
1219 add_immediate_op = NULL;
1221 dbgi = get_irn_dbg_info(node);
1222 block = get_nodes_block(node);
1223 new_block = be_transform_node(block);
1226 if(addr.base == NULL && addr.index == NULL) {
1227 ir_graph *irg = current_ir_graph;
1228 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1229 addr.symconst_sign, addr.offset);
1230 add_irn_dep(new_node, get_irg_frame(irg));
1231 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1234 /* add with immediate? */
1235 if(addr.index == NULL) {
1236 add_immediate_op = addr.base;
1237 } else if(addr.base == NULL && addr.scale == 0) {
1238 add_immediate_op = addr.index;
1241 if(add_immediate_op != NULL) {
1242 if(!am_has_immediates(&addr)) {
1243 #ifdef DEBUG_libfirm
1244 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1247 return be_transform_node(add_immediate_op);
1250 new_node = create_lea_from_address(dbgi, new_block, &addr);
1251 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1255 /* test if we can use source address mode */
1256 match_arguments(&am, block, op1, op2, NULL, match_commutative
1257 | match_mode_neutral | match_am | match_immediate | match_try_am);
1259 /* construct an Add with source address mode */
1260 if (am.op_type == ia32_AddrModeS) {
1261 ir_graph *irg = current_ir_graph;
1262 ia32_address_t *am_addr = &am.addr;
1263 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1264 am_addr->index, am_addr->mem, am.new_op1,
1266 set_am_attributes(new_node, &am);
1267 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1269 new_node = fix_mem_proj(new_node, &am);
1274 /* otherwise construct a lea */
1275 new_node = create_lea_from_address(dbgi, new_block, &addr);
1276 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1281 * Creates an ia32 Mul.
1283 * @return the created ia32 Mul node
1285 static ir_node *gen_Mul(ir_node *node) {
1286 ir_node *op1 = get_Mul_left(node);
1287 ir_node *op2 = get_Mul_right(node);
1288 ir_mode *mode = get_irn_mode(node);
1290 if (mode_is_float(mode)) {
1291 if (ia32_cg_config.use_sse2)
1292 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1293 match_commutative | match_am);
1295 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1296 match_commutative | match_am);
1298 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1299 match_commutative | match_am | match_mode_neutral |
1300 match_immediate | match_am_and_immediates);
1304 * Creates an ia32 Mulh.
1305 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1306 * this result while Mul returns the lower 32 bit.
1308 * @return the created ia32 Mulh node
1310 static ir_node *gen_Mulh(ir_node *node)
1312 ir_node *block = get_nodes_block(node);
1313 ir_node *new_block = be_transform_node(block);
1314 ir_graph *irg = current_ir_graph;
1315 dbg_info *dbgi = get_irn_dbg_info(node);
1316 ir_mode *mode = get_irn_mode(node);
1317 ir_node *op1 = get_Mulh_left(node);
1318 ir_node *op2 = get_Mulh_right(node);
1319 ir_node *proj_res_high;
1321 ia32_address_mode_t am;
1322 ia32_address_t *addr = &am.addr;
1324 assert(!mode_is_float(mode) && "Mulh with float not supported");
1325 assert(get_mode_size_bits(mode) == 32);
1327 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1329 if (mode_is_signed(mode)) {
1330 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1331 addr->index, addr->mem, am.new_op1,
1334 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1335 addr->index, addr->mem, am.new_op1,
1339 set_am_attributes(new_node, &am);
1340 /* we can't use source address mode anymore when using immediates */
1341 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1342 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1343 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1345 assert(get_irn_mode(new_node) == mode_T);
1347 fix_mem_proj(new_node, &am);
1349 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1350 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1351 mode_Iu, pn_ia32_IMul1OP_res_high);
1353 return proj_res_high;
1359 * Creates an ia32 And.
1361 * @return The created ia32 And node
1363 static ir_node *gen_And(ir_node *node) {
1364 ir_node *op1 = get_And_left(node);
1365 ir_node *op2 = get_And_right(node);
1366 assert(! mode_is_float(get_irn_mode(node)));
1368 /* is it a zero extension? */
1369 if (is_Const(op2)) {
1370 tarval *tv = get_Const_tarval(op2);
1371 long v = get_tarval_long(tv);
1373 if (v == 0xFF || v == 0xFFFF) {
1374 dbg_info *dbgi = get_irn_dbg_info(node);
1375 ir_node *block = get_nodes_block(node);
1382 assert(v == 0xFFFF);
1385 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1390 return gen_binop(node, op1, op2, new_rd_ia32_And,
1391 match_commutative | match_mode_neutral | match_am
1398 * Creates an ia32 Or.
1400 * @return The created ia32 Or node
1402 static ir_node *gen_Or(ir_node *node) {
1403 ir_node *op1 = get_Or_left(node);
1404 ir_node *op2 = get_Or_right(node);
1406 assert (! mode_is_float(get_irn_mode(node)));
1407 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1408 | match_mode_neutral | match_am | match_immediate);
1414 * Creates an ia32 Eor.
1416 * @return The created ia32 Eor node
1418 static ir_node *gen_Eor(ir_node *node) {
1419 ir_node *op1 = get_Eor_left(node);
1420 ir_node *op2 = get_Eor_right(node);
1422 assert(! mode_is_float(get_irn_mode(node)));
1423 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1424 | match_mode_neutral | match_am | match_immediate);
1429 * Creates an ia32 Sub.
1431 * @return The created ia32 Sub node
1433 static ir_node *gen_Sub(ir_node *node) {
1434 ir_node *op1 = get_Sub_left(node);
1435 ir_node *op2 = get_Sub_right(node);
1436 ir_mode *mode = get_irn_mode(node);
1438 if (mode_is_float(mode)) {
1439 if (ia32_cg_config.use_sse2)
1440 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1442 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1446 if (is_Const(op2)) {
1447 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1451 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1452 | match_am | match_immediate);
1456 * Generates an ia32 DivMod with additional infrastructure for the
1457 * register allocator if needed.
1459 static ir_node *create_Div(ir_node *node)
1461 ir_graph *irg = current_ir_graph;
1462 dbg_info *dbgi = get_irn_dbg_info(node);
1463 ir_node *block = get_nodes_block(node);
1464 ir_node *new_block = be_transform_node(block);
1471 ir_node *sign_extension;
1472 ia32_address_mode_t am;
1473 ia32_address_t *addr = &am.addr;
1475 /* the upper bits have random contents for smaller modes */
1476 switch (get_irn_opcode(node)) {
1478 op1 = get_Div_left(node);
1479 op2 = get_Div_right(node);
1480 mem = get_Div_mem(node);
1481 mode = get_Div_resmode(node);
1484 op1 = get_Mod_left(node);
1485 op2 = get_Mod_right(node);
1486 mem = get_Mod_mem(node);
1487 mode = get_Mod_resmode(node);
1490 op1 = get_DivMod_left(node);
1491 op2 = get_DivMod_right(node);
1492 mem = get_DivMod_mem(node);
1493 mode = get_DivMod_resmode(node);
1496 panic("invalid divmod node %+F", node);
1499 match_arguments(&am, block, op1, op2, NULL, match_am);
1501 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1502 is the memory of the consumed address. We can have only the second op as address
1503 in Div nodes, so check only op2. */
1504 if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1505 new_mem = be_transform_node(mem);
1506 if(!is_NoMem(addr->mem)) {
1510 new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1513 new_mem = addr->mem;
1516 if (mode_is_signed(mode)) {
1517 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1518 add_irn_dep(produceval, get_irg_frame(irg));
1519 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1522 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1523 addr->index, new_mem, am.new_op2,
1524 am.new_op1, sign_extension);
1526 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1527 add_irn_dep(sign_extension, get_irg_frame(irg));
1529 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1530 addr->index, new_mem, am.new_op2,
1531 am.new_op1, sign_extension);
1534 set_irn_pinned(new_node, get_irn_pinned(node));
1536 set_am_attributes(new_node, &am);
1537 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1539 new_node = fix_mem_proj(new_node, &am);
1545 static ir_node *gen_Mod(ir_node *node) {
1546 return create_Div(node);
1549 static ir_node *gen_Div(ir_node *node) {
1550 return create_Div(node);
1553 static ir_node *gen_DivMod(ir_node *node) {
1554 return create_Div(node);
1560 * Creates an ia32 floating Div.
1562 * @return The created ia32 xDiv node
1564 static ir_node *gen_Quot(ir_node *node)
1566 ir_node *op1 = get_Quot_left(node);
1567 ir_node *op2 = get_Quot_right(node);
1569 if (ia32_cg_config.use_sse2) {
1570 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1572 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1578 * Creates an ia32 Shl.
1580 * @return The created ia32 Shl node
1582 static ir_node *gen_Shl(ir_node *node) {
1583 ir_node *left = get_Shl_left(node);
1584 ir_node *right = get_Shl_right(node);
1586 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1587 match_mode_neutral | match_immediate);
1591 * Creates an ia32 Shr.
1593 * @return The created ia32 Shr node
1595 static ir_node *gen_Shr(ir_node *node) {
1596 ir_node *left = get_Shr_left(node);
1597 ir_node *right = get_Shr_right(node);
1599 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1605 * Creates an ia32 Sar.
1607 * @return The created ia32 Shrs node
1609 static ir_node *gen_Shrs(ir_node *node) {
1610 ir_node *left = get_Shrs_left(node);
1611 ir_node *right = get_Shrs_right(node);
1612 ir_mode *mode = get_irn_mode(node);
1614 if(is_Const(right) && mode == mode_Is) {
1615 tarval *tv = get_Const_tarval(right);
1616 long val = get_tarval_long(tv);
1618 /* this is a sign extension */
1619 ir_graph *irg = current_ir_graph;
1620 dbg_info *dbgi = get_irn_dbg_info(node);
1621 ir_node *block = be_transform_node(get_nodes_block(node));
1623 ir_node *new_op = be_transform_node(op);
1624 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1625 add_irn_dep(pval, get_irg_frame(irg));
1627 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1631 /* 8 or 16 bit sign extension? */
1632 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1633 ir_node *shl_left = get_Shl_left(left);
1634 ir_node *shl_right = get_Shl_right(left);
1635 if(is_Const(shl_right)) {
1636 tarval *tv1 = get_Const_tarval(right);
1637 tarval *tv2 = get_Const_tarval(shl_right);
1638 if(tv1 == tv2 && tarval_is_long(tv1)) {
1639 long val = get_tarval_long(tv1);
1640 if(val == 16 || val == 24) {
1641 dbg_info *dbgi = get_irn_dbg_info(node);
1642 ir_node *block = get_nodes_block(node);
1652 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1661 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1667 * Creates an ia32 RotL.
1669 * @param op1 The first operator
1670 * @param op2 The second operator
1671 * @return The created ia32 RotL node
1673 static ir_node *gen_RotL(ir_node *node, ir_node *op1, ir_node *op2) {
1674 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1680 * Creates an ia32 RotR.
1681 * NOTE: There is no RotR with immediate because this would always be a RotL
1682 * "imm-mode_size_bits" which can be pre-calculated.
1684 * @param op1 The first operator
1685 * @param op2 The second operator
1686 * @return The created ia32 RotR node
1688 static ir_node *gen_RotR(ir_node *node, ir_node *op1, ir_node *op2) {
1689 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1695 * Creates an ia32 RotR or RotL (depending on the found pattern).
1697 * @return The created ia32 RotL or RotR node
1699 static ir_node *gen_Rot(ir_node *node) {
1700 ir_node *rotate = NULL;
1701 ir_node *op1 = get_Rot_left(node);
1702 ir_node *op2 = get_Rot_right(node);
1704 /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
1705 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1706 that means we can create a RotR instead of an Add and a RotL */
1708 if (get_irn_op(op2) == op_Add) {
1710 ir_node *left = get_Add_left(add);
1711 ir_node *right = get_Add_right(add);
1712 if (is_Const(right)) {
1713 tarval *tv = get_Const_tarval(right);
1714 ir_mode *mode = get_irn_mode(node);
1715 long bits = get_mode_size_bits(mode);
1717 if (get_irn_op(left) == op_Minus &&
1718 tarval_is_long(tv) &&
1719 get_tarval_long(tv) == bits &&
1722 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1723 rotate = gen_RotR(node, op1, get_Minus_op(left));
1728 if (rotate == NULL) {
1729 rotate = gen_RotL(node, op1, op2);
1738 * Transforms a Minus node.
1740 * @return The created ia32 Minus node
1742 static ir_node *gen_Minus(ir_node *node)
1744 ir_node *op = get_Minus_op(node);
1745 ir_node *block = be_transform_node(get_nodes_block(node));
1746 ir_graph *irg = current_ir_graph;
1747 dbg_info *dbgi = get_irn_dbg_info(node);
1748 ir_mode *mode = get_irn_mode(node);
1753 if (mode_is_float(mode)) {
1754 ir_node *new_op = be_transform_node(op);
1755 if (ia32_cg_config.use_sse2) {
1756 /* TODO: non-optimal... if we have many xXors, then we should
1757 * rather create a load for the const and use that instead of
1758 * several AM nodes... */
1759 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1760 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1761 ir_node *nomem = new_rd_NoMem(irg);
1763 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1764 nomem, new_op, noreg_xmm);
1766 size = get_mode_size_bits(mode);
1767 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1769 set_ia32_am_sc(new_node, ent);
1770 set_ia32_op_type(new_node, ia32_AddrModeS);
1771 set_ia32_ls_mode(new_node, mode);
1773 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1776 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1779 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1785 * Transforms a Not node.
1787 * @return The created ia32 Not node
1789 static ir_node *gen_Not(ir_node *node) {
1790 ir_node *op = get_Not_op(node);
1792 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1793 assert (! mode_is_float(get_irn_mode(node)));
1795 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1801 * Transforms an Abs node.
1803 * @return The created ia32 Abs node
1805 static ir_node *gen_Abs(ir_node *node)
1807 ir_node *block = get_nodes_block(node);
1808 ir_node *new_block = be_transform_node(block);
1809 ir_node *op = get_Abs_op(node);
1810 ir_graph *irg = current_ir_graph;
1811 dbg_info *dbgi = get_irn_dbg_info(node);
1812 ir_mode *mode = get_irn_mode(node);
1813 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1814 ir_node *nomem = new_NoMem();
1820 if (mode_is_float(mode)) {
1821 new_op = be_transform_node(op);
1823 if (ia32_cg_config.use_sse2) {
1824 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1825 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1826 nomem, new_op, noreg_fp);
1828 size = get_mode_size_bits(mode);
1829 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1831 set_ia32_am_sc(new_node, ent);
1833 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1835 set_ia32_op_type(new_node, ia32_AddrModeS);
1836 set_ia32_ls_mode(new_node, mode);
1838 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1839 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1842 ir_node *xor, *pval, *sign_extension;
1844 if (get_mode_size_bits(mode) == 32) {
1845 new_op = be_transform_node(op);
1847 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1850 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1851 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1854 add_irn_dep(pval, get_irg_frame(irg));
1855 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1857 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1858 nomem, new_op, sign_extension);
1859 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1861 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1862 nomem, xor, sign_extension);
1863 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1870 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1872 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1873 dbg_info *dbgi = get_irn_dbg_info(cmp);
1874 ir_node *block = get_nodes_block(cmp);
1875 ir_node *new_block = be_transform_node(block);
1876 ir_node *op1 = be_transform_node(x);
1877 ir_node *op2 = be_transform_node(n);
1879 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1883 * Transform a node returning a "flag" result.
1885 * @param node the node to transform
1886 * @param pnc_out the compare mode to use
1888 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1897 /* we have a Cmp as input */
1898 if (is_Proj(node)) {
1899 ir_node *pred = get_Proj_pred(node);
1901 pn_Cmp pnc = get_Proj_proj(node);
1902 if (pnc == pn_Cmp_Lg && ia32_cg_config.use_bt) {
1903 ir_node *l = get_Cmp_left(pred);
1905 ir_node *la = get_And_left(l);
1906 ir_node *ra = get_And_right(l);
1908 ir_node *c = get_Shl_left(la);
1909 if (is_Const_1(c)) {
1910 /* (1 << n) & ra) */
1911 ir_node *n = get_Shl_right(la);
1912 flags = gen_bt(pred, ra, n);
1913 /* we must generate a Jc jump */
1914 *pnc_out = ia32_pn_Cmp_unsigned|pn_Cmp_Ge;
1919 ir_node *c = get_Shl_left(ra);
1920 if (is_Const_1(c)) {
1921 /* la & (1 << n)) */
1922 ir_node *n = get_Shl_right(ra);
1923 flags = gen_bt(pred, la, n);
1924 /* we must generate a Jc jump */
1925 *pnc_out = ia32_pn_Cmp_unsigned|pn_Cmp_Ge;
1931 flags = be_transform_node(pred);
1937 /* a mode_b value, we have to compare it against 0 */
1938 dbgi = get_irn_dbg_info(node);
1939 new_block = be_transform_node(get_nodes_block(node));
1940 new_op = be_transform_node(node);
1941 noreg = ia32_new_NoReg_gp(env_cg);
1942 nomem = new_NoMem();
1943 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1944 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1945 *pnc_out = pn_Cmp_Lg;
1950 * Transforms a Load.
1952 * @return the created ia32 Load node
1954 static ir_node *gen_Load(ir_node *node) {
1955 ir_node *old_block = get_nodes_block(node);
1956 ir_node *block = be_transform_node(old_block);
1957 ir_node *ptr = get_Load_ptr(node);
1958 ir_node *mem = get_Load_mem(node);
1959 ir_node *new_mem = be_transform_node(mem);
1962 ir_graph *irg = current_ir_graph;
1963 dbg_info *dbgi = get_irn_dbg_info(node);
1964 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1965 ir_mode *mode = get_Load_mode(node);
1968 ia32_address_t addr;
1970 /* construct load address */
1971 memset(&addr, 0, sizeof(addr));
1972 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1979 base = be_transform_node(base);
1985 index = be_transform_node(index);
1988 if (mode_is_float(mode)) {
1989 if (ia32_cg_config.use_sse2) {
1990 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1992 res_mode = mode_xmm;
1994 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1996 res_mode = mode_vfp;
1999 assert(mode != mode_b);
2001 /* create a conv node with address mode for smaller modes */
2002 if(get_mode_size_bits(mode) < 32) {
2003 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
2004 new_mem, noreg, mode);
2006 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
2011 set_irn_pinned(new_node, get_irn_pinned(node));
2012 set_ia32_op_type(new_node, ia32_AddrModeS);
2013 set_ia32_ls_mode(new_node, mode);
2014 set_address(new_node, &addr);
2016 if(get_irn_pinned(node) == op_pin_state_floats) {
2017 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
2020 /* make sure we are scheduled behind the initial IncSP/Barrier
2021 * to avoid spills being placed before it
2023 if (block == get_irg_start_block(irg)) {
2024 add_irn_dep(new_node, get_irg_frame(irg));
2027 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2032 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2033 ir_node *ptr, ir_node *other)
2040 /* we only use address mode if we're the only user of the load */
2041 if(get_irn_n_edges(node) > 1)
2044 load = get_Proj_pred(node);
2047 if(get_nodes_block(load) != block)
2050 /* Store should be attached to the load */
2051 if(!is_Proj(mem) || get_Proj_pred(mem) != load)
2053 /* store should have the same pointer as the load */
2054 if(get_Load_ptr(load) != ptr)
2057 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2058 if(other != NULL && get_nodes_block(other) == block
2059 && heights_reachable_in_block(heights, other, load))
2065 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2066 ir_node *mem, ir_node *ptr, ir_mode *mode,
2067 construct_binop_dest_func *func,
2068 construct_binop_dest_func *func8bit,
2069 match_flags_t flags)
2071 ir_node *src_block = get_nodes_block(node);
2073 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2074 ir_graph *irg = current_ir_graph;
2079 ia32_address_mode_t am;
2080 ia32_address_t *addr = &am.addr;
2081 memset(&am, 0, sizeof(am));
2083 assert(flags & match_dest_am);
2084 assert(flags & match_immediate); /* there is no destam node without... */
2085 commutative = (flags & match_commutative) != 0;
2087 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2088 build_address(&am, op1);
2089 new_op = create_immediate_or_transform(op2, 0);
2090 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2091 build_address(&am, op2);
2092 new_op = create_immediate_or_transform(op1, 0);
2097 if(addr->base == NULL)
2098 addr->base = noreg_gp;
2099 if(addr->index == NULL)
2100 addr->index = noreg_gp;
2101 if(addr->mem == NULL)
2102 addr->mem = new_NoMem();
2104 dbgi = get_irn_dbg_info(node);
2105 block = be_transform_node(src_block);
2106 if(get_mode_size_bits(mode) == 8) {
2107 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2110 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
2113 set_address(new_node, addr);
2114 set_ia32_op_type(new_node, ia32_AddrModeD);
2115 set_ia32_ls_mode(new_node, mode);
2116 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2121 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2122 ir_node *ptr, ir_mode *mode,
2123 construct_unop_dest_func *func)
2125 ir_graph *irg = current_ir_graph;
2126 ir_node *src_block = get_nodes_block(node);
2130 ia32_address_mode_t am;
2131 ia32_address_t *addr = &am.addr;
2132 memset(&am, 0, sizeof(am));
2134 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2137 build_address(&am, op);
2139 dbgi = get_irn_dbg_info(node);
2140 block = be_transform_node(src_block);
2141 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2142 set_address(new_node, addr);
2143 set_ia32_op_type(new_node, ia32_AddrModeD);
2144 set_ia32_ls_mode(new_node, mode);
2145 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2150 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2151 ir_mode *mode = get_irn_mode(node);
2152 ir_node *psi_true = get_Psi_val(node, 0);
2153 ir_node *psi_default = get_Psi_default(node);
2164 ia32_address_t addr;
2166 if(get_mode_size_bits(mode) != 8)
2169 if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2171 } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2177 build_address_ptr(&addr, ptr, mem);
2179 irg = current_ir_graph;
2180 dbgi = get_irn_dbg_info(node);
2181 block = get_nodes_block(node);
2182 new_block = be_transform_node(block);
2183 cond = get_Psi_cond(node, 0);
2184 flags = get_flags_node(cond, &pnc);
2185 new_mem = be_transform_node(mem);
2186 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2187 addr.index, addr.mem, flags, pnc, negated);
2188 set_address(new_node, &addr);
2189 set_ia32_op_type(new_node, ia32_AddrModeD);
2190 set_ia32_ls_mode(new_node, mode);
2191 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2196 static ir_node *try_create_dest_am(ir_node *node) {
2197 ir_node *val = get_Store_value(node);
2198 ir_node *mem = get_Store_mem(node);
2199 ir_node *ptr = get_Store_ptr(node);
2200 ir_mode *mode = get_irn_mode(val);
2201 unsigned bits = get_mode_size_bits(mode);
2206 /* handle only GP modes for now... */
2207 if(!mode_needs_gp_reg(mode))
2211 /* store must be the only user of the val node */
2212 if(get_irn_n_edges(val) > 1)
2214 /* skip pointless convs */
2216 ir_node *conv_op = get_Conv_op(val);
2217 ir_mode *pred_mode = get_irn_mode(conv_op);
2218 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2226 /* value must be in the same block */
2227 if(get_nodes_block(node) != get_nodes_block(val))
2230 switch(get_irn_opcode(val)) {
2232 op1 = get_Add_left(val);
2233 op2 = get_Add_right(val);
2234 if(is_Const_1(op2)) {
2235 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2236 new_rd_ia32_IncMem);
2238 } else if(is_Const_Minus_1(op2)) {
2239 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2240 new_rd_ia32_DecMem);
2243 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2244 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2245 match_dest_am | match_commutative |
2249 op1 = get_Sub_left(val);
2250 op2 = get_Sub_right(val);
2252 ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2255 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2256 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2257 match_dest_am | match_immediate |
2261 op1 = get_And_left(val);
2262 op2 = get_And_right(val);
2263 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2264 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2265 match_dest_am | match_commutative |
2269 op1 = get_Or_left(val);
2270 op2 = get_Or_right(val);
2271 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2272 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2273 match_dest_am | match_commutative |
2277 op1 = get_Eor_left(val);
2278 op2 = get_Eor_right(val);
2279 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2280 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2281 match_dest_am | match_commutative |
2285 op1 = get_Shl_left(val);
2286 op2 = get_Shl_right(val);
2287 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2288 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2289 match_dest_am | match_immediate);
2292 op1 = get_Shr_left(val);
2293 op2 = get_Shr_right(val);
2294 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2295 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2296 match_dest_am | match_immediate);
2299 op1 = get_Shrs_left(val);
2300 op2 = get_Shrs_right(val);
2301 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2302 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2303 match_dest_am | match_immediate);
2306 op1 = get_Rot_left(val);
2307 op2 = get_Rot_right(val);
2308 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2309 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2310 match_dest_am | match_immediate);
2312 /* TODO: match ROR patterns... */
2314 new_node = try_create_SetMem(val, ptr, mem);
2317 op1 = get_Minus_op(val);
2318 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2321 /* should be lowered already */
2322 assert(mode != mode_b);
2323 op1 = get_Not_op(val);
2324 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2330 if(new_node != NULL) {
2331 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2332 get_irn_pinned(node) == op_pin_state_pinned) {
2333 set_irn_pinned(new_node, op_pin_state_pinned);
2340 static int is_float_to_int32_conv(const ir_node *node)
2342 ir_mode *mode = get_irn_mode(node);
2346 if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode))
2351 conv_op = get_Conv_op(node);
2352 conv_mode = get_irn_mode(conv_op);
2354 if(!mode_is_float(conv_mode))
2361 * Transform a Store(floatConst).
2363 * @return the created ia32 Store node
2365 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2366 ir_mode *mode = get_irn_mode(cns);
2367 int size = get_mode_size_bits(mode);
2368 tarval *tv = get_Const_tarval(cns);
2369 ir_node *block = get_nodes_block(node);
2370 ir_node *new_block = be_transform_node(block);
2371 ir_node *ptr = get_Store_ptr(node);
2372 ir_node *mem = get_Store_mem(node);
2373 ir_graph *irg = current_ir_graph;
2374 dbg_info *dbgi = get_irn_dbg_info(node);
2375 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2378 ia32_address_t addr;
2380 unsigned val = get_tarval_sub_bits(tv, 0) |
2381 (get_tarval_sub_bits(tv, 1) << 8) |
2382 (get_tarval_sub_bits(tv, 2) << 16) |
2383 (get_tarval_sub_bits(tv, 3) << 24);
2384 ir_node *imm = create_Immediate(NULL, 0, val);
2386 /* construct store address */
2387 memset(&addr, 0, sizeof(addr));
2388 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2390 if (addr.base == NULL) {
2393 addr.base = be_transform_node(addr.base);
2396 if (addr.index == NULL) {
2399 addr.index = be_transform_node(addr.index);
2401 addr.mem = be_transform_node(mem);
2403 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2404 addr.index, addr.mem, imm);
2406 set_irn_pinned(new_node, get_irn_pinned(node));
2407 set_ia32_op_type(new_node, ia32_AddrModeD);
2408 set_ia32_ls_mode(new_node, mode_Iu);
2410 set_address(new_node, &addr);
2412 /** add more stores if needed */
2414 unsigned val = get_tarval_sub_bits(tv, ofs) |
2415 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2416 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2417 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2418 ir_node *imm = create_Immediate(NULL, 0, val);
2421 addr.mem = new_node;
2423 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2424 addr.index, addr.mem, imm);
2426 set_irn_pinned(new_node, get_irn_pinned(node));
2427 set_ia32_op_type(new_node, ia32_AddrModeD);
2428 set_ia32_ls_mode(new_node, mode_Iu);
2430 set_address(new_node, &addr);
2435 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2440 * Transforms a normal Store.
2442 * @return the created ia32 Store node
2444 static ir_node *gen_normal_Store(ir_node *node)
2446 ir_node *val = get_Store_value(node);
2447 ir_mode *mode = get_irn_mode(val);
2448 ir_node *block = get_nodes_block(node);
2449 ir_node *new_block = be_transform_node(block);
2450 ir_node *ptr = get_Store_ptr(node);
2451 ir_node *mem = get_Store_mem(node);
2452 ir_graph *irg = current_ir_graph;
2453 dbg_info *dbgi = get_irn_dbg_info(node);
2454 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2457 ia32_address_t addr;
2459 /* check for destination address mode */
2460 new_node = try_create_dest_am(node);
2461 if (new_node != NULL)
2464 /* construct store address */
2465 memset(&addr, 0, sizeof(addr));
2466 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2468 if (addr.base == NULL) {
2471 addr.base = be_transform_node(addr.base);
2474 if (addr.index == NULL) {
2477 addr.index = be_transform_node(addr.index);
2479 addr.mem = be_transform_node(mem);
2481 if (mode_is_float(mode)) {
2482 /* convs (and strict-convs) before stores are unnecessary if the mode
2484 while (is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2485 val = get_Conv_op(val);
2487 new_val = be_transform_node(val);
2488 if (ia32_cg_config.use_sse2) {
2489 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2490 addr.index, addr.mem, new_val);
2492 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2493 addr.index, addr.mem, new_val, mode);
2495 } else if (is_float_to_int32_conv(val)) {
2496 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2497 val = get_Conv_op(val);
2499 /* convs (and strict-convs) before stores are unnecessary if the mode
2501 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2502 val = get_Conv_op(val);
2504 new_val = be_transform_node(val);
2506 new_node = new_rd_ia32_vfist(dbgi, irg, new_block, addr.base,
2507 addr.index, addr.mem, new_val, trunc_mode);
2509 new_val = create_immediate_or_transform(val, 0);
2510 assert(mode != mode_b);
2512 if (get_mode_size_bits(mode) == 8) {
2513 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2514 addr.index, addr.mem, new_val);
2516 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2517 addr.index, addr.mem, new_val);
2521 set_irn_pinned(new_node, get_irn_pinned(node));
2522 set_ia32_op_type(new_node, ia32_AddrModeD);
2523 set_ia32_ls_mode(new_node, mode);
2525 set_address(new_node, &addr);
2526 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2532 * Transforms a Store.
2534 * @return the created ia32 Store node
2536 static ir_node *gen_Store(ir_node *node)
2538 ir_node *val = get_Store_value(node);
2539 ir_mode *mode = get_irn_mode(val);
2541 if (mode_is_float(mode) && is_Const(val)) {
2544 /* we are storing a floating point constant */
2545 if (ia32_cg_config.use_sse2) {
2546 transform = !is_simple_sse_Const(val);
2548 transform = !is_simple_x87_Const(val);
2551 return gen_float_const_Store(node, val);
2553 return gen_normal_Store(node);
2557 * Transforms a Switch.
2559 * @return the created ia32 SwitchJmp node
2561 static ir_node *create_Switch(ir_node *node)
2563 ir_graph *irg = current_ir_graph;
2564 dbg_info *dbgi = get_irn_dbg_info(node);
2565 ir_node *block = be_transform_node(get_nodes_block(node));
2566 ir_node *sel = get_Cond_selector(node);
2567 ir_node *new_sel = be_transform_node(sel);
2568 int switch_min = INT_MAX;
2569 int switch_max = INT_MIN;
2570 long default_pn = get_Cond_defaultProj(node);
2572 const ir_edge_t *edge;
2574 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2576 /* determine the smallest switch case value */
2577 foreach_out_edge(node, edge) {
2578 ir_node *proj = get_edge_src_irn(edge);
2579 long pn = get_Proj_proj(proj);
2580 if(pn == default_pn)
2589 if((unsigned) (switch_max - switch_min) > 256000) {
2590 panic("Size of switch %+F bigger than 256000", node);
2593 if (switch_min != 0) {
2594 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2596 /* if smallest switch case is not 0 we need an additional sub */
2597 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2598 add_ia32_am_offs_int(new_sel, -switch_min);
2599 set_ia32_op_type(new_sel, ia32_AddrModeS);
2601 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2604 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2605 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2611 * Transform a Cond node.
2613 static ir_node *gen_Cond(ir_node *node) {
2614 ir_node *block = get_nodes_block(node);
2615 ir_node *new_block = be_transform_node(block);
2616 ir_graph *irg = current_ir_graph;
2617 dbg_info *dbgi = get_irn_dbg_info(node);
2618 ir_node *sel = get_Cond_selector(node);
2619 ir_mode *sel_mode = get_irn_mode(sel);
2620 ir_node *flags = NULL;
2624 if (sel_mode != mode_b) {
2625 return create_Switch(node);
2628 /* we get flags from a Cmp */
2629 flags = get_flags_node(sel, &pnc);
2631 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2632 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2638 * Transforms a CopyB node.
2640 * @return The transformed node.
2642 static ir_node *gen_CopyB(ir_node *node) {
2643 ir_node *block = be_transform_node(get_nodes_block(node));
2644 ir_node *src = get_CopyB_src(node);
2645 ir_node *new_src = be_transform_node(src);
2646 ir_node *dst = get_CopyB_dst(node);
2647 ir_node *new_dst = be_transform_node(dst);
2648 ir_node *mem = get_CopyB_mem(node);
2649 ir_node *new_mem = be_transform_node(mem);
2650 ir_node *res = NULL;
2651 ir_graph *irg = current_ir_graph;
2652 dbg_info *dbgi = get_irn_dbg_info(node);
2653 int size = get_type_size_bytes(get_CopyB_type(node));
2656 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2657 /* then we need the size explicitly in ECX. */
2658 if (size >= 32 * 4) {
2659 rem = size & 0x3; /* size % 4 */
2662 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2663 add_irn_dep(res, get_irg_frame(irg));
2665 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2668 ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2671 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2674 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2679 static ir_node *gen_be_Copy(ir_node *node)
2681 ir_node *new_node = be_duplicate_node(node);
2682 ir_mode *mode = get_irn_mode(new_node);
2684 if (mode_needs_gp_reg(mode)) {
2685 set_irn_mode(new_node, mode_Iu);
2691 static ir_node *create_Fucom(ir_node *node)
2693 ir_graph *irg = current_ir_graph;
2694 dbg_info *dbgi = get_irn_dbg_info(node);
2695 ir_node *block = get_nodes_block(node);
2696 ir_node *new_block = be_transform_node(block);
2697 ir_node *left = get_Cmp_left(node);
2698 ir_node *new_left = be_transform_node(left);
2699 ir_node *right = get_Cmp_right(node);
2703 if(ia32_cg_config.use_fucomi) {
2704 new_right = be_transform_node(right);
2705 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2707 set_ia32_commutative(new_node);
2708 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2710 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2711 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2714 new_right = be_transform_node(right);
2715 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2719 set_ia32_commutative(new_node);
2721 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2723 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2724 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2730 static ir_node *create_Ucomi(ir_node *node)
2732 ir_graph *irg = current_ir_graph;
2733 dbg_info *dbgi = get_irn_dbg_info(node);
2734 ir_node *src_block = get_nodes_block(node);
2735 ir_node *new_block = be_transform_node(src_block);
2736 ir_node *left = get_Cmp_left(node);
2737 ir_node *right = get_Cmp_right(node);
2739 ia32_address_mode_t am;
2740 ia32_address_t *addr = &am.addr;
2742 match_arguments(&am, src_block, left, right, NULL,
2743 match_commutative | match_am);
2745 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2746 addr->mem, am.new_op1, am.new_op2,
2748 set_am_attributes(new_node, &am);
2750 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2752 new_node = fix_mem_proj(new_node, &am);
2758 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2759 * to fold an and into a test node
2761 static int can_fold_test_and(ir_node *node)
2763 const ir_edge_t *edge;
2765 /** we can only have eq and lg projs */
2766 foreach_out_edge(node, edge) {
2767 ir_node *proj = get_edge_src_irn(edge);
2768 pn_Cmp pnc = get_Proj_proj(proj);
2769 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2777 * Generate code for a Cmp.
2779 static ir_node *gen_Cmp(ir_node *node)
2781 ir_graph *irg = current_ir_graph;
2782 dbg_info *dbgi = get_irn_dbg_info(node);
2783 ir_node *block = get_nodes_block(node);
2784 ir_node *new_block = be_transform_node(block);
2785 ir_node *left = get_Cmp_left(node);
2786 ir_node *right = get_Cmp_right(node);
2787 ir_mode *cmp_mode = get_irn_mode(left);
2789 ia32_address_mode_t am;
2790 ia32_address_t *addr = &am.addr;
2793 if(mode_is_float(cmp_mode)) {
2794 if (ia32_cg_config.use_sse2) {
2795 return create_Ucomi(node);
2797 return create_Fucom(node);
2801 assert(mode_needs_gp_reg(cmp_mode));
2803 /* we prefer the Test instruction where possible except cases where
2804 * we can use SourceAM */
2805 cmp_unsigned = !mode_is_signed(cmp_mode);
2806 if (is_Const_0(right)) {
2808 get_irn_n_edges(left) == 1 &&
2809 can_fold_test_and(node)) {
2810 /* Test(and_left, and_right) */
2811 ir_node *and_left = get_And_left(left);
2812 ir_node *and_right = get_And_right(left);
2813 ir_mode *mode = get_irn_mode(and_left);
2815 match_arguments(&am, block, and_left, and_right, NULL,
2817 match_am | match_8bit_am | match_16bit_am |
2818 match_am_and_immediates | match_immediate |
2819 match_8bit | match_16bit);
2820 if (get_mode_size_bits(mode) == 8) {
2821 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2822 addr->index, addr->mem, am.new_op1,
2823 am.new_op2, am.ins_permuted,
2826 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2827 addr->index, addr->mem, am.new_op1,
2828 am.new_op2, am.ins_permuted, cmp_unsigned);
2831 match_arguments(&am, block, NULL, left, NULL,
2832 match_am | match_8bit_am | match_16bit_am |
2833 match_8bit | match_16bit);
2834 if (am.op_type == ia32_AddrModeS) {
2836 ir_node *imm_zero = try_create_Immediate(right, 0);
2837 if (get_mode_size_bits(cmp_mode) == 8) {
2838 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2839 addr->index, addr->mem, am.new_op2,
2840 imm_zero, am.ins_permuted,
2843 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2844 addr->index, addr->mem, am.new_op2,
2845 imm_zero, am.ins_permuted, cmp_unsigned);
2848 /* Test(left, left) */
2849 if (get_mode_size_bits(cmp_mode) == 8) {
2850 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2851 addr->index, addr->mem, am.new_op2,
2852 am.new_op2, am.ins_permuted,
2855 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2856 addr->index, addr->mem, am.new_op2,
2857 am.new_op2, am.ins_permuted,
2863 /* Cmp(left, right) */
2864 match_arguments(&am, block, left, right, NULL,
2865 match_commutative | match_am | match_8bit_am |
2866 match_16bit_am | match_am_and_immediates |
2867 match_immediate | match_8bit | match_16bit);
2868 if (get_mode_size_bits(cmp_mode) == 8) {
2869 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2870 addr->index, addr->mem, am.new_op1,
2871 am.new_op2, am.ins_permuted,
2874 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2875 addr->index, addr->mem, am.new_op1,
2876 am.new_op2, am.ins_permuted, cmp_unsigned);
2879 set_am_attributes(new_node, &am);
2880 assert(cmp_mode != NULL);
2881 set_ia32_ls_mode(new_node, cmp_mode);
2883 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2885 new_node = fix_mem_proj(new_node, &am);
2890 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2893 ir_graph *irg = current_ir_graph;
2894 dbg_info *dbgi = get_irn_dbg_info(node);
2895 ir_node *block = get_nodes_block(node);
2896 ir_node *new_block = be_transform_node(block);
2897 ir_node *val_true = get_Psi_val(node, 0);
2898 ir_node *val_false = get_Psi_default(node);
2900 match_flags_t match_flags;
2901 ia32_address_mode_t am;
2902 ia32_address_t *addr;
2904 assert(ia32_cg_config.use_cmov);
2905 assert(mode_needs_gp_reg(get_irn_mode(val_true)));
2909 match_flags = match_commutative | match_am | match_16bit_am |
2912 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2914 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2915 addr->mem, am.new_op1, am.new_op2, new_flags,
2916 am.ins_permuted, pnc);
2917 set_am_attributes(new_node, &am);
2919 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2921 new_node = fix_mem_proj(new_node, &am);
2928 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2929 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2932 ir_graph *irg = current_ir_graph;
2933 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2934 ir_node *nomem = new_NoMem();
2935 ir_mode *mode = get_irn_mode(orig_node);
2938 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2939 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2941 /* we might need to conv the result up */
2942 if(get_mode_size_bits(mode) > 8) {
2943 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2944 nomem, new_node, mode_Bu);
2945 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2952 * Transforms a Psi node into CMov.
2954 * @return The transformed node.
2956 static ir_node *gen_Psi(ir_node *node)
2958 dbg_info *dbgi = get_irn_dbg_info(node);
2959 ir_node *block = get_nodes_block(node);
2960 ir_node *new_block = be_transform_node(block);
2961 ir_node *psi_true = get_Psi_val(node, 0);
2962 ir_node *psi_default = get_Psi_default(node);
2963 ir_node *cond = get_Psi_cond(node, 0);
2964 ir_node *flags = NULL;
2968 assert(get_Psi_n_conds(node) == 1);
2969 assert(get_irn_mode(cond) == mode_b);
2970 assert(mode_needs_gp_reg(get_irn_mode(node)));
2972 flags = get_flags_node(cond, &pnc);
2974 if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2975 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 0);
2976 } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2977 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 1);
2979 new_node = create_CMov(node, cond, flags, pnc);
2986 * Create a conversion from x87 state register to general purpose.
2988 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
2989 ir_node *block = be_transform_node(get_nodes_block(node));
2990 ir_node *op = get_Conv_op(node);
2991 ir_node *new_op = be_transform_node(op);
2992 ia32_code_gen_t *cg = env_cg;
2993 ir_graph *irg = current_ir_graph;
2994 dbg_info *dbgi = get_irn_dbg_info(node);
2995 ir_node *noreg = ia32_new_NoReg_gp(cg);
2996 ir_node *trunc_mode = ia32_new_Fpu_truncate(cg);
2997 ir_mode *mode = get_irn_mode(node);
2998 ir_node *fist, *load;
3001 fist = new_rd_ia32_vfist(dbgi, irg, block, get_irg_frame(irg), noreg,
3002 new_NoMem(), new_op, trunc_mode);
3004 set_irn_pinned(fist, op_pin_state_floats);
3005 set_ia32_use_frame(fist);
3006 set_ia32_op_type(fist, ia32_AddrModeD);
3008 assert(get_mode_size_bits(mode) <= 32);
3009 /* exception we can only store signed 32 bit integers, so for unsigned
3010 we store a 64bit (signed) integer and load the lower bits */
3011 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3012 set_ia32_ls_mode(fist, mode_Ls);
3014 set_ia32_ls_mode(fist, mode_Is);
3016 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3019 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, fist);
3021 set_irn_pinned(load, op_pin_state_floats);
3022 set_ia32_use_frame(load);
3023 set_ia32_op_type(load, ia32_AddrModeS);
3024 set_ia32_ls_mode(load, mode_Is);
3025 if(get_ia32_ls_mode(fist) == mode_Ls) {
3026 ia32_attr_t *attr = get_ia32_attr(load);
3027 attr->data.need_64bit_stackent = 1;
3029 ia32_attr_t *attr = get_ia32_attr(load);
3030 attr->data.need_32bit_stackent = 1;
3032 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3034 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3038 * Creates a x87 strict Conv by placing a Sore and a Load
3040 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3042 ir_node *block = get_nodes_block(node);
3043 ir_graph *irg = current_ir_graph;
3044 dbg_info *dbgi = get_irn_dbg_info(node);
3045 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3046 ir_node *nomem = new_NoMem();
3047 ir_node *frame = get_irg_frame(irg);
3048 ir_node *store, *load;
3051 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3053 set_ia32_use_frame(store);
3054 set_ia32_op_type(store, ia32_AddrModeD);
3055 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3057 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3059 set_ia32_use_frame(load);
3060 set_ia32_op_type(load, ia32_AddrModeS);
3061 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3063 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3068 * Create a conversion from general purpose to x87 register
3070 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3071 ir_node *src_block = get_nodes_block(node);
3072 ir_node *block = be_transform_node(src_block);
3073 ir_graph *irg = current_ir_graph;
3074 dbg_info *dbgi = get_irn_dbg_info(node);
3075 ir_node *op = get_Conv_op(node);
3076 ir_node *new_op = NULL;
3080 ir_mode *store_mode;
3086 /* fild can use source AM if the operand is a signed 32bit integer */
3087 if (src_mode == mode_Is) {
3088 ia32_address_mode_t am;
3090 match_arguments(&am, src_block, NULL, op, NULL,
3091 match_am | match_try_am);
3092 if (am.op_type == ia32_AddrModeS) {
3093 ia32_address_t *addr = &am.addr;
3095 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3096 addr->index, addr->mem);
3097 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3100 set_am_attributes(fild, &am);
3101 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3103 fix_mem_proj(fild, &am);
3108 if(new_op == NULL) {
3109 new_op = be_transform_node(op);
3112 noreg = ia32_new_NoReg_gp(env_cg);
3113 nomem = new_NoMem();
3114 mode = get_irn_mode(op);
3116 /* first convert to 32 bit signed if necessary */
3117 src_bits = get_mode_size_bits(src_mode);
3118 if (src_bits == 8) {
3119 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3121 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3123 } else if (src_bits < 32) {
3124 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3126 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3130 assert(get_mode_size_bits(mode) == 32);
3133 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3136 set_ia32_use_frame(store);
3137 set_ia32_op_type(store, ia32_AddrModeD);
3138 set_ia32_ls_mode(store, mode_Iu);
3140 /* exception for 32bit unsigned, do a 64bit spill+load */
3141 if(!mode_is_signed(mode)) {
3144 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3146 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3147 get_irg_frame(irg), noreg, nomem,
3150 set_ia32_use_frame(zero_store);
3151 set_ia32_op_type(zero_store, ia32_AddrModeD);
3152 add_ia32_am_offs_int(zero_store, 4);
3153 set_ia32_ls_mode(zero_store, mode_Iu);
3158 store = new_rd_Sync(dbgi, irg, block, 2, in);
3159 store_mode = mode_Ls;
3161 store_mode = mode_Is;
3165 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3167 set_ia32_use_frame(fild);
3168 set_ia32_op_type(fild, ia32_AddrModeS);
3169 set_ia32_ls_mode(fild, store_mode);
3171 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3177 * Create a conversion from one integer mode into another one
3179 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3180 dbg_info *dbgi, ir_node *block, ir_node *op,
3183 ir_graph *irg = current_ir_graph;
3184 int src_bits = get_mode_size_bits(src_mode);
3185 int tgt_bits = get_mode_size_bits(tgt_mode);
3186 ir_node *new_block = be_transform_node(block);
3188 ir_mode *smaller_mode;
3190 ia32_address_mode_t am;
3191 ia32_address_t *addr = &am.addr;
3194 if (src_bits < tgt_bits) {
3195 smaller_mode = src_mode;
3196 smaller_bits = src_bits;
3198 smaller_mode = tgt_mode;
3199 smaller_bits = tgt_bits;
3202 #ifdef DEBUG_libfirm
3204 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3209 match_arguments(&am, block, NULL, op, NULL,
3210 match_8bit | match_16bit |
3211 match_am | match_8bit_am | match_16bit_am);
3212 if (smaller_bits == 8) {
3213 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3214 addr->index, addr->mem, am.new_op2,
3217 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3218 addr->index, addr->mem, am.new_op2,
3221 set_am_attributes(new_node, &am);
3222 /* match_arguments assume that out-mode = in-mode, this isn't true here
3224 set_ia32_ls_mode(new_node, smaller_mode);
3225 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3226 new_node = fix_mem_proj(new_node, &am);
3231 * Transforms a Conv node.
3233 * @return The created ia32 Conv node
3235 static ir_node *gen_Conv(ir_node *node) {
3236 ir_node *block = get_nodes_block(node);
3237 ir_node *new_block = be_transform_node(block);
3238 ir_node *op = get_Conv_op(node);
3239 ir_node *new_op = NULL;
3240 ir_graph *irg = current_ir_graph;
3241 dbg_info *dbgi = get_irn_dbg_info(node);
3242 ir_mode *src_mode = get_irn_mode(op);
3243 ir_mode *tgt_mode = get_irn_mode(node);
3244 int src_bits = get_mode_size_bits(src_mode);
3245 int tgt_bits = get_mode_size_bits(tgt_mode);
3246 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3247 ir_node *nomem = new_rd_NoMem(irg);
3248 ir_node *res = NULL;
3250 if (src_mode == mode_b) {
3251 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3252 /* nothing to do, we already model bools as 0/1 ints */
3253 return be_transform_node(op);
3256 if (src_mode == tgt_mode) {
3257 if (get_Conv_strict(node)) {
3258 if (ia32_cg_config.use_sse2) {
3259 /* when we are in SSE mode, we can kill all strict no-op conversion */
3260 return be_transform_node(op);
3263 /* this should be optimized already, but who knows... */
3264 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3265 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3266 return be_transform_node(op);
3270 if (mode_is_float(src_mode)) {
3271 new_op = be_transform_node(op);
3272 /* we convert from float ... */
3273 if (mode_is_float(tgt_mode)) {
3274 if(src_mode == mode_E && tgt_mode == mode_D
3275 && !get_Conv_strict(node)) {
3276 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3281 if (ia32_cg_config.use_sse2) {
3282 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3283 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3285 set_ia32_ls_mode(res, tgt_mode);
3287 if(get_Conv_strict(node)) {
3288 res = gen_x87_strict_conv(tgt_mode, new_op);
3289 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3292 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3297 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3298 if (ia32_cg_config.use_sse2) {
3299 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3301 set_ia32_ls_mode(res, src_mode);
3303 return gen_x87_fp_to_gp(node);
3307 /* we convert from int ... */
3308 if (mode_is_float(tgt_mode)) {
3310 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3311 if (ia32_cg_config.use_sse2) {
3312 new_op = be_transform_node(op);
3313 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3315 set_ia32_ls_mode(res, tgt_mode);
3317 res = gen_x87_gp_to_fp(node, src_mode);
3318 if(get_Conv_strict(node)) {
3319 res = gen_x87_strict_conv(tgt_mode, res);
3320 SET_IA32_ORIG_NODE(get_Proj_pred(res),
3321 ia32_get_old_node_name(env_cg, node));
3325 } else if(tgt_mode == mode_b) {
3326 /* mode_b lowering already took care that we only have 0/1 values */
3327 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3328 src_mode, tgt_mode));
3329 return be_transform_node(op);
3332 if (src_bits == tgt_bits) {
3333 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3334 src_mode, tgt_mode));
3335 return be_transform_node(op);
3338 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3346 static int check_immediate_constraint(long val, char immediate_constraint_type)
3348 switch (immediate_constraint_type) {
3352 return val >= 0 && val <= 32;
3354 return val >= 0 && val <= 63;
3356 return val >= -128 && val <= 127;
3358 return val == 0xff || val == 0xffff;
3360 return val >= 0 && val <= 3;
3362 return val >= 0 && val <= 255;
3364 return val >= 0 && val <= 127;
3368 panic("Invalid immediate constraint found");
3372 static ir_node *try_create_Immediate(ir_node *node,
3373 char immediate_constraint_type)
3376 tarval *offset = NULL;
3377 int offset_sign = 0;
3379 ir_entity *symconst_ent = NULL;
3380 int symconst_sign = 0;
3382 ir_node *cnst = NULL;
3383 ir_node *symconst = NULL;
3386 mode = get_irn_mode(node);
3387 if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3391 if(is_Minus(node)) {
3393 node = get_Minus_op(node);
3396 if(is_Const(node)) {
3399 offset_sign = minus;
3400 } else if(is_SymConst(node)) {
3403 symconst_sign = minus;
3404 } else if(is_Add(node)) {
3405 ir_node *left = get_Add_left(node);
3406 ir_node *right = get_Add_right(node);
3407 if(is_Const(left) && is_SymConst(right)) {
3410 symconst_sign = minus;
3411 offset_sign = minus;
3412 } else if(is_SymConst(left) && is_Const(right)) {
3415 symconst_sign = minus;
3416 offset_sign = minus;
3418 } else if(is_Sub(node)) {
3419 ir_node *left = get_Sub_left(node);
3420 ir_node *right = get_Sub_right(node);
3421 if(is_Const(left) && is_SymConst(right)) {
3424 symconst_sign = !minus;
3425 offset_sign = minus;
3426 } else if(is_SymConst(left) && is_Const(right)) {
3429 symconst_sign = minus;
3430 offset_sign = !minus;
3437 offset = get_Const_tarval(cnst);
3438 if(tarval_is_long(offset)) {
3439 val = get_tarval_long(offset);
3441 ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3446 if(!check_immediate_constraint(val, immediate_constraint_type))
3449 if(symconst != NULL) {
3450 if(immediate_constraint_type != 0) {
3451 /* we need full 32bits for symconsts */
3455 /* unfortunately the assembler/linker doesn't support -symconst */
3459 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3461 symconst_ent = get_SymConst_entity(symconst);
3463 if(cnst == NULL && symconst == NULL)
3466 if(offset_sign && offset != NULL) {
3467 offset = tarval_neg(offset);
3470 new_node = create_Immediate(symconst_ent, symconst_sign, val);
3475 static ir_node *create_immediate_or_transform(ir_node *node,
3476 char immediate_constraint_type)
3478 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3479 if (new_node == NULL) {
3480 new_node = be_transform_node(node);
3485 static const arch_register_req_t no_register_req = {
3486 arch_register_req_type_none,
3487 NULL, /* regclass */
3488 NULL, /* limit bitset */
3490 0 /* different pos */
3494 * An assembler constraint.
3496 typedef struct constraint_t constraint_t;
3497 struct constraint_t {
3500 const arch_register_req_t **out_reqs;
3502 const arch_register_req_t *req;
3503 unsigned immediate_possible;
3504 char immediate_type;
3507 static void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
3509 int immediate_possible = 0;
3510 char immediate_type = 0;
3511 unsigned limited = 0;
3512 const arch_register_class_t *cls = NULL;
3513 ir_graph *irg = current_ir_graph;
3514 struct obstack *obst = get_irg_obstack(irg);
3515 arch_register_req_t *req;
3516 unsigned *limited_ptr = NULL;
3520 /* TODO: replace all the asserts with nice error messages */
3523 /* a memory constraint: no need to do anything in backend about it
3524 * (the dependencies are already respected by the memory edge of
3526 constraint->req = &no_register_req;
3538 assert(cls == NULL ||
3539 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3540 cls = &ia32_reg_classes[CLASS_ia32_gp];
3541 limited |= 1 << REG_EAX;
3544 assert(cls == NULL ||
3545 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3546 cls = &ia32_reg_classes[CLASS_ia32_gp];
3547 limited |= 1 << REG_EBX;
3550 assert(cls == NULL ||
3551 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3552 cls = &ia32_reg_classes[CLASS_ia32_gp];
3553 limited |= 1 << REG_ECX;
3556 assert(cls == NULL ||
3557 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3558 cls = &ia32_reg_classes[CLASS_ia32_gp];
3559 limited |= 1 << REG_EDX;
3562 assert(cls == NULL ||
3563 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3564 cls = &ia32_reg_classes[CLASS_ia32_gp];
3565 limited |= 1 << REG_EDI;
3568 assert(cls == NULL ||
3569 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3570 cls = &ia32_reg_classes[CLASS_ia32_gp];
3571 limited |= 1 << REG_ESI;
3574 case 'q': /* q means lower part of the regs only, this makes no
3575 * difference to Q for us (we only assigne whole registers) */
3576 assert(cls == NULL ||
3577 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3578 cls = &ia32_reg_classes[CLASS_ia32_gp];
3579 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3583 assert(cls == NULL ||
3584 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3585 cls = &ia32_reg_classes[CLASS_ia32_gp];
3586 limited |= 1 << REG_EAX | 1 << REG_EDX;
3589 assert(cls == NULL ||
3590 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3591 cls = &ia32_reg_classes[CLASS_ia32_gp];
3592 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3593 1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3600 assert(cls == NULL);
3601 cls = &ia32_reg_classes[CLASS_ia32_gp];
3607 /* TODO: mark values so the x87 simulator knows about t and u */
3608 assert(cls == NULL);
3609 cls = &ia32_reg_classes[CLASS_ia32_vfp];
3614 assert(cls == NULL);
3615 /* TODO: check that sse2 is supported */
3616 cls = &ia32_reg_classes[CLASS_ia32_xmm];
3626 assert(!immediate_possible);
3627 immediate_possible = 1;
3628 immediate_type = *c;
3632 assert(!immediate_possible);
3633 immediate_possible = 1;
3637 assert(!immediate_possible && cls == NULL);
3638 immediate_possible = 1;
3639 cls = &ia32_reg_classes[CLASS_ia32_gp];
3652 assert(constraint->is_in && "can only specify same constraint "
3655 sscanf(c, "%d%n", &same_as, &p);
3663 /* memory constraint no need to do anything in backend about it
3664 * (the dependencies are already respected by the memory edge of
3666 constraint->req = &no_register_req;
3669 case 'E': /* no float consts yet */
3670 case 'F': /* no float consts yet */
3671 case 's': /* makes no sense on x86 */
3672 case 'X': /* we can't support that in firm */
3675 case '<': /* no autodecrement on x86 */
3676 case '>': /* no autoincrement on x86 */
3677 case 'C': /* sse constant not supported yet */
3678 case 'G': /* 80387 constant not supported yet */
3679 case 'y': /* we don't support mmx registers yet */
3680 case 'Z': /* not available in 32 bit mode */
3681 case 'e': /* not available in 32 bit mode */
3682 panic("unsupported asm constraint '%c' found in (%+F)",
3683 *c, current_ir_graph);
3686 panic("unknown asm constraint '%c' found in (%+F)", *c,
3694 const arch_register_req_t *other_constr;
3696 assert(cls == NULL && "same as and register constraint not supported");
3697 assert(!immediate_possible && "same as and immediate constraint not "
3699 assert(same_as < constraint->n_outs && "wrong constraint number in "
3700 "same_as constraint");
3702 other_constr = constraint->out_reqs[same_as];
3704 req = obstack_alloc(obst, sizeof(req[0]));
3705 req->cls = other_constr->cls;
3706 req->type = arch_register_req_type_should_be_same;
3707 req->limited = NULL;
3708 req->other_same = 1U << pos;
3709 req->other_different = 0;
3711 /* switch constraints. This is because in firm we have same_as
3712 * constraints on the output constraints while in the gcc asm syntax
3713 * they are specified on the input constraints */
3714 constraint->req = other_constr;
3715 constraint->out_reqs[same_as] = req;
3716 constraint->immediate_possible = 0;
3720 if(immediate_possible && cls == NULL) {
3721 cls = &ia32_reg_classes[CLASS_ia32_gp];
3723 assert(!immediate_possible || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3724 assert(cls != NULL);
3726 if(immediate_possible) {
3727 assert(constraint->is_in
3728 && "immediate make no sense for output constraints");
3730 /* todo: check types (no float input on 'r' constrained in and such... */
3733 req = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3734 limited_ptr = (unsigned*) (req+1);
3736 req = obstack_alloc(obst, sizeof(req[0]));
3738 memset(req, 0, sizeof(req[0]));
3741 req->type = arch_register_req_type_limited;
3742 *limited_ptr = limited;
3743 req->limited = limited_ptr;
3745 req->type = arch_register_req_type_normal;
3749 constraint->req = req;
3750 constraint->immediate_possible = immediate_possible;
3751 constraint->immediate_type = immediate_type;
3754 static void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
3755 const char *clobber)
3757 ir_graph *irg = get_irn_irg(node);
3758 struct obstack *obst = get_irg_obstack(irg);
3759 const arch_register_t *reg = NULL;
3762 arch_register_req_t *req;
3763 const arch_register_class_t *cls;
3768 /* TODO: construct a hashmap instead of doing linear search for clobber
3770 for(c = 0; c < N_CLASSES; ++c) {
3771 cls = & ia32_reg_classes[c];
3772 for(r = 0; r < cls->n_regs; ++r) {
3773 const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3774 if(strcmp(temp_reg->name, clobber) == 0
3775 || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3784 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3788 assert(reg->index < 32);
3790 limited = obstack_alloc(obst, sizeof(limited[0]));
3791 *limited = 1 << reg->index;
3793 req = obstack_alloc(obst, sizeof(req[0]));
3794 memset(req, 0, sizeof(req[0]));
3795 req->type = arch_register_req_type_limited;
3797 req->limited = limited;
3799 constraint->req = req;
3800 constraint->immediate_possible = 0;
3801 constraint->immediate_type = 0;
3804 static int is_memory_op(const ir_asm_constraint *constraint)
3806 ident *id = constraint->constraint;
3807 const char *str = get_id_str(id);
3810 for(c = str; *c != '\0'; ++c) {
3819 * generates code for a ASM node
3821 static ir_node *gen_ASM(ir_node *node)
3824 ir_graph *irg = current_ir_graph;
3825 ir_node *block = get_nodes_block(node);
3826 ir_node *new_block = be_transform_node(block);
3827 dbg_info *dbgi = get_irn_dbg_info(node);
3831 int n_out_constraints;
3833 const arch_register_req_t **out_reg_reqs;
3834 const arch_register_req_t **in_reg_reqs;
3835 ia32_asm_reg_t *register_map;
3836 unsigned reg_map_size = 0;
3837 struct obstack *obst;
3838 const ir_asm_constraint *in_constraints;
3839 const ir_asm_constraint *out_constraints;
3841 constraint_t parsed_constraint;
3843 arity = get_irn_arity(node);
3844 in = alloca(arity * sizeof(in[0]));
3845 memset(in, 0, arity * sizeof(in[0]));
3847 n_out_constraints = get_ASM_n_output_constraints(node);
3848 n_clobbers = get_ASM_n_clobbers(node);
3849 out_arity = n_out_constraints + n_clobbers;
3850 /* hack to keep space for mem proj */
3854 in_constraints = get_ASM_input_constraints(node);
3855 out_constraints = get_ASM_output_constraints(node);
3856 clobbers = get_ASM_clobbers(node);
3858 /* construct output constraints */
3859 obst = get_irg_obstack(irg);
3860 out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
3861 parsed_constraint.out_reqs = out_reg_reqs;
3862 parsed_constraint.n_outs = n_out_constraints;
3863 parsed_constraint.is_in = 0;
3865 for(i = 0; i < out_arity; ++i) {
3868 if(i < n_out_constraints) {
3869 const ir_asm_constraint *constraint = &out_constraints[i];
3870 c = get_id_str(constraint->constraint);
3871 parse_asm_constraint(i, &parsed_constraint, c);
3873 if(constraint->pos > reg_map_size)
3874 reg_map_size = constraint->pos;
3876 out_reg_reqs[i] = parsed_constraint.req;
3877 } else if(i < out_arity - 1) {
3878 ident *glob_id = clobbers [i - n_out_constraints];
3879 assert(glob_id != NULL);
3880 c = get_id_str(glob_id);
3881 parse_clobber(node, i, &parsed_constraint, c);
3883 out_reg_reqs[i+1] = parsed_constraint.req;
3887 out_reg_reqs[n_out_constraints] = &no_register_req;
3889 /* construct input constraints */
3890 in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
3891 parsed_constraint.is_in = 1;
3892 for(i = 0; i < arity; ++i) {
3893 const ir_asm_constraint *constraint = &in_constraints[i];
3894 ident *constr_id = constraint->constraint;
3895 const char *c = get_id_str(constr_id);
3897 parse_asm_constraint(i, &parsed_constraint, c);
3898 in_reg_reqs[i] = parsed_constraint.req;
3900 if(constraint->pos > reg_map_size)
3901 reg_map_size = constraint->pos;
3903 if(parsed_constraint.immediate_possible) {
3904 ir_node *pred = get_irn_n(node, i);
3905 char imm_type = parsed_constraint.immediate_type;
3906 ir_node *immediate = try_create_Immediate(pred, imm_type);
3908 if(immediate != NULL) {
3915 register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
3916 memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
3918 for(i = 0; i < n_out_constraints; ++i) {
3919 const ir_asm_constraint *constraint = &out_constraints[i];
3920 unsigned pos = constraint->pos;
3922 assert(pos < reg_map_size);
3923 register_map[pos].use_input = 0;
3924 register_map[pos].valid = 1;
3925 register_map[pos].memory = is_memory_op(constraint);
3926 register_map[pos].inout_pos = i;
3927 register_map[pos].mode = constraint->mode;
3930 /* transform inputs */
3931 for(i = 0; i < arity; ++i) {
3932 const ir_asm_constraint *constraint = &in_constraints[i];
3933 unsigned pos = constraint->pos;
3934 ir_node *pred = get_irn_n(node, i);
3935 ir_node *transformed;
3937 assert(pos < reg_map_size);
3938 register_map[pos].use_input = 1;
3939 register_map[pos].valid = 1;
3940 register_map[pos].memory = is_memory_op(constraint);
3941 register_map[pos].inout_pos = i;
3942 register_map[pos].mode = constraint->mode;
3947 transformed = be_transform_node(pred);
3948 in[i] = transformed;
3951 new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
3952 get_ASM_text(node), register_map);
3954 set_ia32_out_req_all(new_node, out_reg_reqs);
3955 set_ia32_in_req_all(new_node, in_reg_reqs);
3957 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3963 * Transforms a FrameAddr into an ia32 Add.
3965 static ir_node *gen_be_FrameAddr(ir_node *node) {
3966 ir_node *block = be_transform_node(get_nodes_block(node));
3967 ir_node *op = be_get_FrameAddr_frame(node);
3968 ir_node *new_op = be_transform_node(op);
3969 ir_graph *irg = current_ir_graph;
3970 dbg_info *dbgi = get_irn_dbg_info(node);
3971 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3974 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3975 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3976 set_ia32_use_frame(new_node);
3978 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3984 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3986 static ir_node *gen_be_Return(ir_node *node) {
3987 ir_graph *irg = current_ir_graph;
3988 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3989 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3990 ir_entity *ent = get_irg_entity(irg);
3991 ir_type *tp = get_entity_type(ent);
3996 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3997 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
4000 int pn_ret_val, pn_ret_mem, arity, i;
4002 assert(ret_val != NULL);
4003 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4004 return be_duplicate_node(node);
4007 res_type = get_method_res_type(tp, 0);
4009 if (! is_Primitive_type(res_type)) {
4010 return be_duplicate_node(node);
4013 mode = get_type_mode(res_type);
4014 if (! mode_is_float(mode)) {
4015 return be_duplicate_node(node);
4018 assert(get_method_n_ress(tp) == 1);
4020 pn_ret_val = get_Proj_proj(ret_val);
4021 pn_ret_mem = get_Proj_proj(ret_mem);
4023 /* get the Barrier */
4024 barrier = get_Proj_pred(ret_val);
4026 /* get result input of the Barrier */
4027 ret_val = get_irn_n(barrier, pn_ret_val);
4028 new_ret_val = be_transform_node(ret_val);
4030 /* get memory input of the Barrier */
4031 ret_mem = get_irn_n(barrier, pn_ret_mem);
4032 new_ret_mem = be_transform_node(ret_mem);
4034 frame = get_irg_frame(irg);
4036 dbgi = get_irn_dbg_info(barrier);
4037 block = be_transform_node(get_nodes_block(barrier));
4039 noreg = ia32_new_NoReg_gp(env_cg);
4041 /* store xmm0 onto stack */
4042 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
4043 new_ret_mem, new_ret_val);
4044 set_ia32_ls_mode(sse_store, mode);
4045 set_ia32_op_type(sse_store, ia32_AddrModeD);
4046 set_ia32_use_frame(sse_store);
4048 /* load into x87 register */
4049 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
4050 set_ia32_op_type(fld, ia32_AddrModeS);
4051 set_ia32_use_frame(fld);
4053 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
4054 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
4056 /* create a new barrier */
4057 arity = get_irn_arity(barrier);
4058 in = alloca(arity * sizeof(in[0]));
4059 for (i = 0; i < arity; ++i) {
4062 if (i == pn_ret_val) {
4064 } else if (i == pn_ret_mem) {
4067 ir_node *in = get_irn_n(barrier, i);
4068 new_in = be_transform_node(in);
4073 new_barrier = new_ir_node(dbgi, irg, block,
4074 get_irn_op(barrier), get_irn_mode(barrier),
4076 copy_node_attr(barrier, new_barrier);
4077 be_duplicate_deps(barrier, new_barrier);
4078 be_set_transformed_node(barrier, new_barrier);
4079 mark_irn_visited(barrier);
4081 /* transform normally */
4082 return be_duplicate_node(node);
4086 * Transform a be_AddSP into an ia32_SubSP.
4088 static ir_node *gen_be_AddSP(ir_node *node)
4090 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4091 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4093 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
4097 * Transform a be_SubSP into an ia32_AddSP
4099 static ir_node *gen_be_SubSP(ir_node *node)
4101 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4102 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4104 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
4108 * This function just sets the register for the Unknown node
4109 * as this is not done during register allocation because Unknown
4110 * is an "ignore" node.
4112 static ir_node *gen_Unknown(ir_node *node) {
4113 ir_mode *mode = get_irn_mode(node);
4115 if (mode_is_float(mode)) {
4116 if (ia32_cg_config.use_sse2) {
4117 return ia32_new_Unknown_xmm(env_cg);
4119 /* Unknown nodes are buggy in x87 simulator, use zero for now... */
4120 ir_graph *irg = current_ir_graph;
4121 dbg_info *dbgi = get_irn_dbg_info(node);
4122 ir_node *block = get_irg_start_block(irg);
4123 ir_node *ret = new_rd_ia32_vfldz(dbgi, irg, block);
4125 /* Const Nodes before the initial IncSP are a bad idea, because
4126 * they could be spilled and we have no SP ready at that point yet.
4127 * So add a dependency to the initial frame pointer calculation to
4128 * avoid that situation.
4130 add_irn_dep(ret, get_irg_frame(irg));
4133 } else if (mode_needs_gp_reg(mode)) {
4134 return ia32_new_Unknown_gp(env_cg);
4136 panic("unsupported Unknown-Mode");
4142 * Change some phi modes
4144 static ir_node *gen_Phi(ir_node *node) {
4145 ir_node *block = be_transform_node(get_nodes_block(node));
4146 ir_graph *irg = current_ir_graph;
4147 dbg_info *dbgi = get_irn_dbg_info(node);
4148 ir_mode *mode = get_irn_mode(node);
4151 if(mode_needs_gp_reg(mode)) {
4152 /* we shouldn't have any 64bit stuff around anymore */
4153 assert(get_mode_size_bits(mode) <= 32);
4154 /* all integer operations are on 32bit registers now */
4156 } else if(mode_is_float(mode)) {
4157 if (ia32_cg_config.use_sse2) {
4164 /* phi nodes allow loops, so we use the old arguments for now
4165 * and fix this later */
4166 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4167 get_irn_in(node) + 1);
4168 copy_node_attr(node, phi);
4169 be_duplicate_deps(node, phi);
4171 be_set_transformed_node(node, phi);
4172 be_enqueue_preds(node);
4180 static ir_node *gen_IJmp(ir_node *node)
4182 ir_node *block = get_nodes_block(node);
4183 ir_node *new_block = be_transform_node(block);
4184 ir_graph *irg = current_ir_graph;
4185 dbg_info *dbgi = get_irn_dbg_info(node);
4186 ir_node *op = get_IJmp_target(node);
4188 ia32_address_mode_t am;
4189 ia32_address_t *addr = &am.addr;
4191 assert(get_irn_mode(op) == mode_P);
4193 match_arguments(&am, block, NULL, op, NULL,
4194 match_am | match_8bit_am | match_16bit_am |
4195 match_immediate | match_8bit | match_16bit);
4197 new_node = new_rd_ia32_IJmp(dbgi, irg, new_block, addr->base, addr->index,
4198 addr->mem, am.new_op2);
4199 set_am_attributes(new_node, &am);
4200 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4202 new_node = fix_mem_proj(new_node, &am);
4207 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4210 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4211 ir_node *val, ir_node *mem);
4214 * Transforms a lowered Load into a "real" one.
4216 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4218 ir_node *block = be_transform_node(get_nodes_block(node));
4219 ir_node *ptr = get_irn_n(node, 0);
4220 ir_node *new_ptr = be_transform_node(ptr);
4221 ir_node *mem = get_irn_n(node, 1);
4222 ir_node *new_mem = be_transform_node(mem);
4223 ir_graph *irg = current_ir_graph;
4224 dbg_info *dbgi = get_irn_dbg_info(node);
4225 ir_mode *mode = get_ia32_ls_mode(node);
4226 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4229 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4231 set_ia32_op_type(new_op, ia32_AddrModeS);
4232 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4233 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4234 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4235 if (is_ia32_am_sc_sign(node))
4236 set_ia32_am_sc_sign(new_op);
4237 set_ia32_ls_mode(new_op, mode);
4238 if (is_ia32_use_frame(node)) {
4239 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4240 set_ia32_use_frame(new_op);
4243 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4249 * Transforms a lowered Store into a "real" one.
4251 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4253 ir_node *block = be_transform_node(get_nodes_block(node));
4254 ir_node *ptr = get_irn_n(node, 0);
4255 ir_node *new_ptr = be_transform_node(ptr);
4256 ir_node *val = get_irn_n(node, 1);
4257 ir_node *new_val = be_transform_node(val);
4258 ir_node *mem = get_irn_n(node, 2);
4259 ir_node *new_mem = be_transform_node(mem);
4260 ir_graph *irg = current_ir_graph;
4261 dbg_info *dbgi = get_irn_dbg_info(node);
4262 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4263 ir_mode *mode = get_ia32_ls_mode(node);
4267 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4269 am_offs = get_ia32_am_offs_int(node);
4270 add_ia32_am_offs_int(new_op, am_offs);
4272 set_ia32_op_type(new_op, ia32_AddrModeD);
4273 set_ia32_ls_mode(new_op, mode);
4274 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4275 set_ia32_use_frame(new_op);
4277 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4282 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4284 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4285 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4287 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4288 match_immediate | match_mode_neutral);
4291 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4293 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4294 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4295 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4299 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4301 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4302 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4303 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4307 static ir_node *gen_ia32_l_Add(ir_node *node) {
4308 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4309 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4310 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4311 match_commutative | match_am | match_immediate |
4312 match_mode_neutral);
4314 if(is_Proj(lowered)) {
4315 lowered = get_Proj_pred(lowered);
4317 assert(is_ia32_Add(lowered));
4318 set_irn_mode(lowered, mode_T);
4324 static ir_node *gen_ia32_l_Adc(ir_node *node)
4326 return gen_binop_flags(node, new_rd_ia32_Adc,
4327 match_commutative | match_am | match_immediate |
4328 match_mode_neutral);
4332 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4334 * @param node The node to transform
4335 * @return the created ia32 vfild node
4337 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4338 return gen_lowered_Load(node, new_rd_ia32_vfild);
4342 * Transforms an ia32_l_Load into a "real" ia32_Load node
4344 * @param node The node to transform
4345 * @return the created ia32 Load node
4347 static ir_node *gen_ia32_l_Load(ir_node *node) {
4348 return gen_lowered_Load(node, new_rd_ia32_Load);
4352 * Transforms an ia32_l_Store into a "real" ia32_Store node
4354 * @param node The node to transform
4355 * @return the created ia32 Store node
4357 static ir_node *gen_ia32_l_Store(ir_node *node) {
4358 return gen_lowered_Store(node, new_rd_ia32_Store);
4362 * Transforms a l_vfist into a "real" vfist node.
4364 * @param node The node to transform
4365 * @return the created ia32 vfist node
4367 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4368 ir_node *block = be_transform_node(get_nodes_block(node));
4369 ir_node *ptr = get_irn_n(node, 0);
4370 ir_node *new_ptr = be_transform_node(ptr);
4371 ir_node *val = get_irn_n(node, 1);
4372 ir_node *new_val = be_transform_node(val);
4373 ir_node *mem = get_irn_n(node, 2);
4374 ir_node *new_mem = be_transform_node(mem);
4375 ir_graph *irg = current_ir_graph;
4376 dbg_info *dbgi = get_irn_dbg_info(node);
4377 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4378 ir_mode *mode = get_ia32_ls_mode(node);
4379 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
4383 new_op = new_rd_ia32_vfist(dbgi, irg, block, new_ptr, noreg, new_mem,
4384 new_val, trunc_mode);
4386 am_offs = get_ia32_am_offs_int(node);
4387 add_ia32_am_offs_int(new_op, am_offs);
4389 set_ia32_op_type(new_op, ia32_AddrModeD);
4390 set_ia32_ls_mode(new_op, mode);
4391 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4392 set_ia32_use_frame(new_op);
4394 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4400 * Transforms a l_MulS into a "real" MulS node.
4402 * @return the created ia32 Mul node
4404 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4405 ir_node *left = get_binop_left(node);
4406 ir_node *right = get_binop_right(node);
4408 return gen_binop(node, left, right, new_rd_ia32_Mul,
4409 match_commutative | match_am | match_mode_neutral);
4413 * Transforms a l_IMulS into a "real" IMul1OPS node.
4415 * @return the created ia32 IMul1OP node
4417 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4418 ir_node *left = get_binop_left(node);
4419 ir_node *right = get_binop_right(node);
4421 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4422 match_commutative | match_am | match_mode_neutral);
4425 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4426 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4427 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4428 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4429 match_am | match_immediate | match_mode_neutral);
4431 if(is_Proj(lowered)) {
4432 lowered = get_Proj_pred(lowered);
4434 assert(is_ia32_Sub(lowered));
4435 set_irn_mode(lowered, mode_T);
4441 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4442 return gen_binop_flags(node, new_rd_ia32_Sbb,
4443 match_am | match_immediate | match_mode_neutral);
4447 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4448 * op1 - target to be shifted
4449 * op2 - contains bits to be shifted into target
4451 * Only op3 can be an immediate.
4453 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4454 ir_node *low, ir_node *count)
4456 ir_node *block = get_nodes_block(node);
4457 ir_node *new_block = be_transform_node(block);
4458 ir_graph *irg = current_ir_graph;
4459 dbg_info *dbgi = get_irn_dbg_info(node);
4460 ir_node *new_high = be_transform_node(high);
4461 ir_node *new_low = be_transform_node(low);
4465 /* the shift amount can be any mode that is bigger than 5 bits, since all
4466 * other bits are ignored anyway */
4467 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4468 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4469 count = get_Conv_op(count);
4471 new_count = create_immediate_or_transform(count, 0);
4473 if (is_ia32_l_ShlD(node)) {
4474 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4477 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4480 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4485 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4487 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4488 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4489 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4490 return gen_lowered_64bit_shifts(node, high, low, count);
4493 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4495 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4496 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4497 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4498 return gen_lowered_64bit_shifts(node, high, low, count);
4501 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4502 ir_node *src_block = get_nodes_block(node);
4503 ir_node *block = be_transform_node(src_block);
4504 ir_graph *irg = current_ir_graph;
4505 dbg_info *dbgi = get_irn_dbg_info(node);
4506 ir_node *frame = get_irg_frame(irg);
4507 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4508 ir_node *nomem = new_NoMem();
4509 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4510 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4511 ir_node *new_val_low = be_transform_node(val_low);
4512 ir_node *new_val_high = be_transform_node(val_high);
4517 ir_node *store_high;
4519 if(!mode_is_signed(get_irn_mode(val_high))) {
4520 panic("unsigned long long -> float not supported yet (%+F)", node);
4524 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4526 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4528 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4529 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4531 set_ia32_use_frame(store_low);
4532 set_ia32_use_frame(store_high);
4533 set_ia32_op_type(store_low, ia32_AddrModeD);
4534 set_ia32_op_type(store_high, ia32_AddrModeD);
4535 set_ia32_ls_mode(store_low, mode_Iu);
4536 set_ia32_ls_mode(store_high, mode_Is);
4537 add_ia32_am_offs_int(store_high, 4);
4541 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4544 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4546 set_ia32_use_frame(fild);
4547 set_ia32_op_type(fild, ia32_AddrModeS);
4548 set_ia32_ls_mode(fild, mode_Ls);
4550 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4552 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4555 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4556 ir_node *src_block = get_nodes_block(node);
4557 ir_node *block = be_transform_node(src_block);
4558 ir_graph *irg = current_ir_graph;
4559 dbg_info *dbgi = get_irn_dbg_info(node);
4560 ir_node *frame = get_irg_frame(irg);
4561 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4562 ir_node *nomem = new_NoMem();
4563 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4564 ir_node *new_val = be_transform_node(val);
4565 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
4570 fist = new_rd_ia32_vfist(dbgi, irg, block, frame, noreg, nomem, new_val,
4572 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4573 set_ia32_use_frame(fist);
4574 set_ia32_op_type(fist, ia32_AddrModeD);
4575 set_ia32_ls_mode(fist, mode_Ls);
4581 * the BAD transformer.
4583 static ir_node *bad_transform(ir_node *node) {
4584 panic("No transform function for %+F available.\n", node);
4588 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4589 ir_graph *irg = current_ir_graph;
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_node *frame = get_irg_frame(irg);
4594 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4595 dbg_info *dbgi = get_irn_dbg_info(node);
4596 long pn = get_Proj_proj(node);
4601 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4602 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4603 set_ia32_use_frame(load);
4604 set_ia32_op_type(load, ia32_AddrModeS);
4605 set_ia32_ls_mode(load, mode_Iu);
4606 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4607 * 32 bit from it with this particular load */
4608 attr = get_ia32_attr(load);
4609 attr->data.need_64bit_stackent = 1;
4611 if (pn == pn_ia32_l_FloattoLL_res_high) {
4612 add_ia32_am_offs_int(load, 4);
4614 assert(pn == pn_ia32_l_FloattoLL_res_low);
4617 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4623 * Transform the Projs of an AddSP.
4625 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4626 ir_node *block = be_transform_node(get_nodes_block(node));
4627 ir_node *pred = get_Proj_pred(node);
4628 ir_node *new_pred = be_transform_node(pred);
4629 ir_graph *irg = current_ir_graph;
4630 dbg_info *dbgi = get_irn_dbg_info(node);
4631 long proj = get_Proj_proj(node);
4633 if (proj == pn_be_AddSP_sp) {
4634 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4635 pn_ia32_SubSP_stack);
4636 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4638 } else if(proj == pn_be_AddSP_res) {
4639 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4640 pn_ia32_SubSP_addr);
4641 } else if (proj == pn_be_AddSP_M) {
4642 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4646 return new_rd_Unknown(irg, get_irn_mode(node));
4650 * Transform the Projs of a SubSP.
4652 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4653 ir_node *block = be_transform_node(get_nodes_block(node));
4654 ir_node *pred = get_Proj_pred(node);
4655 ir_node *new_pred = be_transform_node(pred);
4656 ir_graph *irg = current_ir_graph;
4657 dbg_info *dbgi = get_irn_dbg_info(node);
4658 long proj = get_Proj_proj(node);
4660 if (proj == pn_be_SubSP_sp) {
4661 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4662 pn_ia32_AddSP_stack);
4663 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4665 } else if (proj == pn_be_SubSP_M) {
4666 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4670 return new_rd_Unknown(irg, get_irn_mode(node));
4674 * Transform and renumber the Projs from a Load.
4676 static ir_node *gen_Proj_Load(ir_node *node) {
4678 ir_node *block = be_transform_node(get_nodes_block(node));
4679 ir_node *pred = get_Proj_pred(node);
4680 ir_graph *irg = current_ir_graph;
4681 dbg_info *dbgi = get_irn_dbg_info(node);
4682 long proj = get_Proj_proj(node);
4685 /* loads might be part of source address mode matches, so we don't
4686 transform the ProjMs yet (with the exception of loads whose result is
4689 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4692 assert(pn_ia32_Load_M == 1); /* convention: mem-result of Source-AM
4694 /* this is needed, because sometimes we have loops that are only
4695 reachable through the ProjM */
4696 be_enqueue_preds(node);
4697 /* do it in 2 steps, to silence firm verifier */
4698 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4699 set_Proj_proj(res, pn_ia32_Load_M);
4703 /* renumber the proj */
4704 new_pred = be_transform_node(pred);
4705 if (is_ia32_Load(new_pred)) {
4708 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4710 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4711 case pn_Load_X_regular:
4712 return new_rd_Jmp(dbgi, irg, block);
4713 case pn_Load_X_except:
4714 /* This Load might raise an exception. Mark it. */
4715 set_ia32_exc_label(new_pred, 1);
4716 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4720 } else if (is_ia32_Conv_I2I(new_pred) ||
4721 is_ia32_Conv_I2I8Bit(new_pred)) {
4722 set_irn_mode(new_pred, mode_T);
4723 if (proj == pn_Load_res) {
4724 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4725 } else if (proj == pn_Load_M) {
4726 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4728 } else if (is_ia32_xLoad(new_pred)) {
4731 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4733 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4734 case pn_Load_X_regular:
4735 return new_rd_Jmp(dbgi, irg, block);
4736 case pn_Load_X_except:
4737 /* This Load might raise an exception. Mark it. */
4738 set_ia32_exc_label(new_pred, 1);
4739 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4743 } else if (is_ia32_vfld(new_pred)) {
4746 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4748 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4749 case pn_Load_X_regular:
4750 return new_rd_Jmp(dbgi, irg, block);
4751 case pn_Load_X_except:
4752 /* This Load might raise an exception. Mark it. */
4753 set_ia32_exc_label(new_pred, 1);
4754 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4759 /* can happen for ProJMs when source address mode happened for the
4762 /* however it should not be the result proj, as that would mean the
4763 load had multiple users and should not have been used for
4765 if (proj != pn_Load_M) {
4766 panic("internal error: transformed node not a Load");
4768 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4772 return new_rd_Unknown(irg, get_irn_mode(node));
4776 * Transform and renumber the Projs from a DivMod like instruction.
4778 static ir_node *gen_Proj_DivMod(ir_node *node) {
4779 ir_node *block = be_transform_node(get_nodes_block(node));
4780 ir_node *pred = get_Proj_pred(node);
4781 ir_node *new_pred = be_transform_node(pred);
4782 ir_graph *irg = current_ir_graph;
4783 dbg_info *dbgi = get_irn_dbg_info(node);
4784 ir_mode *mode = get_irn_mode(node);
4785 long proj = get_Proj_proj(node);
4787 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4789 switch (get_irn_opcode(pred)) {
4793 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4795 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4796 case pn_Div_X_regular:
4797 return new_rd_Jmp(dbgi, irg, block);
4798 case pn_Div_X_except:
4799 set_ia32_exc_label(new_pred, 1);
4800 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4808 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4810 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4811 case pn_Mod_X_except:
4812 set_ia32_exc_label(new_pred, 1);
4813 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4821 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4822 case pn_DivMod_res_div:
4823 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4824 case pn_DivMod_res_mod:
4825 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4826 case pn_DivMod_X_regular:
4827 return new_rd_Jmp(dbgi, irg, block);
4828 case pn_DivMod_X_except:
4829 set_ia32_exc_label(new_pred, 1);
4830 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4840 return new_rd_Unknown(irg, mode);
4844 * Transform and renumber the Projs from a CopyB.
4846 static ir_node *gen_Proj_CopyB(ir_node *node) {
4847 ir_node *block = be_transform_node(get_nodes_block(node));
4848 ir_node *pred = get_Proj_pred(node);
4849 ir_node *new_pred = be_transform_node(pred);
4850 ir_graph *irg = current_ir_graph;
4851 dbg_info *dbgi = get_irn_dbg_info(node);
4852 ir_mode *mode = get_irn_mode(node);
4853 long proj = get_Proj_proj(node);
4856 case pn_CopyB_M_regular:
4857 if (is_ia32_CopyB_i(new_pred)) {
4858 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4859 } else if (is_ia32_CopyB(new_pred)) {
4860 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4868 return new_rd_Unknown(irg, mode);
4872 * Transform and renumber the Projs from a Quot.
4874 static ir_node *gen_Proj_Quot(ir_node *node) {
4875 ir_node *block = be_transform_node(get_nodes_block(node));
4876 ir_node *pred = get_Proj_pred(node);
4877 ir_node *new_pred = be_transform_node(pred);
4878 ir_graph *irg = current_ir_graph;
4879 dbg_info *dbgi = get_irn_dbg_info(node);
4880 ir_mode *mode = get_irn_mode(node);
4881 long proj = get_Proj_proj(node);
4885 if (is_ia32_xDiv(new_pred)) {
4886 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4887 } else if (is_ia32_vfdiv(new_pred)) {
4888 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4892 if (is_ia32_xDiv(new_pred)) {
4893 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4894 } else if (is_ia32_vfdiv(new_pred)) {
4895 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4898 case pn_Quot_X_regular:
4899 case pn_Quot_X_except:
4905 return new_rd_Unknown(irg, mode);
4909 * Transform the Thread Local Storage Proj.
4911 static ir_node *gen_Proj_tls(ir_node *node) {
4912 ir_node *block = be_transform_node(get_nodes_block(node));
4913 ir_graph *irg = current_ir_graph;
4914 dbg_info *dbgi = NULL;
4915 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4920 static ir_node *gen_be_Call(ir_node *node) {
4921 ir_node *res = be_duplicate_node(node);
4922 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4927 static ir_node *gen_be_IncSP(ir_node *node) {
4928 ir_node *res = be_duplicate_node(node);
4929 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4935 * Transform the Projs from a be_Call.
4937 static ir_node *gen_Proj_be_Call(ir_node *node) {
4938 ir_node *block = be_transform_node(get_nodes_block(node));
4939 ir_node *call = get_Proj_pred(node);
4940 ir_node *new_call = be_transform_node(call);
4941 ir_graph *irg = current_ir_graph;
4942 dbg_info *dbgi = get_irn_dbg_info(node);
4943 ir_type *method_type = be_Call_get_type(call);
4944 int n_res = get_method_n_ress(method_type);
4945 long proj = get_Proj_proj(node);
4946 ir_mode *mode = get_irn_mode(node);
4948 const arch_register_class_t *cls;
4950 /* The following is kinda tricky: If we're using SSE, then we have to
4951 * move the result value of the call in floating point registers to an
4952 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4953 * after the call, we have to make sure to correctly make the
4954 * MemProj and the result Proj use these 2 nodes
4956 if (proj == pn_be_Call_M_regular) {
4957 // get new node for result, are we doing the sse load/store hack?
4958 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4959 ir_node *call_res_new;
4960 ir_node *call_res_pred = NULL;
4962 if (call_res != NULL) {
4963 call_res_new = be_transform_node(call_res);
4964 call_res_pred = get_Proj_pred(call_res_new);
4967 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4968 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4969 pn_be_Call_M_regular);
4971 assert(is_ia32_xLoad(call_res_pred));
4972 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4976 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4977 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4979 ir_node *frame = get_irg_frame(irg);
4980 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4982 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4985 /* in case there is no memory output: create one to serialize the copy
4987 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4988 pn_be_Call_M_regular);
4989 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4990 pn_be_Call_first_res);
4992 /* store st(0) onto stack */
4993 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4995 set_ia32_op_type(fstp, ia32_AddrModeD);
4996 set_ia32_use_frame(fstp);
4998 /* load into SSE register */
4999 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5001 set_ia32_op_type(sse_load, ia32_AddrModeS);
5002 set_ia32_use_frame(sse_load);
5004 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5010 /* transform call modes */
5011 if (mode_is_data(mode)) {
5012 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5016 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5020 * Transform the Projs from a Cmp.
5022 static ir_node *gen_Proj_Cmp(ir_node *node)
5024 /* this probably means not all mode_b nodes were lowered... */
5025 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5030 * Transform and potentially renumber Proj nodes.
5032 static ir_node *gen_Proj(ir_node *node) {
5033 ir_node *pred = get_Proj_pred(node);
5034 if (is_Store(pred)) {
5035 long proj = get_Proj_proj(node);
5036 if (proj == pn_Store_M) {
5037 return be_transform_node(pred);
5040 return new_r_Bad(current_ir_graph);
5042 } else if (is_Load(pred)) {
5043 return gen_Proj_Load(node);
5044 } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
5045 return gen_Proj_DivMod(node);
5046 } else if (is_CopyB(pred)) {
5047 return gen_Proj_CopyB(node);
5048 } else if (is_Quot(pred)) {
5049 return gen_Proj_Quot(node);
5050 } else if (be_is_SubSP(pred)) {
5051 return gen_Proj_be_SubSP(node);
5052 } else if (be_is_AddSP(pred)) {
5053 return gen_Proj_be_AddSP(node);
5054 } else if (be_is_Call(pred)) {
5055 return gen_Proj_be_Call(node);
5056 } else if (is_Cmp(pred)) {
5057 return gen_Proj_Cmp(node);
5058 } else if (get_irn_op(pred) == op_Start) {
5059 long proj = get_Proj_proj(node);
5060 if (proj == pn_Start_X_initial_exec) {
5061 ir_node *block = get_nodes_block(pred);
5062 dbg_info *dbgi = get_irn_dbg_info(node);
5065 /* we exchange the ProjX with a jump */
5066 block = be_transform_node(block);
5067 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
5070 if (node == be_get_old_anchor(anchor_tls)) {
5071 return gen_Proj_tls(node);
5073 } else if (is_ia32_l_FloattoLL(pred)) {
5074 return gen_Proj_l_FloattoLL(node);
5076 } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5080 ir_mode *mode = get_irn_mode(node);
5081 if (mode_needs_gp_reg(mode)) {
5082 ir_node *new_pred = be_transform_node(pred);
5083 ir_node *block = be_transform_node(get_nodes_block(node));
5084 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5085 mode_Iu, get_Proj_proj(node));
5086 #ifdef DEBUG_libfirm
5087 new_proj->node_nr = node->node_nr;
5093 return be_duplicate_node(node);
5097 * Enters all transform functions into the generic pointer
5099 static void register_transformers(void)
5103 /* first clear the generic function pointer for all ops */
5104 clear_irp_opcodes_generic_func();
5106 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5107 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5145 /* transform ops from intrinsic lowering */
5161 GEN(ia32_l_LLtoFloat);
5162 GEN(ia32_l_FloattoLL);
5168 /* we should never see these nodes */
5183 /* handle generic backend nodes */
5192 op_Mulh = get_op_Mulh();
5201 * Pre-transform all unknown and noreg nodes.
5203 static void ia32_pretransform_node(void *arch_cg) {
5204 ia32_code_gen_t *cg = arch_cg;
5206 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5207 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5208 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5209 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5210 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5211 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5216 * Walker, checks if all ia32 nodes producing more than one result have
5217 * its Projs, other wise creates new projs and keep them using a be_Keep node.
5219 static void add_missing_keep_walker(ir_node *node, void *data)
5222 unsigned found_projs = 0;
5223 const ir_edge_t *edge;
5224 ir_mode *mode = get_irn_mode(node);
5229 if(!is_ia32_irn(node))
5232 n_outs = get_ia32_n_res(node);
5235 if(is_ia32_SwitchJmp(node))
5238 assert(n_outs < (int) sizeof(unsigned) * 8);
5239 foreach_out_edge(node, edge) {
5240 ir_node *proj = get_edge_src_irn(edge);
5241 int pn = get_Proj_proj(proj);
5243 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
5244 found_projs |= 1 << pn;
5248 /* are keeps missing? */
5250 for(i = 0; i < n_outs; ++i) {
5253 const arch_register_req_t *req;
5254 const arch_register_class_t *class;
5256 if(found_projs & (1 << i)) {
5260 req = get_ia32_out_req(node, i);
5265 if(class == &ia32_reg_classes[CLASS_ia32_flags]) {
5269 block = get_nodes_block(node);
5270 in[0] = new_r_Proj(current_ir_graph, block, node,
5271 arch_register_class_mode(class), i);
5272 if(last_keep != NULL) {
5273 be_Keep_add_node(last_keep, class, in[0]);
5275 last_keep = be_new_Keep(class, current_ir_graph, block, 1, in);
5276 if(sched_is_scheduled(node)) {
5277 sched_add_after(node, last_keep);
5284 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5287 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5289 ir_graph *irg = be_get_birg_irg(cg->birg);
5290 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5293 /* do the transformation */
5294 void ia32_transform_graph(ia32_code_gen_t *cg) {
5296 ir_graph *irg = cg->irg;
5298 register_transformers();
5300 initial_fpcw = NULL;
5302 BE_TIMER_PUSH(t_heights);
5303 heights = heights_new(irg);
5304 BE_TIMER_POP(t_heights);
5305 ia32_calculate_non_address_mode_nodes(cg->birg);
5307 /* the transform phase is not safe for CSE (yet) because several nodes get
5308 * attributes set after their creation */
5309 cse_last = get_opt_cse();
5312 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5314 set_opt_cse(cse_last);
5316 ia32_free_non_address_mode_nodes();
5317 heights_free(heights);
5321 void ia32_init_transform(void)
5323 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");