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 (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1903 ir_node *l = get_Cmp_left(pred);
1904 ir_node *r = get_Cmp_right(pred);
1906 ir_node *la = get_And_left(l);
1907 ir_node *ra = get_And_right(l);
1909 ir_node *c = get_Shl_left(la);
1910 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1911 /* (1 << n) & ra) */
1912 ir_node *n = get_Shl_right(la);
1913 flags = gen_bt(pred, ra, n);
1914 /* we must generate a Jc/Jnc jump */
1915 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1918 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1923 ir_node *c = get_Shl_left(ra);
1924 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1925 /* la & (1 << n)) */
1926 ir_node *n = get_Shl_right(ra);
1927 flags = gen_bt(pred, la, n);
1928 /* we must generate a Jc/Jnc jump */
1929 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1932 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1938 flags = be_transform_node(pred);
1944 /* a mode_b value, we have to compare it against 0 */
1945 dbgi = get_irn_dbg_info(node);
1946 new_block = be_transform_node(get_nodes_block(node));
1947 new_op = be_transform_node(node);
1948 noreg = ia32_new_NoReg_gp(env_cg);
1949 nomem = new_NoMem();
1950 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1951 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1952 *pnc_out = pn_Cmp_Lg;
1957 * Transforms a Load.
1959 * @return the created ia32 Load node
1961 static ir_node *gen_Load(ir_node *node) {
1962 ir_node *old_block = get_nodes_block(node);
1963 ir_node *block = be_transform_node(old_block);
1964 ir_node *ptr = get_Load_ptr(node);
1965 ir_node *mem = get_Load_mem(node);
1966 ir_node *new_mem = be_transform_node(mem);
1969 ir_graph *irg = current_ir_graph;
1970 dbg_info *dbgi = get_irn_dbg_info(node);
1971 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1972 ir_mode *mode = get_Load_mode(node);
1975 ia32_address_t addr;
1977 /* construct load address */
1978 memset(&addr, 0, sizeof(addr));
1979 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1986 base = be_transform_node(base);
1992 index = be_transform_node(index);
1995 if (mode_is_float(mode)) {
1996 if (ia32_cg_config.use_sse2) {
1997 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1999 res_mode = mode_xmm;
2001 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
2003 res_mode = mode_vfp;
2006 assert(mode != mode_b);
2008 /* create a conv node with address mode for smaller modes */
2009 if(get_mode_size_bits(mode) < 32) {
2010 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
2011 new_mem, noreg, mode);
2013 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
2018 set_irn_pinned(new_node, get_irn_pinned(node));
2019 set_ia32_op_type(new_node, ia32_AddrModeS);
2020 set_ia32_ls_mode(new_node, mode);
2021 set_address(new_node, &addr);
2023 if(get_irn_pinned(node) == op_pin_state_floats) {
2024 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
2027 /* make sure we are scheduled behind the initial IncSP/Barrier
2028 * to avoid spills being placed before it
2030 if (block == get_irg_start_block(irg)) {
2031 add_irn_dep(new_node, get_irg_frame(irg));
2034 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2039 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2040 ir_node *ptr, ir_node *other)
2047 /* we only use address mode if we're the only user of the load */
2048 if(get_irn_n_edges(node) > 1)
2051 load = get_Proj_pred(node);
2054 if(get_nodes_block(load) != block)
2057 /* Store should be attached to the load */
2058 if(!is_Proj(mem) || get_Proj_pred(mem) != load)
2060 /* store should have the same pointer as the load */
2061 if(get_Load_ptr(load) != ptr)
2064 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2065 if(other != NULL && get_nodes_block(other) == block
2066 && heights_reachable_in_block(heights, other, load))
2072 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2073 ir_node *mem, ir_node *ptr, ir_mode *mode,
2074 construct_binop_dest_func *func,
2075 construct_binop_dest_func *func8bit,
2076 match_flags_t flags)
2078 ir_node *src_block = get_nodes_block(node);
2080 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2081 ir_graph *irg = current_ir_graph;
2086 ia32_address_mode_t am;
2087 ia32_address_t *addr = &am.addr;
2088 memset(&am, 0, sizeof(am));
2090 assert(flags & match_dest_am);
2091 assert(flags & match_immediate); /* there is no destam node without... */
2092 commutative = (flags & match_commutative) != 0;
2094 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2095 build_address(&am, op1);
2096 new_op = create_immediate_or_transform(op2, 0);
2097 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2098 build_address(&am, op2);
2099 new_op = create_immediate_or_transform(op1, 0);
2104 if(addr->base == NULL)
2105 addr->base = noreg_gp;
2106 if(addr->index == NULL)
2107 addr->index = noreg_gp;
2108 if(addr->mem == NULL)
2109 addr->mem = new_NoMem();
2111 dbgi = get_irn_dbg_info(node);
2112 block = be_transform_node(src_block);
2113 if(get_mode_size_bits(mode) == 8) {
2114 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2117 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
2120 set_address(new_node, addr);
2121 set_ia32_op_type(new_node, ia32_AddrModeD);
2122 set_ia32_ls_mode(new_node, mode);
2123 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2128 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2129 ir_node *ptr, ir_mode *mode,
2130 construct_unop_dest_func *func)
2132 ir_graph *irg = current_ir_graph;
2133 ir_node *src_block = get_nodes_block(node);
2137 ia32_address_mode_t am;
2138 ia32_address_t *addr = &am.addr;
2139 memset(&am, 0, sizeof(am));
2141 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2144 build_address(&am, op);
2146 dbgi = get_irn_dbg_info(node);
2147 block = be_transform_node(src_block);
2148 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2149 set_address(new_node, addr);
2150 set_ia32_op_type(new_node, ia32_AddrModeD);
2151 set_ia32_ls_mode(new_node, mode);
2152 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2157 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2158 ir_mode *mode = get_irn_mode(node);
2159 ir_node *psi_true = get_Psi_val(node, 0);
2160 ir_node *psi_default = get_Psi_default(node);
2171 ia32_address_t addr;
2173 if(get_mode_size_bits(mode) != 8)
2176 if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2178 } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2184 build_address_ptr(&addr, ptr, mem);
2186 irg = current_ir_graph;
2187 dbgi = get_irn_dbg_info(node);
2188 block = get_nodes_block(node);
2189 new_block = be_transform_node(block);
2190 cond = get_Psi_cond(node, 0);
2191 flags = get_flags_node(cond, &pnc);
2192 new_mem = be_transform_node(mem);
2193 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2194 addr.index, addr.mem, flags, pnc, negated);
2195 set_address(new_node, &addr);
2196 set_ia32_op_type(new_node, ia32_AddrModeD);
2197 set_ia32_ls_mode(new_node, mode);
2198 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2203 static ir_node *try_create_dest_am(ir_node *node) {
2204 ir_node *val = get_Store_value(node);
2205 ir_node *mem = get_Store_mem(node);
2206 ir_node *ptr = get_Store_ptr(node);
2207 ir_mode *mode = get_irn_mode(val);
2208 unsigned bits = get_mode_size_bits(mode);
2213 /* handle only GP modes for now... */
2214 if(!mode_needs_gp_reg(mode))
2218 /* store must be the only user of the val node */
2219 if(get_irn_n_edges(val) > 1)
2221 /* skip pointless convs */
2223 ir_node *conv_op = get_Conv_op(val);
2224 ir_mode *pred_mode = get_irn_mode(conv_op);
2225 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2233 /* value must be in the same block */
2234 if(get_nodes_block(node) != get_nodes_block(val))
2237 switch(get_irn_opcode(val)) {
2239 op1 = get_Add_left(val);
2240 op2 = get_Add_right(val);
2241 if(is_Const_1(op2)) {
2242 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2243 new_rd_ia32_IncMem);
2245 } else if(is_Const_Minus_1(op2)) {
2246 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2247 new_rd_ia32_DecMem);
2250 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2251 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2252 match_dest_am | match_commutative |
2256 op1 = get_Sub_left(val);
2257 op2 = get_Sub_right(val);
2259 ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2262 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2263 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2264 match_dest_am | match_immediate |
2268 op1 = get_And_left(val);
2269 op2 = get_And_right(val);
2270 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2271 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2272 match_dest_am | match_commutative |
2276 op1 = get_Or_left(val);
2277 op2 = get_Or_right(val);
2278 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2279 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2280 match_dest_am | match_commutative |
2284 op1 = get_Eor_left(val);
2285 op2 = get_Eor_right(val);
2286 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2287 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2288 match_dest_am | match_commutative |
2292 op1 = get_Shl_left(val);
2293 op2 = get_Shl_right(val);
2294 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2295 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2296 match_dest_am | match_immediate);
2299 op1 = get_Shr_left(val);
2300 op2 = get_Shr_right(val);
2301 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2302 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2303 match_dest_am | match_immediate);
2306 op1 = get_Shrs_left(val);
2307 op2 = get_Shrs_right(val);
2308 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2309 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2310 match_dest_am | match_immediate);
2313 op1 = get_Rot_left(val);
2314 op2 = get_Rot_right(val);
2315 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2316 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2317 match_dest_am | match_immediate);
2319 /* TODO: match ROR patterns... */
2321 new_node = try_create_SetMem(val, ptr, mem);
2324 op1 = get_Minus_op(val);
2325 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2328 /* should be lowered already */
2329 assert(mode != mode_b);
2330 op1 = get_Not_op(val);
2331 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2337 if(new_node != NULL) {
2338 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2339 get_irn_pinned(node) == op_pin_state_pinned) {
2340 set_irn_pinned(new_node, op_pin_state_pinned);
2347 static int is_float_to_int32_conv(const ir_node *node)
2349 ir_mode *mode = get_irn_mode(node);
2353 if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode))
2358 conv_op = get_Conv_op(node);
2359 conv_mode = get_irn_mode(conv_op);
2361 if(!mode_is_float(conv_mode))
2368 * Transform a Store(floatConst).
2370 * @return the created ia32 Store node
2372 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2373 ir_mode *mode = get_irn_mode(cns);
2374 int size = get_mode_size_bits(mode);
2375 tarval *tv = get_Const_tarval(cns);
2376 ir_node *block = get_nodes_block(node);
2377 ir_node *new_block = be_transform_node(block);
2378 ir_node *ptr = get_Store_ptr(node);
2379 ir_node *mem = get_Store_mem(node);
2380 ir_graph *irg = current_ir_graph;
2381 dbg_info *dbgi = get_irn_dbg_info(node);
2382 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2385 ia32_address_t addr;
2387 unsigned val = get_tarval_sub_bits(tv, 0) |
2388 (get_tarval_sub_bits(tv, 1) << 8) |
2389 (get_tarval_sub_bits(tv, 2) << 16) |
2390 (get_tarval_sub_bits(tv, 3) << 24);
2391 ir_node *imm = create_Immediate(NULL, 0, val);
2393 /* construct store address */
2394 memset(&addr, 0, sizeof(addr));
2395 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2397 if (addr.base == NULL) {
2400 addr.base = be_transform_node(addr.base);
2403 if (addr.index == NULL) {
2406 addr.index = be_transform_node(addr.index);
2408 addr.mem = be_transform_node(mem);
2410 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2411 addr.index, addr.mem, imm);
2413 set_irn_pinned(new_node, get_irn_pinned(node));
2414 set_ia32_op_type(new_node, ia32_AddrModeD);
2415 set_ia32_ls_mode(new_node, mode_Iu);
2417 set_address(new_node, &addr);
2419 /** add more stores if needed */
2421 unsigned val = get_tarval_sub_bits(tv, ofs) |
2422 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2423 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2424 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2425 ir_node *imm = create_Immediate(NULL, 0, val);
2428 addr.mem = new_node;
2430 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2431 addr.index, addr.mem, imm);
2433 set_irn_pinned(new_node, get_irn_pinned(node));
2434 set_ia32_op_type(new_node, ia32_AddrModeD);
2435 set_ia32_ls_mode(new_node, mode_Iu);
2437 set_address(new_node, &addr);
2442 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2447 * Generate a vfist or vfisttp instruction.
2449 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2450 ir_node *mem, ir_node *val, ir_node **fist)
2454 if (ia32_cg_config.use_fisttp) {
2455 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2456 if other users exists */
2457 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2458 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2459 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2460 be_new_Keep(reg_class, irg, block, 1, &value);
2462 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2465 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2468 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2474 * Transforms a normal Store.
2476 * @return the created ia32 Store node
2478 static ir_node *gen_normal_Store(ir_node *node)
2480 ir_node *val = get_Store_value(node);
2481 ir_mode *mode = get_irn_mode(val);
2482 ir_node *block = get_nodes_block(node);
2483 ir_node *new_block = be_transform_node(block);
2484 ir_node *ptr = get_Store_ptr(node);
2485 ir_node *mem = get_Store_mem(node);
2486 ir_graph *irg = current_ir_graph;
2487 dbg_info *dbgi = get_irn_dbg_info(node);
2488 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2489 ir_node *new_val, *new_node, *store;
2490 ia32_address_t addr;
2492 /* check for destination address mode */
2493 new_node = try_create_dest_am(node);
2494 if (new_node != NULL)
2497 /* construct store address */
2498 memset(&addr, 0, sizeof(addr));
2499 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2501 if (addr.base == NULL) {
2504 addr.base = be_transform_node(addr.base);
2507 if (addr.index == NULL) {
2510 addr.index = be_transform_node(addr.index);
2512 addr.mem = be_transform_node(mem);
2514 if (mode_is_float(mode)) {
2515 /* convs (and strict-convs) before stores are unnecessary if the mode
2517 while (is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2518 val = get_Conv_op(val);
2520 new_val = be_transform_node(val);
2521 if (ia32_cg_config.use_sse2) {
2522 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2523 addr.index, addr.mem, new_val);
2525 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2526 addr.index, addr.mem, new_val, mode);
2529 } else if (is_float_to_int32_conv(val)) {
2530 val = get_Conv_op(val);
2532 /* convs (and strict-convs) before stores are unnecessary if the mode
2534 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2535 val = get_Conv_op(val);
2537 new_val = be_transform_node(val);
2538 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2540 new_val = create_immediate_or_transform(val, 0);
2541 assert(mode != mode_b);
2543 if (get_mode_size_bits(mode) == 8) {
2544 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2545 addr.index, addr.mem, new_val);
2547 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2548 addr.index, addr.mem, new_val);
2553 set_irn_pinned(store, get_irn_pinned(node));
2554 set_ia32_op_type(store, ia32_AddrModeD);
2555 set_ia32_ls_mode(store, mode);
2557 set_address(store, &addr);
2558 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2564 * Transforms a Store.
2566 * @return the created ia32 Store node
2568 static ir_node *gen_Store(ir_node *node)
2570 ir_node *val = get_Store_value(node);
2571 ir_mode *mode = get_irn_mode(val);
2573 if (mode_is_float(mode) && is_Const(val)) {
2576 /* we are storing a floating point constant */
2577 if (ia32_cg_config.use_sse2) {
2578 transform = !is_simple_sse_Const(val);
2580 transform = !is_simple_x87_Const(val);
2583 return gen_float_const_Store(node, val);
2585 return gen_normal_Store(node);
2589 * Transforms a Switch.
2591 * @return the created ia32 SwitchJmp node
2593 static ir_node *create_Switch(ir_node *node)
2595 ir_graph *irg = current_ir_graph;
2596 dbg_info *dbgi = get_irn_dbg_info(node);
2597 ir_node *block = be_transform_node(get_nodes_block(node));
2598 ir_node *sel = get_Cond_selector(node);
2599 ir_node *new_sel = be_transform_node(sel);
2600 int switch_min = INT_MAX;
2601 int switch_max = INT_MIN;
2602 long default_pn = get_Cond_defaultProj(node);
2604 const ir_edge_t *edge;
2606 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2608 /* determine the smallest switch case value */
2609 foreach_out_edge(node, edge) {
2610 ir_node *proj = get_edge_src_irn(edge);
2611 long pn = get_Proj_proj(proj);
2612 if(pn == default_pn)
2621 if((unsigned) (switch_max - switch_min) > 256000) {
2622 panic("Size of switch %+F bigger than 256000", node);
2625 if (switch_min != 0) {
2626 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2628 /* if smallest switch case is not 0 we need an additional sub */
2629 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2630 add_ia32_am_offs_int(new_sel, -switch_min);
2631 set_ia32_op_type(new_sel, ia32_AddrModeS);
2633 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2636 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2637 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2643 * Transform a Cond node.
2645 static ir_node *gen_Cond(ir_node *node) {
2646 ir_node *block = get_nodes_block(node);
2647 ir_node *new_block = be_transform_node(block);
2648 ir_graph *irg = current_ir_graph;
2649 dbg_info *dbgi = get_irn_dbg_info(node);
2650 ir_node *sel = get_Cond_selector(node);
2651 ir_mode *sel_mode = get_irn_mode(sel);
2652 ir_node *flags = NULL;
2656 if (sel_mode != mode_b) {
2657 return create_Switch(node);
2660 /* we get flags from a Cmp */
2661 flags = get_flags_node(sel, &pnc);
2663 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2664 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2670 * Transforms a CopyB node.
2672 * @return The transformed node.
2674 static ir_node *gen_CopyB(ir_node *node) {
2675 ir_node *block = be_transform_node(get_nodes_block(node));
2676 ir_node *src = get_CopyB_src(node);
2677 ir_node *new_src = be_transform_node(src);
2678 ir_node *dst = get_CopyB_dst(node);
2679 ir_node *new_dst = be_transform_node(dst);
2680 ir_node *mem = get_CopyB_mem(node);
2681 ir_node *new_mem = be_transform_node(mem);
2682 ir_node *res = NULL;
2683 ir_graph *irg = current_ir_graph;
2684 dbg_info *dbgi = get_irn_dbg_info(node);
2685 int size = get_type_size_bytes(get_CopyB_type(node));
2688 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2689 /* then we need the size explicitly in ECX. */
2690 if (size >= 32 * 4) {
2691 rem = size & 0x3; /* size % 4 */
2694 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2695 add_irn_dep(res, get_irg_frame(irg));
2697 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2700 ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2703 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2706 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2711 static ir_node *gen_be_Copy(ir_node *node)
2713 ir_node *new_node = be_duplicate_node(node);
2714 ir_mode *mode = get_irn_mode(new_node);
2716 if (mode_needs_gp_reg(mode)) {
2717 set_irn_mode(new_node, mode_Iu);
2723 static ir_node *create_Fucom(ir_node *node)
2725 ir_graph *irg = current_ir_graph;
2726 dbg_info *dbgi = get_irn_dbg_info(node);
2727 ir_node *block = get_nodes_block(node);
2728 ir_node *new_block = be_transform_node(block);
2729 ir_node *left = get_Cmp_left(node);
2730 ir_node *new_left = be_transform_node(left);
2731 ir_node *right = get_Cmp_right(node);
2735 if(ia32_cg_config.use_fucomi) {
2736 new_right = be_transform_node(right);
2737 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2739 set_ia32_commutative(new_node);
2740 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2742 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2743 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2746 new_right = be_transform_node(right);
2747 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2751 set_ia32_commutative(new_node);
2753 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2755 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2756 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2762 static ir_node *create_Ucomi(ir_node *node)
2764 ir_graph *irg = current_ir_graph;
2765 dbg_info *dbgi = get_irn_dbg_info(node);
2766 ir_node *src_block = get_nodes_block(node);
2767 ir_node *new_block = be_transform_node(src_block);
2768 ir_node *left = get_Cmp_left(node);
2769 ir_node *right = get_Cmp_right(node);
2771 ia32_address_mode_t am;
2772 ia32_address_t *addr = &am.addr;
2774 match_arguments(&am, src_block, left, right, NULL,
2775 match_commutative | match_am);
2777 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2778 addr->mem, am.new_op1, am.new_op2,
2780 set_am_attributes(new_node, &am);
2782 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2784 new_node = fix_mem_proj(new_node, &am);
2790 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2791 * to fold an and into a test node
2793 static int can_fold_test_and(ir_node *node)
2795 const ir_edge_t *edge;
2797 /** we can only have eq and lg projs */
2798 foreach_out_edge(node, edge) {
2799 ir_node *proj = get_edge_src_irn(edge);
2800 pn_Cmp pnc = get_Proj_proj(proj);
2801 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2809 * Generate code for a Cmp.
2811 static ir_node *gen_Cmp(ir_node *node)
2813 ir_graph *irg = current_ir_graph;
2814 dbg_info *dbgi = get_irn_dbg_info(node);
2815 ir_node *block = get_nodes_block(node);
2816 ir_node *new_block = be_transform_node(block);
2817 ir_node *left = get_Cmp_left(node);
2818 ir_node *right = get_Cmp_right(node);
2819 ir_mode *cmp_mode = get_irn_mode(left);
2821 ia32_address_mode_t am;
2822 ia32_address_t *addr = &am.addr;
2825 if(mode_is_float(cmp_mode)) {
2826 if (ia32_cg_config.use_sse2) {
2827 return create_Ucomi(node);
2829 return create_Fucom(node);
2833 assert(mode_needs_gp_reg(cmp_mode));
2835 /* we prefer the Test instruction where possible except cases where
2836 * we can use SourceAM */
2837 cmp_unsigned = !mode_is_signed(cmp_mode);
2838 if (is_Const_0(right)) {
2840 get_irn_n_edges(left) == 1 &&
2841 can_fold_test_and(node)) {
2842 /* Test(and_left, and_right) */
2843 ir_node *and_left = get_And_left(left);
2844 ir_node *and_right = get_And_right(left);
2845 ir_mode *mode = get_irn_mode(and_left);
2847 match_arguments(&am, block, and_left, and_right, NULL,
2849 match_am | match_8bit_am | match_16bit_am |
2850 match_am_and_immediates | match_immediate |
2851 match_8bit | match_16bit);
2852 if (get_mode_size_bits(mode) == 8) {
2853 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2854 addr->index, addr->mem, am.new_op1,
2855 am.new_op2, am.ins_permuted,
2858 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2859 addr->index, addr->mem, am.new_op1,
2860 am.new_op2, am.ins_permuted, cmp_unsigned);
2863 match_arguments(&am, block, NULL, left, NULL,
2864 match_am | match_8bit_am | match_16bit_am |
2865 match_8bit | match_16bit);
2866 if (am.op_type == ia32_AddrModeS) {
2868 ir_node *imm_zero = try_create_Immediate(right, 0);
2869 if (get_mode_size_bits(cmp_mode) == 8) {
2870 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2871 addr->index, addr->mem, am.new_op2,
2872 imm_zero, am.ins_permuted,
2875 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2876 addr->index, addr->mem, am.new_op2,
2877 imm_zero, am.ins_permuted, cmp_unsigned);
2880 /* Test(left, left) */
2881 if (get_mode_size_bits(cmp_mode) == 8) {
2882 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2883 addr->index, addr->mem, am.new_op2,
2884 am.new_op2, am.ins_permuted,
2887 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2888 addr->index, addr->mem, am.new_op2,
2889 am.new_op2, am.ins_permuted,
2895 /* Cmp(left, right) */
2896 match_arguments(&am, block, left, right, NULL,
2897 match_commutative | match_am | match_8bit_am |
2898 match_16bit_am | match_am_and_immediates |
2899 match_immediate | match_8bit | match_16bit);
2900 if (get_mode_size_bits(cmp_mode) == 8) {
2901 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2902 addr->index, addr->mem, am.new_op1,
2903 am.new_op2, am.ins_permuted,
2906 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2907 addr->index, addr->mem, am.new_op1,
2908 am.new_op2, am.ins_permuted, cmp_unsigned);
2911 set_am_attributes(new_node, &am);
2912 assert(cmp_mode != NULL);
2913 set_ia32_ls_mode(new_node, cmp_mode);
2915 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2917 new_node = fix_mem_proj(new_node, &am);
2922 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2925 ir_graph *irg = current_ir_graph;
2926 dbg_info *dbgi = get_irn_dbg_info(node);
2927 ir_node *block = get_nodes_block(node);
2928 ir_node *new_block = be_transform_node(block);
2929 ir_node *val_true = get_Psi_val(node, 0);
2930 ir_node *val_false = get_Psi_default(node);
2932 match_flags_t match_flags;
2933 ia32_address_mode_t am;
2934 ia32_address_t *addr;
2936 assert(ia32_cg_config.use_cmov);
2937 assert(mode_needs_gp_reg(get_irn_mode(val_true)));
2941 match_flags = match_commutative | match_am | match_16bit_am |
2944 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2946 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2947 addr->mem, am.new_op1, am.new_op2, new_flags,
2948 am.ins_permuted, pnc);
2949 set_am_attributes(new_node, &am);
2951 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2953 new_node = fix_mem_proj(new_node, &am);
2960 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2961 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2964 ir_graph *irg = current_ir_graph;
2965 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2966 ir_node *nomem = new_NoMem();
2967 ir_mode *mode = get_irn_mode(orig_node);
2970 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2971 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2973 /* we might need to conv the result up */
2974 if(get_mode_size_bits(mode) > 8) {
2975 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2976 nomem, new_node, mode_Bu);
2977 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2984 * Transforms a Psi node into CMov.
2986 * @return The transformed node.
2988 static ir_node *gen_Psi(ir_node *node)
2990 dbg_info *dbgi = get_irn_dbg_info(node);
2991 ir_node *block = get_nodes_block(node);
2992 ir_node *new_block = be_transform_node(block);
2993 ir_node *psi_true = get_Psi_val(node, 0);
2994 ir_node *psi_default = get_Psi_default(node);
2995 ir_node *cond = get_Psi_cond(node, 0);
2996 ir_mode *mode = get_irn_mode(node);
2997 ir_node *flags = NULL;
3001 assert(get_Psi_n_conds(node) == 1);
3002 assert(get_irn_mode(cond) == mode_b);
3004 if (mode_is_float(mode)) {
3005 ir_node *cmp = get_Proj_pred(cond);
3006 ir_node *cmp_left = get_Cmp_left(cmp);
3007 ir_node *cmp_right = get_Cmp_right(cmp);
3008 pn_Cmp pnc = get_Proj_proj(cond);
3010 if (ia32_cg_config.use_sse2) {
3011 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3012 if (cmp_left == psi_true && cmp_right == psi_default) {
3013 /* psi(a <= b, a, b) => MIN */
3014 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3015 match_commutative | match_am);
3016 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3017 /* psi(a <= b, b, a) => MAX */
3018 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3019 match_commutative | match_am);
3021 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3022 if (cmp_left == psi_true && cmp_right == psi_default) {
3023 /* psi(a >= b, a, b) => MAX */
3024 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3025 match_commutative | match_am);
3026 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3027 /* psi(a >= b, b, a) => MIN */
3028 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3029 match_commutative | match_am);
3033 panic("cannot transform floating point Psi");
3036 assert(mode_needs_gp_reg(mode));
3038 flags = get_flags_node(cond, &pnc);
3040 if (is_Const_1(psi_true) && is_Const_0(psi_default)) {
3041 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 0);
3042 } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
3043 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, 1);
3045 new_node = create_CMov(node, cond, flags, pnc);
3053 * Create a conversion from x87 state register to general purpose.
3055 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3056 ir_node *block = be_transform_node(get_nodes_block(node));
3057 ir_node *op = get_Conv_op(node);
3058 ir_node *new_op = be_transform_node(op);
3059 ia32_code_gen_t *cg = env_cg;
3060 ir_graph *irg = current_ir_graph;
3061 dbg_info *dbgi = get_irn_dbg_info(node);
3062 ir_node *noreg = ia32_new_NoReg_gp(cg);
3063 ir_mode *mode = get_irn_mode(node);
3064 ir_node *fist, *load, *mem;
3066 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3067 set_irn_pinned(fist, op_pin_state_floats);
3068 set_ia32_use_frame(fist);
3069 set_ia32_op_type(fist, ia32_AddrModeD);
3071 assert(get_mode_size_bits(mode) <= 32);
3072 /* exception we can only store signed 32 bit integers, so for unsigned
3073 we store a 64bit (signed) integer and load the lower bits */
3074 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3075 set_ia32_ls_mode(fist, mode_Ls);
3077 set_ia32_ls_mode(fist, mode_Is);
3079 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3082 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3084 set_irn_pinned(load, op_pin_state_floats);
3085 set_ia32_use_frame(load);
3086 set_ia32_op_type(load, ia32_AddrModeS);
3087 set_ia32_ls_mode(load, mode_Is);
3088 if(get_ia32_ls_mode(fist) == mode_Ls) {
3089 ia32_attr_t *attr = get_ia32_attr(load);
3090 attr->data.need_64bit_stackent = 1;
3092 ia32_attr_t *attr = get_ia32_attr(load);
3093 attr->data.need_32bit_stackent = 1;
3095 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3097 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3101 * Creates a x87 strict Conv by placing a Sore and a Load
3103 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3105 ir_node *block = get_nodes_block(node);
3106 ir_graph *irg = current_ir_graph;
3107 dbg_info *dbgi = get_irn_dbg_info(node);
3108 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3109 ir_node *nomem = new_NoMem();
3110 ir_node *frame = get_irg_frame(irg);
3111 ir_node *store, *load;
3114 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3116 set_ia32_use_frame(store);
3117 set_ia32_op_type(store, ia32_AddrModeD);
3118 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3120 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3122 set_ia32_use_frame(load);
3123 set_ia32_op_type(load, ia32_AddrModeS);
3124 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3126 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3131 * Create a conversion from general purpose to x87 register
3133 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3134 ir_node *src_block = get_nodes_block(node);
3135 ir_node *block = be_transform_node(src_block);
3136 ir_graph *irg = current_ir_graph;
3137 dbg_info *dbgi = get_irn_dbg_info(node);
3138 ir_node *op = get_Conv_op(node);
3139 ir_node *new_op = NULL;
3143 ir_mode *store_mode;
3149 /* fild can use source AM if the operand is a signed 32bit integer */
3150 if (src_mode == mode_Is) {
3151 ia32_address_mode_t am;
3153 match_arguments(&am, src_block, NULL, op, NULL,
3154 match_am | match_try_am);
3155 if (am.op_type == ia32_AddrModeS) {
3156 ia32_address_t *addr = &am.addr;
3158 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3159 addr->index, addr->mem);
3160 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3163 set_am_attributes(fild, &am);
3164 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3166 fix_mem_proj(fild, &am);
3171 if(new_op == NULL) {
3172 new_op = be_transform_node(op);
3175 noreg = ia32_new_NoReg_gp(env_cg);
3176 nomem = new_NoMem();
3177 mode = get_irn_mode(op);
3179 /* first convert to 32 bit signed if necessary */
3180 src_bits = get_mode_size_bits(src_mode);
3181 if (src_bits == 8) {
3182 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3184 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3186 } else if (src_bits < 32) {
3187 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3189 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3193 assert(get_mode_size_bits(mode) == 32);
3196 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3199 set_ia32_use_frame(store);
3200 set_ia32_op_type(store, ia32_AddrModeD);
3201 set_ia32_ls_mode(store, mode_Iu);
3203 /* exception for 32bit unsigned, do a 64bit spill+load */
3204 if(!mode_is_signed(mode)) {
3207 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3209 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3210 get_irg_frame(irg), noreg, nomem,
3213 set_ia32_use_frame(zero_store);
3214 set_ia32_op_type(zero_store, ia32_AddrModeD);
3215 add_ia32_am_offs_int(zero_store, 4);
3216 set_ia32_ls_mode(zero_store, mode_Iu);
3221 store = new_rd_Sync(dbgi, irg, block, 2, in);
3222 store_mode = mode_Ls;
3224 store_mode = mode_Is;
3228 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3230 set_ia32_use_frame(fild);
3231 set_ia32_op_type(fild, ia32_AddrModeS);
3232 set_ia32_ls_mode(fild, store_mode);
3234 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3240 * Create a conversion from one integer mode into another one
3242 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3243 dbg_info *dbgi, ir_node *block, ir_node *op,
3246 ir_graph *irg = current_ir_graph;
3247 int src_bits = get_mode_size_bits(src_mode);
3248 int tgt_bits = get_mode_size_bits(tgt_mode);
3249 ir_node *new_block = be_transform_node(block);
3251 ir_mode *smaller_mode;
3253 ia32_address_mode_t am;
3254 ia32_address_t *addr = &am.addr;
3257 if (src_bits < tgt_bits) {
3258 smaller_mode = src_mode;
3259 smaller_bits = src_bits;
3261 smaller_mode = tgt_mode;
3262 smaller_bits = tgt_bits;
3265 #ifdef DEBUG_libfirm
3267 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3272 match_arguments(&am, block, NULL, op, NULL,
3273 match_8bit | match_16bit |
3274 match_am | match_8bit_am | match_16bit_am);
3275 if (smaller_bits == 8) {
3276 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3277 addr->index, addr->mem, am.new_op2,
3280 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3281 addr->index, addr->mem, am.new_op2,
3284 set_am_attributes(new_node, &am);
3285 /* match_arguments assume that out-mode = in-mode, this isn't true here
3287 set_ia32_ls_mode(new_node, smaller_mode);
3288 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3289 new_node = fix_mem_proj(new_node, &am);
3294 * Transforms a Conv node.
3296 * @return The created ia32 Conv node
3298 static ir_node *gen_Conv(ir_node *node) {
3299 ir_node *block = get_nodes_block(node);
3300 ir_node *new_block = be_transform_node(block);
3301 ir_node *op = get_Conv_op(node);
3302 ir_node *new_op = NULL;
3303 ir_graph *irg = current_ir_graph;
3304 dbg_info *dbgi = get_irn_dbg_info(node);
3305 ir_mode *src_mode = get_irn_mode(op);
3306 ir_mode *tgt_mode = get_irn_mode(node);
3307 int src_bits = get_mode_size_bits(src_mode);
3308 int tgt_bits = get_mode_size_bits(tgt_mode);
3309 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3310 ir_node *nomem = new_rd_NoMem(irg);
3311 ir_node *res = NULL;
3313 if (src_mode == mode_b) {
3314 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3315 /* nothing to do, we already model bools as 0/1 ints */
3316 return be_transform_node(op);
3319 if (src_mode == tgt_mode) {
3320 if (get_Conv_strict(node)) {
3321 if (ia32_cg_config.use_sse2) {
3322 /* when we are in SSE mode, we can kill all strict no-op conversion */
3323 return be_transform_node(op);
3326 /* this should be optimized already, but who knows... */
3327 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3328 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3329 return be_transform_node(op);
3333 if (mode_is_float(src_mode)) {
3334 new_op = be_transform_node(op);
3335 /* we convert from float ... */
3336 if (mode_is_float(tgt_mode)) {
3337 if(src_mode == mode_E && tgt_mode == mode_D
3338 && !get_Conv_strict(node)) {
3339 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3344 if (ia32_cg_config.use_sse2) {
3345 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3346 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3348 set_ia32_ls_mode(res, tgt_mode);
3350 if(get_Conv_strict(node)) {
3351 res = gen_x87_strict_conv(tgt_mode, new_op);
3352 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3355 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3360 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3361 if (ia32_cg_config.use_sse2) {
3362 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3364 set_ia32_ls_mode(res, src_mode);
3366 return gen_x87_fp_to_gp(node);
3370 /* we convert from int ... */
3371 if (mode_is_float(tgt_mode)) {
3373 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3374 if (ia32_cg_config.use_sse2) {
3375 new_op = be_transform_node(op);
3376 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3378 set_ia32_ls_mode(res, tgt_mode);
3380 res = gen_x87_gp_to_fp(node, src_mode);
3381 if(get_Conv_strict(node)) {
3382 res = gen_x87_strict_conv(tgt_mode, res);
3383 SET_IA32_ORIG_NODE(get_Proj_pred(res),
3384 ia32_get_old_node_name(env_cg, node));
3388 } else if(tgt_mode == mode_b) {
3389 /* mode_b lowering already took care that we only have 0/1 values */
3390 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3391 src_mode, tgt_mode));
3392 return be_transform_node(op);
3395 if (src_bits == tgt_bits) {
3396 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3397 src_mode, tgt_mode));
3398 return be_transform_node(op);
3401 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3409 static int check_immediate_constraint(long val, char immediate_constraint_type)
3411 switch (immediate_constraint_type) {
3415 return val >= 0 && val <= 32;
3417 return val >= 0 && val <= 63;
3419 return val >= -128 && val <= 127;
3421 return val == 0xff || val == 0xffff;
3423 return val >= 0 && val <= 3;
3425 return val >= 0 && val <= 255;
3427 return val >= 0 && val <= 127;
3431 panic("Invalid immediate constraint found");
3435 static ir_node *try_create_Immediate(ir_node *node,
3436 char immediate_constraint_type)
3439 tarval *offset = NULL;
3440 int offset_sign = 0;
3442 ir_entity *symconst_ent = NULL;
3443 int symconst_sign = 0;
3445 ir_node *cnst = NULL;
3446 ir_node *symconst = NULL;
3449 mode = get_irn_mode(node);
3450 if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3454 if(is_Minus(node)) {
3456 node = get_Minus_op(node);
3459 if(is_Const(node)) {
3462 offset_sign = minus;
3463 } else if(is_SymConst(node)) {
3466 symconst_sign = minus;
3467 } else if(is_Add(node)) {
3468 ir_node *left = get_Add_left(node);
3469 ir_node *right = get_Add_right(node);
3470 if(is_Const(left) && is_SymConst(right)) {
3473 symconst_sign = minus;
3474 offset_sign = minus;
3475 } else if(is_SymConst(left) && is_Const(right)) {
3478 symconst_sign = minus;
3479 offset_sign = minus;
3481 } else if(is_Sub(node)) {
3482 ir_node *left = get_Sub_left(node);
3483 ir_node *right = get_Sub_right(node);
3484 if(is_Const(left) && is_SymConst(right)) {
3487 symconst_sign = !minus;
3488 offset_sign = minus;
3489 } else if(is_SymConst(left) && is_Const(right)) {
3492 symconst_sign = minus;
3493 offset_sign = !minus;
3500 offset = get_Const_tarval(cnst);
3501 if(tarval_is_long(offset)) {
3502 val = get_tarval_long(offset);
3504 ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3509 if(!check_immediate_constraint(val, immediate_constraint_type))
3512 if(symconst != NULL) {
3513 if(immediate_constraint_type != 0) {
3514 /* we need full 32bits for symconsts */
3518 /* unfortunately the assembler/linker doesn't support -symconst */
3522 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3524 symconst_ent = get_SymConst_entity(symconst);
3526 if(cnst == NULL && symconst == NULL)
3529 if(offset_sign && offset != NULL) {
3530 offset = tarval_neg(offset);
3533 new_node = create_Immediate(symconst_ent, symconst_sign, val);
3538 static ir_node *create_immediate_or_transform(ir_node *node,
3539 char immediate_constraint_type)
3541 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3542 if (new_node == NULL) {
3543 new_node = be_transform_node(node);
3548 static const arch_register_req_t no_register_req = {
3549 arch_register_req_type_none,
3550 NULL, /* regclass */
3551 NULL, /* limit bitset */
3553 0 /* different pos */
3557 * An assembler constraint.
3559 typedef struct constraint_t constraint_t;
3560 struct constraint_t {
3563 const arch_register_req_t **out_reqs;
3565 const arch_register_req_t *req;
3566 unsigned immediate_possible;
3567 char immediate_type;
3570 static void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
3572 int immediate_possible = 0;
3573 char immediate_type = 0;
3574 unsigned limited = 0;
3575 const arch_register_class_t *cls = NULL;
3576 ir_graph *irg = current_ir_graph;
3577 struct obstack *obst = get_irg_obstack(irg);
3578 arch_register_req_t *req;
3579 unsigned *limited_ptr = NULL;
3583 /* TODO: replace all the asserts with nice error messages */
3586 /* a memory constraint: no need to do anything in backend about it
3587 * (the dependencies are already respected by the memory edge of
3589 constraint->req = &no_register_req;
3601 assert(cls == NULL ||
3602 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3603 cls = &ia32_reg_classes[CLASS_ia32_gp];
3604 limited |= 1 << REG_EAX;
3607 assert(cls == NULL ||
3608 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3609 cls = &ia32_reg_classes[CLASS_ia32_gp];
3610 limited |= 1 << REG_EBX;
3613 assert(cls == NULL ||
3614 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3615 cls = &ia32_reg_classes[CLASS_ia32_gp];
3616 limited |= 1 << REG_ECX;
3619 assert(cls == NULL ||
3620 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3621 cls = &ia32_reg_classes[CLASS_ia32_gp];
3622 limited |= 1 << REG_EDX;
3625 assert(cls == NULL ||
3626 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3627 cls = &ia32_reg_classes[CLASS_ia32_gp];
3628 limited |= 1 << REG_EDI;
3631 assert(cls == NULL ||
3632 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3633 cls = &ia32_reg_classes[CLASS_ia32_gp];
3634 limited |= 1 << REG_ESI;
3637 case 'q': /* q means lower part of the regs only, this makes no
3638 * difference to Q for us (we only assigne whole registers) */
3639 assert(cls == NULL ||
3640 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3641 cls = &ia32_reg_classes[CLASS_ia32_gp];
3642 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3646 assert(cls == NULL ||
3647 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3648 cls = &ia32_reg_classes[CLASS_ia32_gp];
3649 limited |= 1 << REG_EAX | 1 << REG_EDX;
3652 assert(cls == NULL ||
3653 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3654 cls = &ia32_reg_classes[CLASS_ia32_gp];
3655 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3656 1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3663 assert(cls == NULL);
3664 cls = &ia32_reg_classes[CLASS_ia32_gp];
3670 /* TODO: mark values so the x87 simulator knows about t and u */
3671 assert(cls == NULL);
3672 cls = &ia32_reg_classes[CLASS_ia32_vfp];
3677 assert(cls == NULL);
3678 /* TODO: check that sse2 is supported */
3679 cls = &ia32_reg_classes[CLASS_ia32_xmm];
3689 assert(!immediate_possible);
3690 immediate_possible = 1;
3691 immediate_type = *c;
3695 assert(!immediate_possible);
3696 immediate_possible = 1;
3700 assert(!immediate_possible && cls == NULL);
3701 immediate_possible = 1;
3702 cls = &ia32_reg_classes[CLASS_ia32_gp];
3715 assert(constraint->is_in && "can only specify same constraint "
3718 sscanf(c, "%d%n", &same_as, &p);
3726 /* memory constraint no need to do anything in backend about it
3727 * (the dependencies are already respected by the memory edge of
3729 constraint->req = &no_register_req;
3732 case 'E': /* no float consts yet */
3733 case 'F': /* no float consts yet */
3734 case 's': /* makes no sense on x86 */
3735 case 'X': /* we can't support that in firm */
3738 case '<': /* no autodecrement on x86 */
3739 case '>': /* no autoincrement on x86 */
3740 case 'C': /* sse constant not supported yet */
3741 case 'G': /* 80387 constant not supported yet */
3742 case 'y': /* we don't support mmx registers yet */
3743 case 'Z': /* not available in 32 bit mode */
3744 case 'e': /* not available in 32 bit mode */
3745 panic("unsupported asm constraint '%c' found in (%+F)",
3746 *c, current_ir_graph);
3749 panic("unknown asm constraint '%c' found in (%+F)", *c,
3757 const arch_register_req_t *other_constr;
3759 assert(cls == NULL && "same as and register constraint not supported");
3760 assert(!immediate_possible && "same as and immediate constraint not "
3762 assert(same_as < constraint->n_outs && "wrong constraint number in "
3763 "same_as constraint");
3765 other_constr = constraint->out_reqs[same_as];
3767 req = obstack_alloc(obst, sizeof(req[0]));
3768 req->cls = other_constr->cls;
3769 req->type = arch_register_req_type_should_be_same;
3770 req->limited = NULL;
3771 req->other_same = 1U << pos;
3772 req->other_different = 0;
3774 /* switch constraints. This is because in firm we have same_as
3775 * constraints on the output constraints while in the gcc asm syntax
3776 * they are specified on the input constraints */
3777 constraint->req = other_constr;
3778 constraint->out_reqs[same_as] = req;
3779 constraint->immediate_possible = 0;
3783 if(immediate_possible && cls == NULL) {
3784 cls = &ia32_reg_classes[CLASS_ia32_gp];
3786 assert(!immediate_possible || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3787 assert(cls != NULL);
3789 if(immediate_possible) {
3790 assert(constraint->is_in
3791 && "immediate make no sense for output constraints");
3793 /* todo: check types (no float input on 'r' constrained in and such... */
3796 req = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3797 limited_ptr = (unsigned*) (req+1);
3799 req = obstack_alloc(obst, sizeof(req[0]));
3801 memset(req, 0, sizeof(req[0]));
3804 req->type = arch_register_req_type_limited;
3805 *limited_ptr = limited;
3806 req->limited = limited_ptr;
3808 req->type = arch_register_req_type_normal;
3812 constraint->req = req;
3813 constraint->immediate_possible = immediate_possible;
3814 constraint->immediate_type = immediate_type;
3817 static void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
3818 const char *clobber)
3820 ir_graph *irg = get_irn_irg(node);
3821 struct obstack *obst = get_irg_obstack(irg);
3822 const arch_register_t *reg = NULL;
3825 arch_register_req_t *req;
3826 const arch_register_class_t *cls;
3831 /* TODO: construct a hashmap instead of doing linear search for clobber
3833 for(c = 0; c < N_CLASSES; ++c) {
3834 cls = & ia32_reg_classes[c];
3835 for(r = 0; r < cls->n_regs; ++r) {
3836 const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3837 if(strcmp(temp_reg->name, clobber) == 0
3838 || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3847 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3851 assert(reg->index < 32);
3853 limited = obstack_alloc(obst, sizeof(limited[0]));
3854 *limited = 1 << reg->index;
3856 req = obstack_alloc(obst, sizeof(req[0]));
3857 memset(req, 0, sizeof(req[0]));
3858 req->type = arch_register_req_type_limited;
3860 req->limited = limited;
3862 constraint->req = req;
3863 constraint->immediate_possible = 0;
3864 constraint->immediate_type = 0;
3867 static int is_memory_op(const ir_asm_constraint *constraint)
3869 ident *id = constraint->constraint;
3870 const char *str = get_id_str(id);
3873 for(c = str; *c != '\0'; ++c) {
3882 * generates code for a ASM node
3884 static ir_node *gen_ASM(ir_node *node)
3887 ir_graph *irg = current_ir_graph;
3888 ir_node *block = get_nodes_block(node);
3889 ir_node *new_block = be_transform_node(block);
3890 dbg_info *dbgi = get_irn_dbg_info(node);
3894 int n_out_constraints;
3896 const arch_register_req_t **out_reg_reqs;
3897 const arch_register_req_t **in_reg_reqs;
3898 ia32_asm_reg_t *register_map;
3899 unsigned reg_map_size = 0;
3900 struct obstack *obst;
3901 const ir_asm_constraint *in_constraints;
3902 const ir_asm_constraint *out_constraints;
3904 constraint_t parsed_constraint;
3906 arity = get_irn_arity(node);
3907 in = alloca(arity * sizeof(in[0]));
3908 memset(in, 0, arity * sizeof(in[0]));
3910 n_out_constraints = get_ASM_n_output_constraints(node);
3911 n_clobbers = get_ASM_n_clobbers(node);
3912 out_arity = n_out_constraints + n_clobbers;
3913 /* hack to keep space for mem proj */
3917 in_constraints = get_ASM_input_constraints(node);
3918 out_constraints = get_ASM_output_constraints(node);
3919 clobbers = get_ASM_clobbers(node);
3921 /* construct output constraints */
3922 obst = get_irg_obstack(irg);
3923 out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
3924 parsed_constraint.out_reqs = out_reg_reqs;
3925 parsed_constraint.n_outs = n_out_constraints;
3926 parsed_constraint.is_in = 0;
3928 for(i = 0; i < out_arity; ++i) {
3931 if(i < n_out_constraints) {
3932 const ir_asm_constraint *constraint = &out_constraints[i];
3933 c = get_id_str(constraint->constraint);
3934 parse_asm_constraint(i, &parsed_constraint, c);
3936 if(constraint->pos > reg_map_size)
3937 reg_map_size = constraint->pos;
3939 out_reg_reqs[i] = parsed_constraint.req;
3940 } else if(i < out_arity - 1) {
3941 ident *glob_id = clobbers [i - n_out_constraints];
3942 assert(glob_id != NULL);
3943 c = get_id_str(glob_id);
3944 parse_clobber(node, i, &parsed_constraint, c);
3946 out_reg_reqs[i+1] = parsed_constraint.req;
3950 out_reg_reqs[n_out_constraints] = &no_register_req;
3952 /* construct input constraints */
3953 in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
3954 parsed_constraint.is_in = 1;
3955 for(i = 0; i < arity; ++i) {
3956 const ir_asm_constraint *constraint = &in_constraints[i];
3957 ident *constr_id = constraint->constraint;
3958 const char *c = get_id_str(constr_id);
3960 parse_asm_constraint(i, &parsed_constraint, c);
3961 in_reg_reqs[i] = parsed_constraint.req;
3963 if(constraint->pos > reg_map_size)
3964 reg_map_size = constraint->pos;
3966 if(parsed_constraint.immediate_possible) {
3967 ir_node *pred = get_irn_n(node, i);
3968 char imm_type = parsed_constraint.immediate_type;
3969 ir_node *immediate = try_create_Immediate(pred, imm_type);
3971 if(immediate != NULL) {
3978 register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
3979 memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
3981 for(i = 0; i < n_out_constraints; ++i) {
3982 const ir_asm_constraint *constraint = &out_constraints[i];
3983 unsigned pos = constraint->pos;
3985 assert(pos < reg_map_size);
3986 register_map[pos].use_input = 0;
3987 register_map[pos].valid = 1;
3988 register_map[pos].memory = is_memory_op(constraint);
3989 register_map[pos].inout_pos = i;
3990 register_map[pos].mode = constraint->mode;
3993 /* transform inputs */
3994 for(i = 0; i < arity; ++i) {
3995 const ir_asm_constraint *constraint = &in_constraints[i];
3996 unsigned pos = constraint->pos;
3997 ir_node *pred = get_irn_n(node, i);
3998 ir_node *transformed;
4000 assert(pos < reg_map_size);
4001 register_map[pos].use_input = 1;
4002 register_map[pos].valid = 1;
4003 register_map[pos].memory = is_memory_op(constraint);
4004 register_map[pos].inout_pos = i;
4005 register_map[pos].mode = constraint->mode;
4010 transformed = be_transform_node(pred);
4011 in[i] = transformed;
4014 new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
4015 get_ASM_text(node), register_map);
4017 set_ia32_out_req_all(new_node, out_reg_reqs);
4018 set_ia32_in_req_all(new_node, in_reg_reqs);
4020 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4026 * Transforms a FrameAddr into an ia32 Add.
4028 static ir_node *gen_be_FrameAddr(ir_node *node) {
4029 ir_node *block = be_transform_node(get_nodes_block(node));
4030 ir_node *op = be_get_FrameAddr_frame(node);
4031 ir_node *new_op = be_transform_node(op);
4032 ir_graph *irg = current_ir_graph;
4033 dbg_info *dbgi = get_irn_dbg_info(node);
4034 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4037 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
4038 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
4039 set_ia32_use_frame(new_node);
4041 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4047 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
4049 static ir_node *gen_be_Return(ir_node *node) {
4050 ir_graph *irg = current_ir_graph;
4051 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
4052 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
4053 ir_entity *ent = get_irg_entity(irg);
4054 ir_type *tp = get_entity_type(ent);
4059 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
4060 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
4063 int pn_ret_val, pn_ret_mem, arity, i;
4065 assert(ret_val != NULL);
4066 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4067 return be_duplicate_node(node);
4070 res_type = get_method_res_type(tp, 0);
4072 if (! is_Primitive_type(res_type)) {
4073 return be_duplicate_node(node);
4076 mode = get_type_mode(res_type);
4077 if (! mode_is_float(mode)) {
4078 return be_duplicate_node(node);
4081 assert(get_method_n_ress(tp) == 1);
4083 pn_ret_val = get_Proj_proj(ret_val);
4084 pn_ret_mem = get_Proj_proj(ret_mem);
4086 /* get the Barrier */
4087 barrier = get_Proj_pred(ret_val);
4089 /* get result input of the Barrier */
4090 ret_val = get_irn_n(barrier, pn_ret_val);
4091 new_ret_val = be_transform_node(ret_val);
4093 /* get memory input of the Barrier */
4094 ret_mem = get_irn_n(barrier, pn_ret_mem);
4095 new_ret_mem = be_transform_node(ret_mem);
4097 frame = get_irg_frame(irg);
4099 dbgi = get_irn_dbg_info(barrier);
4100 block = be_transform_node(get_nodes_block(barrier));
4102 noreg = ia32_new_NoReg_gp(env_cg);
4104 /* store xmm0 onto stack */
4105 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
4106 new_ret_mem, new_ret_val);
4107 set_ia32_ls_mode(sse_store, mode);
4108 set_ia32_op_type(sse_store, ia32_AddrModeD);
4109 set_ia32_use_frame(sse_store);
4111 /* load into x87 register */
4112 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
4113 set_ia32_op_type(fld, ia32_AddrModeS);
4114 set_ia32_use_frame(fld);
4116 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
4117 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
4119 /* create a new barrier */
4120 arity = get_irn_arity(barrier);
4121 in = alloca(arity * sizeof(in[0]));
4122 for (i = 0; i < arity; ++i) {
4125 if (i == pn_ret_val) {
4127 } else if (i == pn_ret_mem) {
4130 ir_node *in = get_irn_n(barrier, i);
4131 new_in = be_transform_node(in);
4136 new_barrier = new_ir_node(dbgi, irg, block,
4137 get_irn_op(barrier), get_irn_mode(barrier),
4139 copy_node_attr(barrier, new_barrier);
4140 be_duplicate_deps(barrier, new_barrier);
4141 be_set_transformed_node(barrier, new_barrier);
4142 mark_irn_visited(barrier);
4144 /* transform normally */
4145 return be_duplicate_node(node);
4149 * Transform a be_AddSP into an ia32_SubSP.
4151 static ir_node *gen_be_AddSP(ir_node *node)
4153 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4154 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4156 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
4160 * Transform a be_SubSP into an ia32_AddSP
4162 static ir_node *gen_be_SubSP(ir_node *node)
4164 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4165 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4167 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
4171 * This function just sets the register for the Unknown node
4172 * as this is not done during register allocation because Unknown
4173 * is an "ignore" node.
4175 static ir_node *gen_Unknown(ir_node *node) {
4176 ir_mode *mode = get_irn_mode(node);
4178 if (mode_is_float(mode)) {
4179 if (ia32_cg_config.use_sse2) {
4180 return ia32_new_Unknown_xmm(env_cg);
4182 /* Unknown nodes are buggy in x87 simulator, use zero for now... */
4183 ir_graph *irg = current_ir_graph;
4184 dbg_info *dbgi = get_irn_dbg_info(node);
4185 ir_node *block = get_irg_start_block(irg);
4186 ir_node *ret = new_rd_ia32_vfldz(dbgi, irg, block);
4188 /* Const Nodes before the initial IncSP are a bad idea, because
4189 * they could be spilled and we have no SP ready at that point yet.
4190 * So add a dependency to the initial frame pointer calculation to
4191 * avoid that situation.
4193 add_irn_dep(ret, get_irg_frame(irg));
4196 } else if (mode_needs_gp_reg(mode)) {
4197 return ia32_new_Unknown_gp(env_cg);
4199 panic("unsupported Unknown-Mode");
4205 * Change some phi modes
4207 static ir_node *gen_Phi(ir_node *node) {
4208 ir_node *block = be_transform_node(get_nodes_block(node));
4209 ir_graph *irg = current_ir_graph;
4210 dbg_info *dbgi = get_irn_dbg_info(node);
4211 ir_mode *mode = get_irn_mode(node);
4214 if(mode_needs_gp_reg(mode)) {
4215 /* we shouldn't have any 64bit stuff around anymore */
4216 assert(get_mode_size_bits(mode) <= 32);
4217 /* all integer operations are on 32bit registers now */
4219 } else if(mode_is_float(mode)) {
4220 if (ia32_cg_config.use_sse2) {
4227 /* phi nodes allow loops, so we use the old arguments for now
4228 * and fix this later */
4229 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4230 get_irn_in(node) + 1);
4231 copy_node_attr(node, phi);
4232 be_duplicate_deps(node, phi);
4234 be_set_transformed_node(node, phi);
4235 be_enqueue_preds(node);
4243 static ir_node *gen_IJmp(ir_node *node)
4245 ir_node *block = get_nodes_block(node);
4246 ir_node *new_block = be_transform_node(block);
4247 ir_graph *irg = current_ir_graph;
4248 dbg_info *dbgi = get_irn_dbg_info(node);
4249 ir_node *op = get_IJmp_target(node);
4251 ia32_address_mode_t am;
4252 ia32_address_t *addr = &am.addr;
4254 assert(get_irn_mode(op) == mode_P);
4256 match_arguments(&am, block, NULL, op, NULL,
4257 match_am | match_8bit_am | match_16bit_am |
4258 match_immediate | match_8bit | match_16bit);
4260 new_node = new_rd_ia32_IJmp(dbgi, irg, new_block, addr->base, addr->index,
4261 addr->mem, am.new_op2);
4262 set_am_attributes(new_node, &am);
4263 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4265 new_node = fix_mem_proj(new_node, &am);
4270 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4273 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4274 ir_node *val, ir_node *mem);
4277 * Transforms a lowered Load into a "real" one.
4279 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4281 ir_node *block = be_transform_node(get_nodes_block(node));
4282 ir_node *ptr = get_irn_n(node, 0);
4283 ir_node *new_ptr = be_transform_node(ptr);
4284 ir_node *mem = get_irn_n(node, 1);
4285 ir_node *new_mem = be_transform_node(mem);
4286 ir_graph *irg = current_ir_graph;
4287 dbg_info *dbgi = get_irn_dbg_info(node);
4288 ir_mode *mode = get_ia32_ls_mode(node);
4289 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4292 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4294 set_ia32_op_type(new_op, ia32_AddrModeS);
4295 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4296 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4297 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4298 if (is_ia32_am_sc_sign(node))
4299 set_ia32_am_sc_sign(new_op);
4300 set_ia32_ls_mode(new_op, mode);
4301 if (is_ia32_use_frame(node)) {
4302 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4303 set_ia32_use_frame(new_op);
4306 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4312 * Transforms a lowered Store into a "real" one.
4314 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4316 ir_node *block = be_transform_node(get_nodes_block(node));
4317 ir_node *ptr = get_irn_n(node, 0);
4318 ir_node *new_ptr = be_transform_node(ptr);
4319 ir_node *val = get_irn_n(node, 1);
4320 ir_node *new_val = be_transform_node(val);
4321 ir_node *mem = get_irn_n(node, 2);
4322 ir_node *new_mem = be_transform_node(mem);
4323 ir_graph *irg = current_ir_graph;
4324 dbg_info *dbgi = get_irn_dbg_info(node);
4325 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4326 ir_mode *mode = get_ia32_ls_mode(node);
4330 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4332 am_offs = get_ia32_am_offs_int(node);
4333 add_ia32_am_offs_int(new_op, am_offs);
4335 set_ia32_op_type(new_op, ia32_AddrModeD);
4336 set_ia32_ls_mode(new_op, mode);
4337 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4338 set_ia32_use_frame(new_op);
4340 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4345 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4347 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4348 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4350 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4351 match_immediate | match_mode_neutral);
4354 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4356 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4357 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4358 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4362 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4364 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4365 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4366 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4370 static ir_node *gen_ia32_l_Add(ir_node *node) {
4371 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4372 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4373 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4374 match_commutative | match_am | match_immediate |
4375 match_mode_neutral);
4377 if(is_Proj(lowered)) {
4378 lowered = get_Proj_pred(lowered);
4380 assert(is_ia32_Add(lowered));
4381 set_irn_mode(lowered, mode_T);
4387 static ir_node *gen_ia32_l_Adc(ir_node *node)
4389 return gen_binop_flags(node, new_rd_ia32_Adc,
4390 match_commutative | match_am | match_immediate |
4391 match_mode_neutral);
4395 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4397 * @param node The node to transform
4398 * @return the created ia32 vfild node
4400 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4401 return gen_lowered_Load(node, new_rd_ia32_vfild);
4405 * Transforms an ia32_l_Load into a "real" ia32_Load node
4407 * @param node The node to transform
4408 * @return the created ia32 Load node
4410 static ir_node *gen_ia32_l_Load(ir_node *node) {
4411 return gen_lowered_Load(node, new_rd_ia32_Load);
4415 * Transforms an ia32_l_Store into a "real" ia32_Store node
4417 * @param node The node to transform
4418 * @return the created ia32 Store node
4420 static ir_node *gen_ia32_l_Store(ir_node *node) {
4421 return gen_lowered_Store(node, new_rd_ia32_Store);
4425 * Transforms a l_vfist into a "real" vfist node.
4427 * @param node The node to transform
4428 * @return the created ia32 vfist node
4430 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4431 ir_node *block = be_transform_node(get_nodes_block(node));
4432 ir_node *ptr = get_irn_n(node, 0);
4433 ir_node *new_ptr = be_transform_node(ptr);
4434 ir_node *val = get_irn_n(node, 1);
4435 ir_node *new_val = be_transform_node(val);
4436 ir_node *mem = get_irn_n(node, 2);
4437 ir_node *new_mem = be_transform_node(mem);
4438 ir_graph *irg = current_ir_graph;
4439 dbg_info *dbgi = get_irn_dbg_info(node);
4440 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4441 ir_mode *mode = get_ia32_ls_mode(node);
4442 ir_node *memres, *fist;
4445 memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
4446 am_offs = get_ia32_am_offs_int(node);
4447 add_ia32_am_offs_int(fist, am_offs);
4449 set_ia32_op_type(fist, ia32_AddrModeD);
4450 set_ia32_ls_mode(fist, mode);
4451 set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
4452 set_ia32_use_frame(fist);
4454 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4460 * Transforms a l_MulS into a "real" MulS node.
4462 * @return the created ia32 Mul node
4464 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4465 ir_node *left = get_binop_left(node);
4466 ir_node *right = get_binop_right(node);
4468 return gen_binop(node, left, right, new_rd_ia32_Mul,
4469 match_commutative | match_am | match_mode_neutral);
4473 * Transforms a l_IMulS into a "real" IMul1OPS node.
4475 * @return the created ia32 IMul1OP node
4477 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4478 ir_node *left = get_binop_left(node);
4479 ir_node *right = get_binop_right(node);
4481 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4482 match_commutative | match_am | match_mode_neutral);
4485 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4486 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4487 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4488 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4489 match_am | match_immediate | match_mode_neutral);
4491 if(is_Proj(lowered)) {
4492 lowered = get_Proj_pred(lowered);
4494 assert(is_ia32_Sub(lowered));
4495 set_irn_mode(lowered, mode_T);
4501 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4502 return gen_binop_flags(node, new_rd_ia32_Sbb,
4503 match_am | match_immediate | match_mode_neutral);
4507 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4508 * op1 - target to be shifted
4509 * op2 - contains bits to be shifted into target
4511 * Only op3 can be an immediate.
4513 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4514 ir_node *low, ir_node *count)
4516 ir_node *block = get_nodes_block(node);
4517 ir_node *new_block = be_transform_node(block);
4518 ir_graph *irg = current_ir_graph;
4519 dbg_info *dbgi = get_irn_dbg_info(node);
4520 ir_node *new_high = be_transform_node(high);
4521 ir_node *new_low = be_transform_node(low);
4525 /* the shift amount can be any mode that is bigger than 5 bits, since all
4526 * other bits are ignored anyway */
4527 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4528 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4529 count = get_Conv_op(count);
4531 new_count = create_immediate_or_transform(count, 0);
4533 if (is_ia32_l_ShlD(node)) {
4534 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4537 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4540 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4545 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4547 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4548 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4549 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4550 return gen_lowered_64bit_shifts(node, high, low, count);
4553 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4555 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4556 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4557 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4558 return gen_lowered_64bit_shifts(node, high, low, count);
4561 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4562 ir_node *src_block = get_nodes_block(node);
4563 ir_node *block = be_transform_node(src_block);
4564 ir_graph *irg = current_ir_graph;
4565 dbg_info *dbgi = get_irn_dbg_info(node);
4566 ir_node *frame = get_irg_frame(irg);
4567 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4568 ir_node *nomem = new_NoMem();
4569 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4570 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4571 ir_node *new_val_low = be_transform_node(val_low);
4572 ir_node *new_val_high = be_transform_node(val_high);
4577 ir_node *store_high;
4579 if(!mode_is_signed(get_irn_mode(val_high))) {
4580 panic("unsigned long long -> float not supported yet (%+F)", node);
4584 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4586 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4588 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4589 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4591 set_ia32_use_frame(store_low);
4592 set_ia32_use_frame(store_high);
4593 set_ia32_op_type(store_low, ia32_AddrModeD);
4594 set_ia32_op_type(store_high, ia32_AddrModeD);
4595 set_ia32_ls_mode(store_low, mode_Iu);
4596 set_ia32_ls_mode(store_high, mode_Is);
4597 add_ia32_am_offs_int(store_high, 4);
4601 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4604 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4606 set_ia32_use_frame(fild);
4607 set_ia32_op_type(fild, ia32_AddrModeS);
4608 set_ia32_ls_mode(fild, mode_Ls);
4610 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4612 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4615 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4616 ir_node *src_block = get_nodes_block(node);
4617 ir_node *block = be_transform_node(src_block);
4618 ir_graph *irg = current_ir_graph;
4619 dbg_info *dbgi = get_irn_dbg_info(node);
4620 ir_node *frame = get_irg_frame(irg);
4621 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4622 ir_node *nomem = new_NoMem();
4623 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4624 ir_node *new_val = be_transform_node(val);
4625 ir_node *fist, *mem;
4627 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4628 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4629 set_ia32_use_frame(fist);
4630 set_ia32_op_type(fist, ia32_AddrModeD);
4631 set_ia32_ls_mode(fist, mode_Ls);
4637 * the BAD transformer.
4639 static ir_node *bad_transform(ir_node *node) {
4640 panic("No transform function for %+F available.\n", node);
4644 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4645 ir_graph *irg = current_ir_graph;
4646 ir_node *block = be_transform_node(get_nodes_block(node));
4647 ir_node *pred = get_Proj_pred(node);
4648 ir_node *new_pred = be_transform_node(pred);
4649 ir_node *frame = get_irg_frame(irg);
4650 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4651 dbg_info *dbgi = get_irn_dbg_info(node);
4652 long pn = get_Proj_proj(node);
4657 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4658 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4659 set_ia32_use_frame(load);
4660 set_ia32_op_type(load, ia32_AddrModeS);
4661 set_ia32_ls_mode(load, mode_Iu);
4662 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4663 * 32 bit from it with this particular load */
4664 attr = get_ia32_attr(load);
4665 attr->data.need_64bit_stackent = 1;
4667 if (pn == pn_ia32_l_FloattoLL_res_high) {
4668 add_ia32_am_offs_int(load, 4);
4670 assert(pn == pn_ia32_l_FloattoLL_res_low);
4673 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4679 * Transform the Projs of an AddSP.
4681 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4682 ir_node *block = be_transform_node(get_nodes_block(node));
4683 ir_node *pred = get_Proj_pred(node);
4684 ir_node *new_pred = be_transform_node(pred);
4685 ir_graph *irg = current_ir_graph;
4686 dbg_info *dbgi = get_irn_dbg_info(node);
4687 long proj = get_Proj_proj(node);
4689 if (proj == pn_be_AddSP_sp) {
4690 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4691 pn_ia32_SubSP_stack);
4692 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4694 } else if(proj == pn_be_AddSP_res) {
4695 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4696 pn_ia32_SubSP_addr);
4697 } else if (proj == pn_be_AddSP_M) {
4698 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4702 return new_rd_Unknown(irg, get_irn_mode(node));
4706 * Transform the Projs of a SubSP.
4708 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4709 ir_node *block = be_transform_node(get_nodes_block(node));
4710 ir_node *pred = get_Proj_pred(node);
4711 ir_node *new_pred = be_transform_node(pred);
4712 ir_graph *irg = current_ir_graph;
4713 dbg_info *dbgi = get_irn_dbg_info(node);
4714 long proj = get_Proj_proj(node);
4716 if (proj == pn_be_SubSP_sp) {
4717 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4718 pn_ia32_AddSP_stack);
4719 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4721 } else if (proj == pn_be_SubSP_M) {
4722 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4726 return new_rd_Unknown(irg, get_irn_mode(node));
4730 * Transform and renumber the Projs from a Load.
4732 static ir_node *gen_Proj_Load(ir_node *node) {
4734 ir_node *block = be_transform_node(get_nodes_block(node));
4735 ir_node *pred = get_Proj_pred(node);
4736 ir_graph *irg = current_ir_graph;
4737 dbg_info *dbgi = get_irn_dbg_info(node);
4738 long proj = get_Proj_proj(node);
4741 /* loads might be part of source address mode matches, so we don't
4742 transform the ProjMs yet (with the exception of loads whose result is
4745 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4748 assert(pn_ia32_Load_M == 1); /* convention: mem-result of Source-AM
4750 /* this is needed, because sometimes we have loops that are only
4751 reachable through the ProjM */
4752 be_enqueue_preds(node);
4753 /* do it in 2 steps, to silence firm verifier */
4754 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4755 set_Proj_proj(res, pn_ia32_Load_M);
4759 /* renumber the proj */
4760 new_pred = be_transform_node(pred);
4761 if (is_ia32_Load(new_pred)) {
4764 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4766 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4767 case pn_Load_X_regular:
4768 return new_rd_Jmp(dbgi, irg, block);
4769 case pn_Load_X_except:
4770 /* This Load might raise an exception. Mark it. */
4771 set_ia32_exc_label(new_pred, 1);
4772 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4776 } else if (is_ia32_Conv_I2I(new_pred) ||
4777 is_ia32_Conv_I2I8Bit(new_pred)) {
4778 set_irn_mode(new_pred, mode_T);
4779 if (proj == pn_Load_res) {
4780 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4781 } else if (proj == pn_Load_M) {
4782 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4784 } else if (is_ia32_xLoad(new_pred)) {
4787 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4789 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4790 case pn_Load_X_regular:
4791 return new_rd_Jmp(dbgi, irg, block);
4792 case pn_Load_X_except:
4793 /* This Load might raise an exception. Mark it. */
4794 set_ia32_exc_label(new_pred, 1);
4795 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4799 } else if (is_ia32_vfld(new_pred)) {
4802 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4804 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4805 case pn_Load_X_regular:
4806 return new_rd_Jmp(dbgi, irg, block);
4807 case pn_Load_X_except:
4808 /* This Load might raise an exception. Mark it. */
4809 set_ia32_exc_label(new_pred, 1);
4810 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4815 /* can happen for ProJMs when source address mode happened for the
4818 /* however it should not be the result proj, as that would mean the
4819 load had multiple users and should not have been used for
4821 if (proj != pn_Load_M) {
4822 panic("internal error: transformed node not a Load");
4824 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4828 return new_rd_Unknown(irg, get_irn_mode(node));
4832 * Transform and renumber the Projs from a DivMod like instruction.
4834 static ir_node *gen_Proj_DivMod(ir_node *node) {
4835 ir_node *block = be_transform_node(get_nodes_block(node));
4836 ir_node *pred = get_Proj_pred(node);
4837 ir_node *new_pred = be_transform_node(pred);
4838 ir_graph *irg = current_ir_graph;
4839 dbg_info *dbgi = get_irn_dbg_info(node);
4840 ir_mode *mode = get_irn_mode(node);
4841 long proj = get_Proj_proj(node);
4843 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4845 switch (get_irn_opcode(pred)) {
4849 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4851 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4852 case pn_Div_X_regular:
4853 return new_rd_Jmp(dbgi, irg, block);
4854 case pn_Div_X_except:
4855 set_ia32_exc_label(new_pred, 1);
4856 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4864 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4866 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4867 case pn_Mod_X_except:
4868 set_ia32_exc_label(new_pred, 1);
4869 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4877 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4878 case pn_DivMod_res_div:
4879 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4880 case pn_DivMod_res_mod:
4881 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4882 case pn_DivMod_X_regular:
4883 return new_rd_Jmp(dbgi, irg, block);
4884 case pn_DivMod_X_except:
4885 set_ia32_exc_label(new_pred, 1);
4886 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4896 return new_rd_Unknown(irg, mode);
4900 * Transform and renumber the Projs from a CopyB.
4902 static ir_node *gen_Proj_CopyB(ir_node *node) {
4903 ir_node *block = be_transform_node(get_nodes_block(node));
4904 ir_node *pred = get_Proj_pred(node);
4905 ir_node *new_pred = be_transform_node(pred);
4906 ir_graph *irg = current_ir_graph;
4907 dbg_info *dbgi = get_irn_dbg_info(node);
4908 ir_mode *mode = get_irn_mode(node);
4909 long proj = get_Proj_proj(node);
4912 case pn_CopyB_M_regular:
4913 if (is_ia32_CopyB_i(new_pred)) {
4914 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4915 } else if (is_ia32_CopyB(new_pred)) {
4916 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4924 return new_rd_Unknown(irg, mode);
4928 * Transform and renumber the Projs from a Quot.
4930 static ir_node *gen_Proj_Quot(ir_node *node) {
4931 ir_node *block = be_transform_node(get_nodes_block(node));
4932 ir_node *pred = get_Proj_pred(node);
4933 ir_node *new_pred = be_transform_node(pred);
4934 ir_graph *irg = current_ir_graph;
4935 dbg_info *dbgi = get_irn_dbg_info(node);
4936 ir_mode *mode = get_irn_mode(node);
4937 long proj = get_Proj_proj(node);
4941 if (is_ia32_xDiv(new_pred)) {
4942 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4943 } else if (is_ia32_vfdiv(new_pred)) {
4944 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4948 if (is_ia32_xDiv(new_pred)) {
4949 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4950 } else if (is_ia32_vfdiv(new_pred)) {
4951 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4954 case pn_Quot_X_regular:
4955 case pn_Quot_X_except:
4961 return new_rd_Unknown(irg, mode);
4965 * Transform the Thread Local Storage Proj.
4967 static ir_node *gen_Proj_tls(ir_node *node) {
4968 ir_node *block = be_transform_node(get_nodes_block(node));
4969 ir_graph *irg = current_ir_graph;
4970 dbg_info *dbgi = NULL;
4971 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4976 static ir_node *gen_be_Call(ir_node *node) {
4977 ir_node *res = be_duplicate_node(node);
4978 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4983 static ir_node *gen_be_IncSP(ir_node *node) {
4984 ir_node *res = be_duplicate_node(node);
4985 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4991 * Transform the Projs from a be_Call.
4993 static ir_node *gen_Proj_be_Call(ir_node *node) {
4994 ir_node *block = be_transform_node(get_nodes_block(node));
4995 ir_node *call = get_Proj_pred(node);
4996 ir_node *new_call = be_transform_node(call);
4997 ir_graph *irg = current_ir_graph;
4998 dbg_info *dbgi = get_irn_dbg_info(node);
4999 ir_type *method_type = be_Call_get_type(call);
5000 int n_res = get_method_n_ress(method_type);
5001 long proj = get_Proj_proj(node);
5002 ir_mode *mode = get_irn_mode(node);
5004 const arch_register_class_t *cls;
5006 /* The following is kinda tricky: If we're using SSE, then we have to
5007 * move the result value of the call in floating point registers to an
5008 * xmm register, we therefore construct a GetST0 -> xLoad sequence
5009 * after the call, we have to make sure to correctly make the
5010 * MemProj and the result Proj use these 2 nodes
5012 if (proj == pn_be_Call_M_regular) {
5013 // get new node for result, are we doing the sse load/store hack?
5014 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5015 ir_node *call_res_new;
5016 ir_node *call_res_pred = NULL;
5018 if (call_res != NULL) {
5019 call_res_new = be_transform_node(call_res);
5020 call_res_pred = get_Proj_pred(call_res_new);
5023 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
5024 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5025 pn_be_Call_M_regular);
5027 assert(is_ia32_xLoad(call_res_pred));
5028 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5032 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5033 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5035 ir_node *frame = get_irg_frame(irg);
5036 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
5038 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5041 /* in case there is no memory output: create one to serialize the copy
5043 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5044 pn_be_Call_M_regular);
5045 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5046 pn_be_Call_first_res);
5048 /* store st(0) onto stack */
5049 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
5051 set_ia32_op_type(fstp, ia32_AddrModeD);
5052 set_ia32_use_frame(fstp);
5054 /* load into SSE register */
5055 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5057 set_ia32_op_type(sse_load, ia32_AddrModeS);
5058 set_ia32_use_frame(sse_load);
5060 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5066 /* transform call modes */
5067 if (mode_is_data(mode)) {
5068 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5072 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5076 * Transform the Projs from a Cmp.
5078 static ir_node *gen_Proj_Cmp(ir_node *node)
5080 /* this probably means not all mode_b nodes were lowered... */
5081 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5086 * Transform and potentially renumber Proj nodes.
5088 static ir_node *gen_Proj(ir_node *node) {
5089 ir_node *pred = get_Proj_pred(node);
5090 if (is_Store(pred)) {
5091 long proj = get_Proj_proj(node);
5092 if (proj == pn_Store_M) {
5093 return be_transform_node(pred);
5096 return new_r_Bad(current_ir_graph);
5098 } else if (is_Load(pred)) {
5099 return gen_Proj_Load(node);
5100 } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
5101 return gen_Proj_DivMod(node);
5102 } else if (is_CopyB(pred)) {
5103 return gen_Proj_CopyB(node);
5104 } else if (is_Quot(pred)) {
5105 return gen_Proj_Quot(node);
5106 } else if (be_is_SubSP(pred)) {
5107 return gen_Proj_be_SubSP(node);
5108 } else if (be_is_AddSP(pred)) {
5109 return gen_Proj_be_AddSP(node);
5110 } else if (be_is_Call(pred)) {
5111 return gen_Proj_be_Call(node);
5112 } else if (is_Cmp(pred)) {
5113 return gen_Proj_Cmp(node);
5114 } else if (get_irn_op(pred) == op_Start) {
5115 long proj = get_Proj_proj(node);
5116 if (proj == pn_Start_X_initial_exec) {
5117 ir_node *block = get_nodes_block(pred);
5118 dbg_info *dbgi = get_irn_dbg_info(node);
5121 /* we exchange the ProjX with a jump */
5122 block = be_transform_node(block);
5123 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
5126 if (node == be_get_old_anchor(anchor_tls)) {
5127 return gen_Proj_tls(node);
5129 } else if (is_ia32_l_FloattoLL(pred)) {
5130 return gen_Proj_l_FloattoLL(node);
5132 } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5136 ir_mode *mode = get_irn_mode(node);
5137 if (mode_needs_gp_reg(mode)) {
5138 ir_node *new_pred = be_transform_node(pred);
5139 ir_node *block = be_transform_node(get_nodes_block(node));
5140 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5141 mode_Iu, get_Proj_proj(node));
5142 #ifdef DEBUG_libfirm
5143 new_proj->node_nr = node->node_nr;
5149 return be_duplicate_node(node);
5153 * Enters all transform functions into the generic pointer
5155 static void register_transformers(void)
5159 /* first clear the generic function pointer for all ops */
5160 clear_irp_opcodes_generic_func();
5162 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5163 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5201 /* transform ops from intrinsic lowering */
5217 GEN(ia32_l_LLtoFloat);
5218 GEN(ia32_l_FloattoLL);
5224 /* we should never see these nodes */
5239 /* handle generic backend nodes */
5248 op_Mulh = get_op_Mulh();
5257 * Pre-transform all unknown and noreg nodes.
5259 static void ia32_pretransform_node(void *arch_cg) {
5260 ia32_code_gen_t *cg = arch_cg;
5262 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5263 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5264 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5265 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5266 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5267 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5272 * Walker, checks if all ia32 nodes producing more than one result have
5273 * its Projs, other wise creates new projs and keep them using a be_Keep node.
5275 static void add_missing_keep_walker(ir_node *node, void *data)
5278 unsigned found_projs = 0;
5279 const ir_edge_t *edge;
5280 ir_mode *mode = get_irn_mode(node);
5285 if(!is_ia32_irn(node))
5288 n_outs = get_ia32_n_res(node);
5291 if(is_ia32_SwitchJmp(node))
5294 assert(n_outs < (int) sizeof(unsigned) * 8);
5295 foreach_out_edge(node, edge) {
5296 ir_node *proj = get_edge_src_irn(edge);
5297 int pn = get_Proj_proj(proj);
5299 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
5300 found_projs |= 1 << pn;
5304 /* are keeps missing? */
5306 for(i = 0; i < n_outs; ++i) {
5309 const arch_register_req_t *req;
5310 const arch_register_class_t *class;
5312 if(found_projs & (1 << i)) {
5316 req = get_ia32_out_req(node, i);
5321 if(class == &ia32_reg_classes[CLASS_ia32_flags]) {
5325 block = get_nodes_block(node);
5326 in[0] = new_r_Proj(current_ir_graph, block, node,
5327 arch_register_class_mode(class), i);
5328 if(last_keep != NULL) {
5329 be_Keep_add_node(last_keep, class, in[0]);
5331 last_keep = be_new_Keep(class, current_ir_graph, block, 1, in);
5332 if(sched_is_scheduled(node)) {
5333 sched_add_after(node, last_keep);
5340 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5343 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5345 ir_graph *irg = be_get_birg_irg(cg->birg);
5346 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5349 /* do the transformation */
5350 void ia32_transform_graph(ia32_code_gen_t *cg) {
5352 ir_graph *irg = cg->irg;
5354 register_transformers();
5356 initial_fpcw = NULL;
5358 BE_TIMER_PUSH(t_heights);
5359 heights = heights_new(irg);
5360 BE_TIMER_POP(t_heights);
5361 ia32_calculate_non_address_mode_nodes(cg->birg);
5363 /* the transform phase is not safe for CSE (yet) because several nodes get
5364 * attributes set after their creation */
5365 cse_last = get_opt_cse();
5368 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5370 set_opt_cse(cse_last);
5372 ia32_free_non_address_mode_nodes();
5373 heights_free(heights);
5377 void ia32_init_transform(void)
5379 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");