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;
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, match_flags_t flags)
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) != (flags & match_two_users ? 2 : 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);
763 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
765 ir_mode *mode = get_irn_mode(node);
770 if(mode_is_signed(mode)) {
775 block = get_nodes_block(node);
776 dbgi = get_irn_dbg_info(node);
778 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
782 * matches operands of a node into ia32 addressing/operand modes. This covers
783 * usage of source address mode, immediates, operations with non 32-bit modes,
785 * The resulting data is filled into the @p am struct. block is the block
786 * of the node whose arguments are matched. op1, op2 are the first and second
787 * input that are matched (op1 may be NULL). other_op is another unrelated
788 * input that is not matched! but which is needed sometimes to check if AM
789 * for op1/op2 is legal.
790 * @p flags describes the supported modes of the operation in detail.
792 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
793 ir_node *op1, ir_node *op2, ir_node *other_op,
796 ia32_address_t *addr = &am->addr;
797 ir_mode *mode = get_irn_mode(op2);
798 int mode_bits = get_mode_size_bits(mode);
799 ir_node *noreg_gp, *new_op1, *new_op2;
801 unsigned commutative;
802 int use_am_and_immediates;
805 memset(am, 0, sizeof(am[0]));
807 commutative = (flags & match_commutative) != 0;
808 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
809 use_am = (flags & match_am) != 0;
810 use_immediate = (flags & match_immediate) != 0;
811 assert(!use_am_and_immediates || use_immediate);
814 assert(!commutative || op1 != NULL);
815 assert(use_am || !(flags & match_8bit_am));
816 assert(use_am || !(flags & match_16bit_am));
818 if (mode_bits == 8) {
819 if (!(flags & match_8bit_am))
821 /* we don't automatically add upconvs yet */
822 assert((flags & match_mode_neutral) || (flags & match_8bit));
823 } else if (mode_bits == 16) {
824 if (!(flags & match_16bit_am))
826 /* we don't automatically add upconvs yet */
827 assert((flags & match_mode_neutral) || (flags & match_16bit));
830 /* we can simply skip downconvs for mode neutral nodes: the upper bits
831 * can be random for these operations */
832 if (flags & match_mode_neutral) {
833 op2 = ia32_skip_downconv(op2);
835 op1 = ia32_skip_downconv(op1);
839 /* match immediates. firm nodes are normalized: constants are always on the
842 if (!(flags & match_try_am) && use_immediate) {
843 new_op2 = try_create_Immediate(op2, 0);
846 noreg_gp = ia32_new_NoReg_gp(env_cg);
847 if (new_op2 == NULL &&
848 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
849 build_address(am, op2);
850 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
851 if (mode_is_float(mode)) {
852 new_op2 = ia32_new_NoReg_vfp(env_cg);
856 am->op_type = ia32_AddrModeS;
857 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
859 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
861 build_address(am, op1);
863 if (mode_is_float(mode)) {
864 noreg = ia32_new_NoReg_vfp(env_cg);
869 if (new_op2 != NULL) {
872 new_op1 = be_transform_node(op2);
874 am->ins_permuted = 1;
876 am->op_type = ia32_AddrModeS;
878 if (flags & match_try_am) {
881 am->op_type = ia32_Normal;
885 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
887 new_op2 = be_transform_node(op2);
888 am->op_type = ia32_Normal;
889 am->ls_mode = get_irn_mode(op2);
890 if (flags & match_mode_neutral)
891 am->ls_mode = mode_Iu;
893 if (addr->base == NULL)
894 addr->base = noreg_gp;
895 if (addr->index == NULL)
896 addr->index = noreg_gp;
897 if (addr->mem == NULL)
898 addr->mem = new_NoMem();
900 am->new_op1 = new_op1;
901 am->new_op2 = new_op2;
902 am->commutative = commutative;
905 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
910 if (am->mem_proj == NULL)
913 /* we have to create a mode_T so the old MemProj can attach to us */
914 mode = get_irn_mode(node);
915 load = get_Proj_pred(am->mem_proj);
917 mark_irn_visited(load);
918 be_set_transformed_node(load, node);
920 if (mode != mode_T) {
921 set_irn_mode(node, mode_T);
922 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
929 * Construct a standard binary operation, set AM and immediate if required.
931 * @param node The original node for which the binop is created
932 * @param op1 The first operand
933 * @param op2 The second operand
934 * @param func The node constructor function
935 * @return The constructed ia32 node.
937 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
938 construct_binop_func *func, match_flags_t flags)
941 ir_node *block, *new_block, *new_node;
942 ia32_address_mode_t am;
943 ia32_address_t *addr = &am.addr;
945 block = get_nodes_block(node);
946 match_arguments(&am, block, op1, op2, NULL, flags);
948 dbgi = get_irn_dbg_info(node);
949 new_block = be_transform_node(block);
950 new_node = func(dbgi, current_ir_graph, new_block,
951 addr->base, addr->index, addr->mem,
952 am.new_op1, am.new_op2);
953 set_am_attributes(new_node, &am);
954 /* we can't use source address mode anymore when using immediates */
955 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
956 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
957 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
959 new_node = fix_mem_proj(new_node, &am);
966 n_ia32_l_binop_right,
967 n_ia32_l_binop_eflags
969 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
970 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
971 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
972 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
973 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
974 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
977 * Construct a binary operation which also consumes the eflags.
979 * @param node The node to transform
980 * @param func The node constructor function
981 * @param flags The match flags
982 * @return The constructor ia32 node
984 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
987 ir_node *src_block = get_nodes_block(node);
988 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
989 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
991 ir_node *block, *new_node, *eflags, *new_eflags;
992 ia32_address_mode_t am;
993 ia32_address_t *addr = &am.addr;
995 match_arguments(&am, src_block, op1, op2, NULL, flags);
997 dbgi = get_irn_dbg_info(node);
998 block = be_transform_node(src_block);
999 eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1000 new_eflags = be_transform_node(eflags);
1001 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
1002 addr->mem, am.new_op1, am.new_op2, new_eflags);
1003 set_am_attributes(new_node, &am);
1004 /* we can't use source address mode anymore when using immediates */
1005 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1006 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1007 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1009 new_node = fix_mem_proj(new_node, &am);
1014 static ir_node *get_fpcw(void)
1017 if (initial_fpcw != NULL)
1018 return initial_fpcw;
1020 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
1021 &ia32_fp_cw_regs[REG_FPCW]);
1022 initial_fpcw = be_transform_node(fpcw);
1024 return initial_fpcw;
1028 * Construct a standard binary operation, set AM and immediate if required.
1030 * @param op1 The first operand
1031 * @param op2 The second operand
1032 * @param func The node constructor function
1033 * @return The constructed ia32 node.
1035 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1036 construct_binop_float_func *func,
1037 match_flags_t flags)
1039 ir_mode *mode = get_irn_mode(node);
1041 ir_node *block, *new_block, *new_node;
1042 ia32_address_mode_t am;
1043 ia32_address_t *addr = &am.addr;
1045 /* cannot use address mode with long double on x87 */
1046 if (get_mode_size_bits(mode) > 64)
1049 block = get_nodes_block(node);
1050 match_arguments(&am, block, op1, op2, NULL, flags);
1052 dbgi = get_irn_dbg_info(node);
1053 new_block = be_transform_node(block);
1054 new_node = func(dbgi, current_ir_graph, new_block,
1055 addr->base, addr->index, addr->mem,
1056 am.new_op1, am.new_op2, get_fpcw());
1057 set_am_attributes(new_node, &am);
1059 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1061 new_node = fix_mem_proj(new_node, &am);
1067 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1069 * @param op1 The first operand
1070 * @param op2 The second operand
1071 * @param func The node constructor function
1072 * @return The constructed ia32 node.
1074 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1075 construct_shift_func *func,
1076 match_flags_t flags)
1079 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1081 assert(! mode_is_float(get_irn_mode(node)));
1082 assert(flags & match_immediate);
1083 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1085 if (flags & match_mode_neutral) {
1086 op1 = ia32_skip_downconv(op1);
1087 new_op1 = be_transform_node(op1);
1088 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1089 new_op1 = create_upconv(op1, node);
1091 new_op1 = be_transform_node(op1);
1094 /* the shift amount can be any mode that is bigger than 5 bits, since all
1095 * other bits are ignored anyway */
1096 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1097 op2 = get_Conv_op(op2);
1098 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1100 new_op2 = create_immediate_or_transform(op2, 0);
1102 dbgi = get_irn_dbg_info(node);
1103 block = get_nodes_block(node);
1104 new_block = be_transform_node(block);
1105 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1106 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1108 /* lowered shift instruction may have a dependency operand, handle it here */
1109 if (get_irn_arity(node) == 3) {
1110 /* we have a dependency */
1111 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1112 add_irn_dep(new_node, new_dep);
1120 * Construct a standard unary operation, set AM and immediate if required.
1122 * @param op The operand
1123 * @param func The node constructor function
1124 * @return The constructed ia32 node.
1126 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1127 match_flags_t flags)
1130 ir_node *block, *new_block, *new_op, *new_node;
1132 assert(flags == 0 || flags == match_mode_neutral);
1133 if (flags & match_mode_neutral) {
1134 op = ia32_skip_downconv(op);
1137 new_op = be_transform_node(op);
1138 dbgi = get_irn_dbg_info(node);
1139 block = get_nodes_block(node);
1140 new_block = be_transform_node(block);
1141 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1143 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1148 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1149 ia32_address_t *addr)
1151 ir_node *base, *index, *res;
1155 base = ia32_new_NoReg_gp(env_cg);
1157 base = be_transform_node(base);
1160 index = addr->index;
1161 if (index == NULL) {
1162 index = ia32_new_NoReg_gp(env_cg);
1164 index = be_transform_node(index);
1167 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1168 set_address(res, addr);
1174 * Returns non-zero if a given address mode has a symbolic or
1175 * numerical offset != 0.
1177 static int am_has_immediates(const ia32_address_t *addr)
1179 return addr->offset != 0 || addr->symconst_ent != NULL
1180 || addr->frame_entity || addr->use_frame;
1184 * Creates an ia32 Add.
1186 * @return the created ia32 Add node
1188 static ir_node *gen_Add(ir_node *node) {
1189 ir_mode *mode = get_irn_mode(node);
1190 ir_node *op1 = get_Add_left(node);
1191 ir_node *op2 = get_Add_right(node);
1193 ir_node *block, *new_block, *new_node, *add_immediate_op;
1194 ia32_address_t addr;
1195 ia32_address_mode_t am;
1197 if (mode_is_float(mode)) {
1198 if (ia32_cg_config.use_sse2)
1199 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1200 match_commutative | match_am);
1202 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1203 match_commutative | match_am);
1206 ia32_mark_non_am(node);
1208 op2 = ia32_skip_downconv(op2);
1209 op1 = ia32_skip_downconv(op1);
1213 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1214 * 1. Add with immediate -> Lea
1215 * 2. Add with possible source address mode -> Add
1216 * 3. Otherwise -> Lea
1218 memset(&addr, 0, sizeof(addr));
1219 ia32_create_address_mode(&addr, node, /*force=*/1);
1220 add_immediate_op = NULL;
1222 dbgi = get_irn_dbg_info(node);
1223 block = get_nodes_block(node);
1224 new_block = be_transform_node(block);
1227 if(addr.base == NULL && addr.index == NULL) {
1228 ir_graph *irg = current_ir_graph;
1229 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1230 addr.symconst_sign, addr.offset);
1231 add_irn_dep(new_node, get_irg_frame(irg));
1232 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1235 /* add with immediate? */
1236 if(addr.index == NULL) {
1237 add_immediate_op = addr.base;
1238 } else if(addr.base == NULL && addr.scale == 0) {
1239 add_immediate_op = addr.index;
1242 if(add_immediate_op != NULL) {
1243 if(!am_has_immediates(&addr)) {
1244 #ifdef DEBUG_libfirm
1245 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1248 return be_transform_node(add_immediate_op);
1251 new_node = create_lea_from_address(dbgi, new_block, &addr);
1252 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1256 /* test if we can use source address mode */
1257 match_arguments(&am, block, op1, op2, NULL, match_commutative
1258 | match_mode_neutral | match_am | match_immediate | match_try_am);
1260 /* construct an Add with source address mode */
1261 if (am.op_type == ia32_AddrModeS) {
1262 ir_graph *irg = current_ir_graph;
1263 ia32_address_t *am_addr = &am.addr;
1264 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1265 am_addr->index, am_addr->mem, am.new_op1,
1267 set_am_attributes(new_node, &am);
1268 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1270 new_node = fix_mem_proj(new_node, &am);
1275 /* otherwise construct a lea */
1276 new_node = create_lea_from_address(dbgi, new_block, &addr);
1277 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1282 * Creates an ia32 Mul.
1284 * @return the created ia32 Mul node
1286 static ir_node *gen_Mul(ir_node *node) {
1287 ir_node *op1 = get_Mul_left(node);
1288 ir_node *op2 = get_Mul_right(node);
1289 ir_mode *mode = get_irn_mode(node);
1291 if (mode_is_float(mode)) {
1292 if (ia32_cg_config.use_sse2)
1293 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1294 match_commutative | match_am);
1296 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1297 match_commutative | match_am);
1299 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1300 match_commutative | match_am | match_mode_neutral |
1301 match_immediate | match_am_and_immediates);
1305 * Creates an ia32 Mulh.
1306 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1307 * this result while Mul returns the lower 32 bit.
1309 * @return the created ia32 Mulh node
1311 static ir_node *gen_Mulh(ir_node *node)
1313 ir_node *block = get_nodes_block(node);
1314 ir_node *new_block = be_transform_node(block);
1315 ir_graph *irg = current_ir_graph;
1316 dbg_info *dbgi = get_irn_dbg_info(node);
1317 ir_mode *mode = get_irn_mode(node);
1318 ir_node *op1 = get_Mulh_left(node);
1319 ir_node *op2 = get_Mulh_right(node);
1320 ir_node *proj_res_high;
1322 ia32_address_mode_t am;
1323 ia32_address_t *addr = &am.addr;
1325 assert(!mode_is_float(mode) && "Mulh with float not supported");
1326 assert(get_mode_size_bits(mode) == 32);
1328 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1330 if (mode_is_signed(mode)) {
1331 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1332 addr->index, addr->mem, am.new_op1,
1335 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1336 addr->index, addr->mem, am.new_op1,
1340 set_am_attributes(new_node, &am);
1341 /* we can't use source address mode anymore when using immediates */
1342 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1343 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1344 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1346 assert(get_irn_mode(new_node) == mode_T);
1348 fix_mem_proj(new_node, &am);
1350 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1351 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1352 mode_Iu, pn_ia32_IMul1OP_res_high);
1354 return proj_res_high;
1360 * Creates an ia32 And.
1362 * @return The created ia32 And node
1364 static ir_node *gen_And(ir_node *node) {
1365 ir_node *op1 = get_And_left(node);
1366 ir_node *op2 = get_And_right(node);
1367 assert(! mode_is_float(get_irn_mode(node)));
1369 /* is it a zero extension? */
1370 if (is_Const(op2)) {
1371 tarval *tv = get_Const_tarval(op2);
1372 long v = get_tarval_long(tv);
1374 if (v == 0xFF || v == 0xFFFF) {
1375 dbg_info *dbgi = get_irn_dbg_info(node);
1376 ir_node *block = get_nodes_block(node);
1383 assert(v == 0xFFFF);
1386 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1391 return gen_binop(node, op1, op2, new_rd_ia32_And,
1392 match_commutative | match_mode_neutral | match_am
1399 * Creates an ia32 Or.
1401 * @return The created ia32 Or node
1403 static ir_node *gen_Or(ir_node *node) {
1404 ir_node *op1 = get_Or_left(node);
1405 ir_node *op2 = get_Or_right(node);
1407 assert (! mode_is_float(get_irn_mode(node)));
1408 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1409 | match_mode_neutral | match_am | match_immediate);
1415 * Creates an ia32 Eor.
1417 * @return The created ia32 Eor node
1419 static ir_node *gen_Eor(ir_node *node) {
1420 ir_node *op1 = get_Eor_left(node);
1421 ir_node *op2 = get_Eor_right(node);
1423 assert(! mode_is_float(get_irn_mode(node)));
1424 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1425 | match_mode_neutral | match_am | match_immediate);
1430 * Creates an ia32 Sub.
1432 * @return The created ia32 Sub node
1434 static ir_node *gen_Sub(ir_node *node) {
1435 ir_node *op1 = get_Sub_left(node);
1436 ir_node *op2 = get_Sub_right(node);
1437 ir_mode *mode = get_irn_mode(node);
1439 if (mode_is_float(mode)) {
1440 if (ia32_cg_config.use_sse2)
1441 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1443 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1447 if (is_Const(op2)) {
1448 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1452 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1453 | match_am | match_immediate);
1457 * Generates an ia32 DivMod with additional infrastructure for the
1458 * register allocator if needed.
1460 static ir_node *create_Div(ir_node *node)
1462 ir_graph *irg = current_ir_graph;
1463 dbg_info *dbgi = get_irn_dbg_info(node);
1464 ir_node *block = get_nodes_block(node);
1465 ir_node *new_block = be_transform_node(block);
1472 ir_node *sign_extension;
1473 ia32_address_mode_t am;
1474 ia32_address_t *addr = &am.addr;
1476 /* the upper bits have random contents for smaller modes */
1477 switch (get_irn_opcode(node)) {
1479 op1 = get_Div_left(node);
1480 op2 = get_Div_right(node);
1481 mem = get_Div_mem(node);
1482 mode = get_Div_resmode(node);
1485 op1 = get_Mod_left(node);
1486 op2 = get_Mod_right(node);
1487 mem = get_Mod_mem(node);
1488 mode = get_Mod_resmode(node);
1491 op1 = get_DivMod_left(node);
1492 op2 = get_DivMod_right(node);
1493 mem = get_DivMod_mem(node);
1494 mode = get_DivMod_resmode(node);
1497 panic("invalid divmod node %+F", node);
1500 match_arguments(&am, block, op1, op2, NULL, match_am);
1502 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1503 is the memory of the consumed address. We can have only the second op as address
1504 in Div nodes, so check only op2. */
1505 if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1506 new_mem = be_transform_node(mem);
1507 if(!is_NoMem(addr->mem)) {
1511 new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1514 new_mem = addr->mem;
1517 if (mode_is_signed(mode)) {
1518 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1519 add_irn_dep(produceval, get_irg_frame(irg));
1520 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1523 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1524 addr->index, new_mem, am.new_op2,
1525 am.new_op1, sign_extension);
1527 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1528 add_irn_dep(sign_extension, get_irg_frame(irg));
1530 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1531 addr->index, new_mem, am.new_op2,
1532 am.new_op1, sign_extension);
1535 set_irn_pinned(new_node, get_irn_pinned(node));
1537 set_am_attributes(new_node, &am);
1538 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1540 new_node = fix_mem_proj(new_node, &am);
1546 static ir_node *gen_Mod(ir_node *node) {
1547 return create_Div(node);
1550 static ir_node *gen_Div(ir_node *node) {
1551 return create_Div(node);
1554 static ir_node *gen_DivMod(ir_node *node) {
1555 return create_Div(node);
1561 * Creates an ia32 floating Div.
1563 * @return The created ia32 xDiv node
1565 static ir_node *gen_Quot(ir_node *node)
1567 ir_node *op1 = get_Quot_left(node);
1568 ir_node *op2 = get_Quot_right(node);
1570 if (ia32_cg_config.use_sse2) {
1571 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1573 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1579 * Creates an ia32 Shl.
1581 * @return The created ia32 Shl node
1583 static ir_node *gen_Shl(ir_node *node) {
1584 ir_node *left = get_Shl_left(node);
1585 ir_node *right = get_Shl_right(node);
1587 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1588 match_mode_neutral | match_immediate);
1592 * Creates an ia32 Shr.
1594 * @return The created ia32 Shr node
1596 static ir_node *gen_Shr(ir_node *node) {
1597 ir_node *left = get_Shr_left(node);
1598 ir_node *right = get_Shr_right(node);
1600 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1606 * Creates an ia32 Sar.
1608 * @return The created ia32 Shrs node
1610 static ir_node *gen_Shrs(ir_node *node) {
1611 ir_node *left = get_Shrs_left(node);
1612 ir_node *right = get_Shrs_right(node);
1613 ir_mode *mode = get_irn_mode(node);
1615 if(is_Const(right) && mode == mode_Is) {
1616 tarval *tv = get_Const_tarval(right);
1617 long val = get_tarval_long(tv);
1619 /* this is a sign extension */
1620 ir_graph *irg = current_ir_graph;
1621 dbg_info *dbgi = get_irn_dbg_info(node);
1622 ir_node *block = be_transform_node(get_nodes_block(node));
1624 ir_node *new_op = be_transform_node(op);
1625 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1626 add_irn_dep(pval, get_irg_frame(irg));
1628 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1632 /* 8 or 16 bit sign extension? */
1633 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1634 ir_node *shl_left = get_Shl_left(left);
1635 ir_node *shl_right = get_Shl_right(left);
1636 if(is_Const(shl_right)) {
1637 tarval *tv1 = get_Const_tarval(right);
1638 tarval *tv2 = get_Const_tarval(shl_right);
1639 if(tv1 == tv2 && tarval_is_long(tv1)) {
1640 long val = get_tarval_long(tv1);
1641 if(val == 16 || val == 24) {
1642 dbg_info *dbgi = get_irn_dbg_info(node);
1643 ir_node *block = get_nodes_block(node);
1653 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1662 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1668 * Creates an ia32 Rol.
1670 * @param op1 The first operator
1671 * @param op2 The second operator
1672 * @return The created ia32 RotL node
1674 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1675 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1681 * Creates an ia32 Ror.
1682 * NOTE: There is no RotR with immediate because this would always be a RotL
1683 * "imm-mode_size_bits" which can be pre-calculated.
1685 * @param op1 The first operator
1686 * @param op2 The second operator
1687 * @return The created ia32 RotR node
1689 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1690 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1696 * Creates an ia32 RotR or RotL (depending on the found pattern).
1698 * @return The created ia32 RotL or RotR node
1700 static ir_node *gen_Rotl(ir_node *node) {
1701 ir_node *rotate = NULL;
1702 ir_node *op1 = get_Rotl_left(node);
1703 ir_node *op2 = get_Rotl_right(node);
1705 /* Firm has only RotL, so we are looking for a right (op2)
1706 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1707 that means we can create a RotR instead of an Add and a RotL */
1711 ir_node *left = get_Add_left(add);
1712 ir_node *right = get_Add_right(add);
1713 if (is_Const(right)) {
1714 tarval *tv = get_Const_tarval(right);
1715 ir_mode *mode = get_irn_mode(node);
1716 long bits = get_mode_size_bits(mode);
1718 if (is_Minus(left) &&
1719 tarval_is_long(tv) &&
1720 get_tarval_long(tv) == bits &&
1723 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1724 rotate = gen_Ror(node, op1, get_Minus_op(left));
1729 if (rotate == NULL) {
1730 rotate = gen_Rol(node, op1, op2);
1739 * Transforms a Minus node.
1741 * @return The created ia32 Minus node
1743 static ir_node *gen_Minus(ir_node *node)
1745 ir_node *op = get_Minus_op(node);
1746 ir_node *block = be_transform_node(get_nodes_block(node));
1747 ir_graph *irg = current_ir_graph;
1748 dbg_info *dbgi = get_irn_dbg_info(node);
1749 ir_mode *mode = get_irn_mode(node);
1754 if (mode_is_float(mode)) {
1755 ir_node *new_op = be_transform_node(op);
1756 if (ia32_cg_config.use_sse2) {
1757 /* TODO: non-optimal... if we have many xXors, then we should
1758 * rather create a load for the const and use that instead of
1759 * several AM nodes... */
1760 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1761 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1762 ir_node *nomem = new_rd_NoMem(irg);
1764 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1765 nomem, new_op, noreg_xmm);
1767 size = get_mode_size_bits(mode);
1768 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1770 set_ia32_am_sc(new_node, ent);
1771 set_ia32_op_type(new_node, ia32_AddrModeS);
1772 set_ia32_ls_mode(new_node, mode);
1774 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1777 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1780 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1786 * Transforms a Not node.
1788 * @return The created ia32 Not node
1790 static ir_node *gen_Not(ir_node *node) {
1791 ir_node *op = get_Not_op(node);
1793 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1794 assert (! mode_is_float(get_irn_mode(node)));
1796 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1802 * Transforms an Abs node.
1804 * @return The created ia32 Abs node
1806 static ir_node *gen_Abs(ir_node *node)
1808 ir_node *block = get_nodes_block(node);
1809 ir_node *new_block = be_transform_node(block);
1810 ir_node *op = get_Abs_op(node);
1811 ir_graph *irg = current_ir_graph;
1812 dbg_info *dbgi = get_irn_dbg_info(node);
1813 ir_mode *mode = get_irn_mode(node);
1814 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1815 ir_node *nomem = new_NoMem();
1821 if (mode_is_float(mode)) {
1822 new_op = be_transform_node(op);
1824 if (ia32_cg_config.use_sse2) {
1825 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1826 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1827 nomem, new_op, noreg_fp);
1829 size = get_mode_size_bits(mode);
1830 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1832 set_ia32_am_sc(new_node, ent);
1834 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1836 set_ia32_op_type(new_node, ia32_AddrModeS);
1837 set_ia32_ls_mode(new_node, mode);
1839 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1840 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1843 ir_node *xor, *pval, *sign_extension;
1845 if (get_mode_size_bits(mode) == 32) {
1846 new_op = be_transform_node(op);
1848 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1851 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1852 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1855 add_irn_dep(pval, get_irg_frame(irg));
1856 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1858 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1859 nomem, new_op, sign_extension);
1860 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1862 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1863 nomem, xor, sign_extension);
1864 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1871 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1873 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1874 dbg_info *dbgi = get_irn_dbg_info(cmp);
1875 ir_node *block = get_nodes_block(cmp);
1876 ir_node *new_block = be_transform_node(block);
1877 ir_node *op1 = be_transform_node(x);
1878 ir_node *op2 = be_transform_node(n);
1880 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1884 * Transform a node returning a "flag" result.
1886 * @param node the node to transform
1887 * @param pnc_out the compare mode to use
1889 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1898 /* we have a Cmp as input */
1899 if (is_Proj(node)) {
1900 ir_node *pred = get_Proj_pred(node);
1902 pn_Cmp pnc = get_Proj_proj(node);
1903 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1904 ir_node *l = get_Cmp_left(pred);
1905 ir_node *r = get_Cmp_right(pred);
1907 ir_node *la = get_And_left(l);
1908 ir_node *ra = get_And_right(l);
1910 ir_node *c = get_Shl_left(la);
1911 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1912 /* (1 << n) & ra) */
1913 ir_node *n = get_Shl_right(la);
1914 flags = gen_bt(pred, ra, n);
1915 /* we must generate a Jc/Jnc jump */
1916 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1919 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1924 ir_node *c = get_Shl_left(ra);
1925 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1926 /* la & (1 << n)) */
1927 ir_node *n = get_Shl_right(ra);
1928 flags = gen_bt(pred, la, n);
1929 /* we must generate a Jc/Jnc jump */
1930 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1933 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1939 flags = be_transform_node(pred);
1945 /* a mode_b value, we have to compare it against 0 */
1946 dbgi = get_irn_dbg_info(node);
1947 new_block = be_transform_node(get_nodes_block(node));
1948 new_op = be_transform_node(node);
1949 noreg = ia32_new_NoReg_gp(env_cg);
1950 nomem = new_NoMem();
1951 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1952 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1953 *pnc_out = pn_Cmp_Lg;
1958 * Transforms a Load.
1960 * @return the created ia32 Load node
1962 static ir_node *gen_Load(ir_node *node) {
1963 ir_node *old_block = get_nodes_block(node);
1964 ir_node *block = be_transform_node(old_block);
1965 ir_node *ptr = get_Load_ptr(node);
1966 ir_node *mem = get_Load_mem(node);
1967 ir_node *new_mem = be_transform_node(mem);
1970 ir_graph *irg = current_ir_graph;
1971 dbg_info *dbgi = get_irn_dbg_info(node);
1972 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1973 ir_mode *mode = get_Load_mode(node);
1976 ia32_address_t addr;
1978 /* construct load address */
1979 memset(&addr, 0, sizeof(addr));
1980 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1987 base = be_transform_node(base);
1993 index = be_transform_node(index);
1996 if (mode_is_float(mode)) {
1997 if (ia32_cg_config.use_sse2) {
1998 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
2000 res_mode = mode_xmm;
2002 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
2004 res_mode = mode_vfp;
2007 assert(mode != mode_b);
2009 /* create a conv node with address mode for smaller modes */
2010 if(get_mode_size_bits(mode) < 32) {
2011 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
2012 new_mem, noreg, mode);
2014 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
2019 set_irn_pinned(new_node, get_irn_pinned(node));
2020 set_ia32_op_type(new_node, ia32_AddrModeS);
2021 set_ia32_ls_mode(new_node, mode);
2022 set_address(new_node, &addr);
2024 if(get_irn_pinned(node) == op_pin_state_floats) {
2025 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
2028 /* make sure we are scheduled behind the initial IncSP/Barrier
2029 * to avoid spills being placed before it
2031 if (block == get_irg_start_block(irg)) {
2032 add_irn_dep(new_node, get_irg_frame(irg));
2035 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2040 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2041 ir_node *ptr, ir_node *other)
2048 /* we only use address mode if we're the only user of the load */
2049 if(get_irn_n_edges(node) > 1)
2052 load = get_Proj_pred(node);
2055 if(get_nodes_block(load) != block)
2058 /* Store should be attached to the load */
2059 if(!is_Proj(mem) || get_Proj_pred(mem) != load)
2061 /* store should have the same pointer as the load */
2062 if(get_Load_ptr(load) != ptr)
2065 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2066 if(other != NULL && get_nodes_block(other) == block
2067 && heights_reachable_in_block(heights, other, load))
2073 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2074 ir_node *mem, ir_node *ptr, ir_mode *mode,
2075 construct_binop_dest_func *func,
2076 construct_binop_dest_func *func8bit,
2077 match_flags_t flags)
2079 ir_node *src_block = get_nodes_block(node);
2081 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2082 ir_graph *irg = current_ir_graph;
2087 ia32_address_mode_t am;
2088 ia32_address_t *addr = &am.addr;
2089 memset(&am, 0, sizeof(am));
2091 assert(flags & match_dest_am);
2092 assert(flags & match_immediate); /* there is no destam node without... */
2093 commutative = (flags & match_commutative) != 0;
2095 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2096 build_address(&am, op1);
2097 new_op = create_immediate_or_transform(op2, 0);
2098 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2099 build_address(&am, op2);
2100 new_op = create_immediate_or_transform(op1, 0);
2105 if(addr->base == NULL)
2106 addr->base = noreg_gp;
2107 if(addr->index == NULL)
2108 addr->index = noreg_gp;
2109 if(addr->mem == NULL)
2110 addr->mem = new_NoMem();
2112 dbgi = get_irn_dbg_info(node);
2113 block = be_transform_node(src_block);
2114 if(get_mode_size_bits(mode) == 8) {
2115 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2118 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
2121 set_address(new_node, addr);
2122 set_ia32_op_type(new_node, ia32_AddrModeD);
2123 set_ia32_ls_mode(new_node, mode);
2124 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2129 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2130 ir_node *ptr, ir_mode *mode,
2131 construct_unop_dest_func *func)
2133 ir_graph *irg = current_ir_graph;
2134 ir_node *src_block = get_nodes_block(node);
2138 ia32_address_mode_t am;
2139 ia32_address_t *addr = &am.addr;
2140 memset(&am, 0, sizeof(am));
2142 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2145 build_address(&am, op);
2147 dbgi = get_irn_dbg_info(node);
2148 block = be_transform_node(src_block);
2149 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2150 set_address(new_node, addr);
2151 set_ia32_op_type(new_node, ia32_AddrModeD);
2152 set_ia32_ls_mode(new_node, mode);
2153 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2158 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2159 ir_mode *mode = get_irn_mode(node);
2160 ir_node *psi_true = get_Psi_val(node, 0);
2161 ir_node *psi_default = get_Psi_default(node);
2172 ia32_address_t addr;
2174 if(get_mode_size_bits(mode) != 8)
2177 if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2179 } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2185 build_address_ptr(&addr, ptr, mem);
2187 irg = current_ir_graph;
2188 dbgi = get_irn_dbg_info(node);
2189 block = get_nodes_block(node);
2190 new_block = be_transform_node(block);
2191 cond = get_Psi_cond(node, 0);
2192 flags = get_flags_node(cond, &pnc);
2193 new_mem = be_transform_node(mem);
2194 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2195 addr.index, addr.mem, flags, pnc, negated);
2196 set_address(new_node, &addr);
2197 set_ia32_op_type(new_node, ia32_AddrModeD);
2198 set_ia32_ls_mode(new_node, mode);
2199 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2204 static ir_node *try_create_dest_am(ir_node *node) {
2205 ir_node *val = get_Store_value(node);
2206 ir_node *mem = get_Store_mem(node);
2207 ir_node *ptr = get_Store_ptr(node);
2208 ir_mode *mode = get_irn_mode(val);
2209 unsigned bits = get_mode_size_bits(mode);
2214 /* handle only GP modes for now... */
2215 if(!mode_needs_gp_reg(mode))
2219 /* store must be the only user of the val node */
2220 if(get_irn_n_edges(val) > 1)
2222 /* skip pointless convs */
2224 ir_node *conv_op = get_Conv_op(val);
2225 ir_mode *pred_mode = get_irn_mode(conv_op);
2226 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2234 /* value must be in the same block */
2235 if(get_nodes_block(node) != get_nodes_block(val))
2238 switch (get_irn_opcode(val)) {
2240 op1 = get_Add_left(val);
2241 op2 = get_Add_right(val);
2242 if(is_Const_1(op2)) {
2243 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2244 new_rd_ia32_IncMem);
2246 } else if(is_Const_Minus_1(op2)) {
2247 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2248 new_rd_ia32_DecMem);
2251 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2252 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2253 match_dest_am | match_commutative |
2257 op1 = get_Sub_left(val);
2258 op2 = get_Sub_right(val);
2260 ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2263 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2264 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2265 match_dest_am | match_immediate |
2269 op1 = get_And_left(val);
2270 op2 = get_And_right(val);
2271 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2272 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2273 match_dest_am | match_commutative |
2277 op1 = get_Or_left(val);
2278 op2 = get_Or_right(val);
2279 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2280 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2281 match_dest_am | match_commutative |
2285 op1 = get_Eor_left(val);
2286 op2 = get_Eor_right(val);
2287 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2288 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2289 match_dest_am | match_commutative |
2293 op1 = get_Shl_left(val);
2294 op2 = get_Shl_right(val);
2295 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2296 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2297 match_dest_am | match_immediate);
2300 op1 = get_Shr_left(val);
2301 op2 = get_Shr_right(val);
2302 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2303 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2304 match_dest_am | match_immediate);
2307 op1 = get_Shrs_left(val);
2308 op2 = get_Shrs_right(val);
2309 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2310 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2311 match_dest_am | match_immediate);
2314 op1 = get_Rotl_left(val);
2315 op2 = get_Rotl_right(val);
2316 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2317 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2318 match_dest_am | match_immediate);
2320 /* TODO: match ROR patterns... */
2322 new_node = try_create_SetMem(val, ptr, mem);
2325 op1 = get_Minus_op(val);
2326 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2329 /* should be lowered already */
2330 assert(mode != mode_b);
2331 op1 = get_Not_op(val);
2332 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2338 if(new_node != NULL) {
2339 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2340 get_irn_pinned(node) == op_pin_state_pinned) {
2341 set_irn_pinned(new_node, op_pin_state_pinned);
2348 static int is_float_to_int32_conv(const ir_node *node)
2350 ir_mode *mode = get_irn_mode(node);
2354 if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode))
2359 conv_op = get_Conv_op(node);
2360 conv_mode = get_irn_mode(conv_op);
2362 if(!mode_is_float(conv_mode))
2369 * Transform a Store(floatConst).
2371 * @return the created ia32 Store node
2373 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2374 ir_mode *mode = get_irn_mode(cns);
2375 int size = get_mode_size_bits(mode);
2376 tarval *tv = get_Const_tarval(cns);
2377 ir_node *block = get_nodes_block(node);
2378 ir_node *new_block = be_transform_node(block);
2379 ir_node *ptr = get_Store_ptr(node);
2380 ir_node *mem = get_Store_mem(node);
2381 ir_graph *irg = current_ir_graph;
2382 dbg_info *dbgi = get_irn_dbg_info(node);
2383 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2386 ia32_address_t addr;
2388 unsigned val = get_tarval_sub_bits(tv, 0) |
2389 (get_tarval_sub_bits(tv, 1) << 8) |
2390 (get_tarval_sub_bits(tv, 2) << 16) |
2391 (get_tarval_sub_bits(tv, 3) << 24);
2392 ir_node *imm = create_Immediate(NULL, 0, val);
2394 /* construct store address */
2395 memset(&addr, 0, sizeof(addr));
2396 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2398 if (addr.base == NULL) {
2401 addr.base = be_transform_node(addr.base);
2404 if (addr.index == NULL) {
2407 addr.index = be_transform_node(addr.index);
2409 addr.mem = be_transform_node(mem);
2411 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2412 addr.index, addr.mem, imm);
2414 set_irn_pinned(new_node, get_irn_pinned(node));
2415 set_ia32_op_type(new_node, ia32_AddrModeD);
2416 set_ia32_ls_mode(new_node, mode_Iu);
2418 set_address(new_node, &addr);
2420 /** add more stores if needed */
2422 unsigned val = get_tarval_sub_bits(tv, ofs) |
2423 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2424 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2425 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2426 ir_node *imm = create_Immediate(NULL, 0, val);
2429 addr.mem = new_node;
2431 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2432 addr.index, addr.mem, imm);
2434 set_irn_pinned(new_node, get_irn_pinned(node));
2435 set_ia32_op_type(new_node, ia32_AddrModeD);
2436 set_ia32_ls_mode(new_node, mode_Iu);
2438 set_address(new_node, &addr);
2443 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2448 * Generate a vfist or vfisttp instruction.
2450 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2451 ir_node *mem, ir_node *val, ir_node **fist)
2455 if (ia32_cg_config.use_fisttp) {
2456 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2457 if other users exists */
2458 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2459 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2460 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2461 be_new_Keep(reg_class, irg, block, 1, &value);
2463 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2466 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2469 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2475 * Transforms a normal Store.
2477 * @return the created ia32 Store node
2479 static ir_node *gen_normal_Store(ir_node *node)
2481 ir_node *val = get_Store_value(node);
2482 ir_mode *mode = get_irn_mode(val);
2483 ir_node *block = get_nodes_block(node);
2484 ir_node *new_block = be_transform_node(block);
2485 ir_node *ptr = get_Store_ptr(node);
2486 ir_node *mem = get_Store_mem(node);
2487 ir_graph *irg = current_ir_graph;
2488 dbg_info *dbgi = get_irn_dbg_info(node);
2489 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2490 ir_node *new_val, *new_node, *store;
2491 ia32_address_t addr;
2493 /* check for destination address mode */
2494 new_node = try_create_dest_am(node);
2495 if (new_node != NULL)
2498 /* construct store address */
2499 memset(&addr, 0, sizeof(addr));
2500 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2502 if (addr.base == NULL) {
2505 addr.base = be_transform_node(addr.base);
2508 if (addr.index == NULL) {
2511 addr.index = be_transform_node(addr.index);
2513 addr.mem = be_transform_node(mem);
2515 if (mode_is_float(mode)) {
2516 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2518 while (is_Conv(val) && mode == get_irn_mode(val)) {
2519 ir_node *op = get_Conv_op(val);
2520 if (!mode_is_float(get_irn_mode(op)))
2524 new_val = be_transform_node(val);
2525 if (ia32_cg_config.use_sse2) {
2526 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2527 addr.index, addr.mem, new_val);
2529 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2530 addr.index, addr.mem, new_val, mode);
2533 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2534 val = get_Conv_op(val);
2536 /* We can skip ALL Convs (and strict-Convs) before stores. */
2537 while (is_Conv(val)) {
2538 val = get_Conv_op(val);
2540 new_val = be_transform_node(val);
2541 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2543 new_val = create_immediate_or_transform(val, 0);
2544 assert(mode != mode_b);
2546 if (get_mode_size_bits(mode) == 8) {
2547 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2548 addr.index, addr.mem, new_val);
2550 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2551 addr.index, addr.mem, new_val);
2556 set_irn_pinned(store, get_irn_pinned(node));
2557 set_ia32_op_type(store, ia32_AddrModeD);
2558 set_ia32_ls_mode(store, mode);
2560 set_address(store, &addr);
2561 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2567 * Transforms a Store.
2569 * @return the created ia32 Store node
2571 static ir_node *gen_Store(ir_node *node)
2573 ir_node *val = get_Store_value(node);
2574 ir_mode *mode = get_irn_mode(val);
2576 if (mode_is_float(mode) && is_Const(val)) {
2579 /* we are storing a floating point constant */
2580 if (ia32_cg_config.use_sse2) {
2581 transform = !is_simple_sse_Const(val);
2583 transform = !is_simple_x87_Const(val);
2586 return gen_float_const_Store(node, val);
2588 return gen_normal_Store(node);
2592 * Transforms a Switch.
2594 * @return the created ia32 SwitchJmp node
2596 static ir_node *create_Switch(ir_node *node)
2598 ir_graph *irg = current_ir_graph;
2599 dbg_info *dbgi = get_irn_dbg_info(node);
2600 ir_node *block = be_transform_node(get_nodes_block(node));
2601 ir_node *sel = get_Cond_selector(node);
2602 ir_node *new_sel = be_transform_node(sel);
2603 int switch_min = INT_MAX;
2604 int switch_max = INT_MIN;
2605 long default_pn = get_Cond_defaultProj(node);
2607 const ir_edge_t *edge;
2609 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2611 /* determine the smallest switch case value */
2612 foreach_out_edge(node, edge) {
2613 ir_node *proj = get_edge_src_irn(edge);
2614 long pn = get_Proj_proj(proj);
2615 if(pn == default_pn)
2624 if((unsigned) (switch_max - switch_min) > 256000) {
2625 panic("Size of switch %+F bigger than 256000", node);
2628 if (switch_min != 0) {
2629 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2631 /* if smallest switch case is not 0 we need an additional sub */
2632 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2633 add_ia32_am_offs_int(new_sel, -switch_min);
2634 set_ia32_op_type(new_sel, ia32_AddrModeS);
2636 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2639 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2640 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2646 * Transform a Cond node.
2648 static ir_node *gen_Cond(ir_node *node) {
2649 ir_node *block = get_nodes_block(node);
2650 ir_node *new_block = be_transform_node(block);
2651 ir_graph *irg = current_ir_graph;
2652 dbg_info *dbgi = get_irn_dbg_info(node);
2653 ir_node *sel = get_Cond_selector(node);
2654 ir_mode *sel_mode = get_irn_mode(sel);
2655 ir_node *flags = NULL;
2659 if (sel_mode != mode_b) {
2660 return create_Switch(node);
2663 /* we get flags from a Cmp */
2664 flags = get_flags_node(sel, &pnc);
2666 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2667 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2673 * Transforms a CopyB node.
2675 * @return The transformed node.
2677 static ir_node *gen_CopyB(ir_node *node) {
2678 ir_node *block = be_transform_node(get_nodes_block(node));
2679 ir_node *src = get_CopyB_src(node);
2680 ir_node *new_src = be_transform_node(src);
2681 ir_node *dst = get_CopyB_dst(node);
2682 ir_node *new_dst = be_transform_node(dst);
2683 ir_node *mem = get_CopyB_mem(node);
2684 ir_node *new_mem = be_transform_node(mem);
2685 ir_node *res = NULL;
2686 ir_graph *irg = current_ir_graph;
2687 dbg_info *dbgi = get_irn_dbg_info(node);
2688 int size = get_type_size_bytes(get_CopyB_type(node));
2691 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2692 /* then we need the size explicitly in ECX. */
2693 if (size >= 32 * 4) {
2694 rem = size & 0x3; /* size % 4 */
2697 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2698 add_irn_dep(res, get_irg_frame(irg));
2700 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2703 ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2706 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2709 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2714 static ir_node *gen_be_Copy(ir_node *node)
2716 ir_node *new_node = be_duplicate_node(node);
2717 ir_mode *mode = get_irn_mode(new_node);
2719 if (mode_needs_gp_reg(mode)) {
2720 set_irn_mode(new_node, mode_Iu);
2726 static ir_node *create_Fucom(ir_node *node)
2728 ir_graph *irg = current_ir_graph;
2729 dbg_info *dbgi = get_irn_dbg_info(node);
2730 ir_node *block = get_nodes_block(node);
2731 ir_node *new_block = be_transform_node(block);
2732 ir_node *left = get_Cmp_left(node);
2733 ir_node *new_left = be_transform_node(left);
2734 ir_node *right = get_Cmp_right(node);
2738 if(ia32_cg_config.use_fucomi) {
2739 new_right = be_transform_node(right);
2740 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2742 set_ia32_commutative(new_node);
2743 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2745 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2746 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2749 new_right = be_transform_node(right);
2750 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2754 set_ia32_commutative(new_node);
2756 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2758 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2759 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2765 static ir_node *create_Ucomi(ir_node *node)
2767 ir_graph *irg = current_ir_graph;
2768 dbg_info *dbgi = get_irn_dbg_info(node);
2769 ir_node *src_block = get_nodes_block(node);
2770 ir_node *new_block = be_transform_node(src_block);
2771 ir_node *left = get_Cmp_left(node);
2772 ir_node *right = get_Cmp_right(node);
2774 ia32_address_mode_t am;
2775 ia32_address_t *addr = &am.addr;
2777 match_arguments(&am, src_block, left, right, NULL,
2778 match_commutative | match_am);
2780 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2781 addr->mem, am.new_op1, am.new_op2,
2783 set_am_attributes(new_node, &am);
2785 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2787 new_node = fix_mem_proj(new_node, &am);
2793 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2794 * to fold an and into a test node
2796 static int can_fold_test_and(ir_node *node)
2798 const ir_edge_t *edge;
2800 /** we can only have eq and lg projs */
2801 foreach_out_edge(node, edge) {
2802 ir_node *proj = get_edge_src_irn(edge);
2803 pn_Cmp pnc = get_Proj_proj(proj);
2804 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2812 * Generate code for a Cmp.
2814 static ir_node *gen_Cmp(ir_node *node)
2816 ir_graph *irg = current_ir_graph;
2817 dbg_info *dbgi = get_irn_dbg_info(node);
2818 ir_node *block = get_nodes_block(node);
2819 ir_node *new_block = be_transform_node(block);
2820 ir_node *left = get_Cmp_left(node);
2821 ir_node *right = get_Cmp_right(node);
2822 ir_mode *cmp_mode = get_irn_mode(left);
2824 ia32_address_mode_t am;
2825 ia32_address_t *addr = &am.addr;
2828 if(mode_is_float(cmp_mode)) {
2829 if (ia32_cg_config.use_sse2) {
2830 return create_Ucomi(node);
2832 return create_Fucom(node);
2836 assert(mode_needs_gp_reg(cmp_mode));
2838 /* we prefer the Test instruction where possible except cases where
2839 * we can use SourceAM */
2840 cmp_unsigned = !mode_is_signed(cmp_mode);
2841 if (is_Const_0(right)) {
2843 get_irn_n_edges(left) == 1 &&
2844 can_fold_test_and(node)) {
2845 /* Test(and_left, and_right) */
2846 ir_node *and_left = get_And_left(left);
2847 ir_node *and_right = get_And_right(left);
2848 ir_mode *mode = get_irn_mode(and_left);
2850 match_arguments(&am, block, and_left, and_right, NULL,
2852 match_am | match_8bit_am | match_16bit_am |
2853 match_am_and_immediates | match_immediate |
2854 match_8bit | match_16bit);
2855 if (get_mode_size_bits(mode) == 8) {
2856 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2857 addr->index, addr->mem, am.new_op1,
2858 am.new_op2, am.ins_permuted,
2861 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2862 addr->index, addr->mem, am.new_op1,
2863 am.new_op2, am.ins_permuted, cmp_unsigned);
2866 match_arguments(&am, block, NULL, left, NULL,
2867 match_am | match_8bit_am | match_16bit_am |
2868 match_8bit | match_16bit);
2869 if (am.op_type == ia32_AddrModeS) {
2871 ir_node *imm_zero = try_create_Immediate(right, 0);
2872 if (get_mode_size_bits(cmp_mode) == 8) {
2873 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2874 addr->index, addr->mem, am.new_op2,
2875 imm_zero, am.ins_permuted,
2878 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2879 addr->index, addr->mem, am.new_op2,
2880 imm_zero, am.ins_permuted, cmp_unsigned);
2883 /* Test(left, left) */
2884 if (get_mode_size_bits(cmp_mode) == 8) {
2885 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2886 addr->index, addr->mem, am.new_op2,
2887 am.new_op2, am.ins_permuted,
2890 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2891 addr->index, addr->mem, am.new_op2,
2892 am.new_op2, am.ins_permuted,
2898 /* Cmp(left, right) */
2899 match_arguments(&am, block, left, right, NULL,
2900 match_commutative | match_am | match_8bit_am |
2901 match_16bit_am | match_am_and_immediates |
2902 match_immediate | match_8bit | match_16bit);
2903 if (get_mode_size_bits(cmp_mode) == 8) {
2904 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2905 addr->index, addr->mem, am.new_op1,
2906 am.new_op2, am.ins_permuted,
2909 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2910 addr->index, addr->mem, am.new_op1,
2911 am.new_op2, am.ins_permuted, cmp_unsigned);
2914 set_am_attributes(new_node, &am);
2915 assert(cmp_mode != NULL);
2916 set_ia32_ls_mode(new_node, cmp_mode);
2918 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2920 new_node = fix_mem_proj(new_node, &am);
2925 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2928 ir_graph *irg = current_ir_graph;
2929 dbg_info *dbgi = get_irn_dbg_info(node);
2930 ir_node *block = get_nodes_block(node);
2931 ir_node *new_block = be_transform_node(block);
2932 ir_node *val_true = get_Psi_val(node, 0);
2933 ir_node *val_false = get_Psi_default(node);
2935 match_flags_t match_flags;
2936 ia32_address_mode_t am;
2937 ia32_address_t *addr;
2939 assert(ia32_cg_config.use_cmov);
2940 assert(mode_needs_gp_reg(get_irn_mode(val_true)));
2944 match_flags = match_commutative | match_am | match_16bit_am |
2947 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2949 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2950 addr->mem, am.new_op1, am.new_op2, new_flags,
2951 am.ins_permuted, pnc);
2952 set_am_attributes(new_node, &am);
2954 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2956 new_node = fix_mem_proj(new_node, &am);
2962 * Creates a ia32 Setcc instruction.
2964 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2965 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2968 ir_graph *irg = current_ir_graph;
2969 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2970 ir_node *nomem = new_NoMem();
2971 ir_mode *mode = get_irn_mode(orig_node);
2974 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2975 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2977 /* we might need to conv the result up */
2978 if (get_mode_size_bits(mode) > 8) {
2979 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2980 nomem, new_node, mode_Bu);
2981 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2988 * Create instruction for an unsigned Difference or Zero.
2990 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2991 ir_graph *irg = current_ir_graph;
2992 ir_mode *mode = get_irn_mode(psi);
2993 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2996 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2997 match_mode_neutral | match_am | match_immediate | match_two_users);
2999 block = get_nodes_block(new_node);
3001 if (is_Proj(new_node)) {
3002 sub = get_Proj_pred(new_node);
3003 assert(is_ia32_Sub(sub));
3006 set_irn_mode(sub, mode_T);
3007 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
3009 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3011 dbgi = get_irn_dbg_info(psi);
3012 noreg = ia32_new_NoReg_gp(env_cg);
3013 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
3014 nomem = new_NoMem();
3015 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
3017 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
3018 set_ia32_commutative(new_node);
3023 * Transforms a Psi node into CMov.
3025 * @return The transformed node.
3027 static ir_node *gen_Psi(ir_node *node)
3029 dbg_info *dbgi = get_irn_dbg_info(node);
3030 ir_node *block = get_nodes_block(node);
3031 ir_node *new_block = be_transform_node(block);
3032 ir_node *psi_true = get_Psi_val(node, 0);
3033 ir_node *psi_default = get_Psi_default(node);
3034 ir_node *cond = get_Psi_cond(node, 0);
3035 ir_mode *mode = get_irn_mode(node);
3038 assert(get_Psi_n_conds(node) == 1);
3039 assert(get_irn_mode(cond) == mode_b);
3041 /* Note: a Psi node uses a Load two times IFF it's used in the compare AND in the result */
3042 if (mode_is_float(mode)) {
3043 ir_node *cmp = get_Proj_pred(cond);
3044 ir_node *cmp_left = get_Cmp_left(cmp);
3045 ir_node *cmp_right = get_Cmp_right(cmp);
3046 pn_Cmp pnc = get_Proj_proj(cond);
3048 if (ia32_cg_config.use_sse2) {
3049 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3050 if (cmp_left == psi_true && cmp_right == psi_default) {
3051 /* psi(a <= b, a, b) => MIN */
3052 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3053 match_commutative | match_am | match_two_users);
3054 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3055 /* psi(a <= b, b, a) => MAX */
3056 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3057 match_commutative | match_am | match_two_users);
3059 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3060 if (cmp_left == psi_true && cmp_right == psi_default) {
3061 /* psi(a >= b, a, b) => MAX */
3062 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3063 match_commutative | match_am | match_two_users);
3064 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3065 /* psi(a >= b, b, a) => MIN */
3066 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3067 match_commutative | match_am | match_two_users);
3071 panic("cannot transform floating point Psi");
3077 assert(mode_needs_gp_reg(mode));
3079 if (is_Proj(cond)) {
3080 ir_node *cmp = get_Proj_pred(cond);
3082 ir_node *cmp_left = get_Cmp_left(cmp);
3083 ir_node *cmp_right = get_Cmp_right(cmp);
3084 pn_Cmp pnc = get_Proj_proj(cond);
3086 /* check for unsigned Doz first */
3087 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3088 is_Const_0(psi_default) && is_Sub(psi_true) &&
3089 get_Sub_left(psi_true) == cmp_left && get_Sub_right(psi_true) == cmp_right) {
3090 /* Psi(a >=u b, a - b, 0) unsigned Doz */
3091 return create_Doz(node, cmp_left, cmp_right);
3092 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3093 is_Const_0(psi_true) && is_Sub(psi_default) &&
3094 get_Sub_left(psi_default) == cmp_left && get_Sub_right(psi_default) == cmp_right) {
3095 /* Psi(a <=u b, 0, a - b) unsigned Doz */
3096 return create_Doz(node, cmp_left, cmp_right);
3101 flags = get_flags_node(cond, &pnc);
3103 if (is_Const(psi_true) && is_Const(psi_default)) {
3104 /* both are const, good */
3105 if (is_Const_1(psi_true) && is_Const_0(psi_default)) {
3106 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3107 } else if (is_Const_0(psi_true) && is_Const_1(psi_default)) {
3108 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3110 /* Not that simple. */
3115 new_node = create_CMov(node, cond, flags, pnc);
3123 * Create a conversion from x87 state register to general purpose.
3125 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3126 ir_node *block = be_transform_node(get_nodes_block(node));
3127 ir_node *op = get_Conv_op(node);
3128 ir_node *new_op = be_transform_node(op);
3129 ia32_code_gen_t *cg = env_cg;
3130 ir_graph *irg = current_ir_graph;
3131 dbg_info *dbgi = get_irn_dbg_info(node);
3132 ir_node *noreg = ia32_new_NoReg_gp(cg);
3133 ir_mode *mode = get_irn_mode(node);
3134 ir_node *fist, *load, *mem;
3136 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3137 set_irn_pinned(fist, op_pin_state_floats);
3138 set_ia32_use_frame(fist);
3139 set_ia32_op_type(fist, ia32_AddrModeD);
3141 assert(get_mode_size_bits(mode) <= 32);
3142 /* exception we can only store signed 32 bit integers, so for unsigned
3143 we store a 64bit (signed) integer and load the lower bits */
3144 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3145 set_ia32_ls_mode(fist, mode_Ls);
3147 set_ia32_ls_mode(fist, mode_Is);
3149 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3152 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3154 set_irn_pinned(load, op_pin_state_floats);
3155 set_ia32_use_frame(load);
3156 set_ia32_op_type(load, ia32_AddrModeS);
3157 set_ia32_ls_mode(load, mode_Is);
3158 if(get_ia32_ls_mode(fist) == mode_Ls) {
3159 ia32_attr_t *attr = get_ia32_attr(load);
3160 attr->data.need_64bit_stackent = 1;
3162 ia32_attr_t *attr = get_ia32_attr(load);
3163 attr->data.need_32bit_stackent = 1;
3165 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3167 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3171 * Creates a x87 strict Conv by placing a Sore and a Load
3173 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3175 ir_node *block = get_nodes_block(node);
3176 ir_graph *irg = current_ir_graph;
3177 dbg_info *dbgi = get_irn_dbg_info(node);
3178 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3179 ir_node *nomem = new_NoMem();
3180 ir_node *frame = get_irg_frame(irg);
3181 ir_node *store, *load;
3184 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3186 set_ia32_use_frame(store);
3187 set_ia32_op_type(store, ia32_AddrModeD);
3188 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3190 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3192 set_ia32_use_frame(load);
3193 set_ia32_op_type(load, ia32_AddrModeS);
3194 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3196 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3201 * Create a conversion from general purpose to x87 register
3203 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3204 ir_node *src_block = get_nodes_block(node);
3205 ir_node *block = be_transform_node(src_block);
3206 ir_graph *irg = current_ir_graph;
3207 dbg_info *dbgi = get_irn_dbg_info(node);
3208 ir_node *op = get_Conv_op(node);
3209 ir_node *new_op = NULL;
3213 ir_mode *store_mode;
3219 /* fild can use source AM if the operand is a signed 32bit integer */
3220 if (src_mode == mode_Is) {
3221 ia32_address_mode_t am;
3223 match_arguments(&am, src_block, NULL, op, NULL,
3224 match_am | match_try_am);
3225 if (am.op_type == ia32_AddrModeS) {
3226 ia32_address_t *addr = &am.addr;
3228 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3229 addr->index, addr->mem);
3230 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3233 set_am_attributes(fild, &am);
3234 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3236 fix_mem_proj(fild, &am);
3241 if(new_op == NULL) {
3242 new_op = be_transform_node(op);
3245 noreg = ia32_new_NoReg_gp(env_cg);
3246 nomem = new_NoMem();
3247 mode = get_irn_mode(op);
3249 /* first convert to 32 bit signed if necessary */
3250 src_bits = get_mode_size_bits(src_mode);
3251 if (src_bits == 8) {
3252 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3254 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3256 } else if (src_bits < 32) {
3257 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3259 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3263 assert(get_mode_size_bits(mode) == 32);
3266 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3269 set_ia32_use_frame(store);
3270 set_ia32_op_type(store, ia32_AddrModeD);
3271 set_ia32_ls_mode(store, mode_Iu);
3273 /* exception for 32bit unsigned, do a 64bit spill+load */
3274 if(!mode_is_signed(mode)) {
3277 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3279 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3280 get_irg_frame(irg), noreg, nomem,
3283 set_ia32_use_frame(zero_store);
3284 set_ia32_op_type(zero_store, ia32_AddrModeD);
3285 add_ia32_am_offs_int(zero_store, 4);
3286 set_ia32_ls_mode(zero_store, mode_Iu);
3291 store = new_rd_Sync(dbgi, irg, block, 2, in);
3292 store_mode = mode_Ls;
3294 store_mode = mode_Is;
3298 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3300 set_ia32_use_frame(fild);
3301 set_ia32_op_type(fild, ia32_AddrModeS);
3302 set_ia32_ls_mode(fild, store_mode);
3304 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3310 * Create a conversion from one integer mode into another one
3312 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3313 dbg_info *dbgi, ir_node *block, ir_node *op,
3316 ir_graph *irg = current_ir_graph;
3317 int src_bits = get_mode_size_bits(src_mode);
3318 int tgt_bits = get_mode_size_bits(tgt_mode);
3319 ir_node *new_block = be_transform_node(block);
3321 ir_mode *smaller_mode;
3323 ia32_address_mode_t am;
3324 ia32_address_t *addr = &am.addr;
3327 if (src_bits < tgt_bits) {
3328 smaller_mode = src_mode;
3329 smaller_bits = src_bits;
3331 smaller_mode = tgt_mode;
3332 smaller_bits = tgt_bits;
3335 #ifdef DEBUG_libfirm
3337 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3342 match_arguments(&am, block, NULL, op, NULL,
3343 match_8bit | match_16bit |
3344 match_am | match_8bit_am | match_16bit_am);
3345 if (smaller_bits == 8) {
3346 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3347 addr->index, addr->mem, am.new_op2,
3350 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3351 addr->index, addr->mem, am.new_op2,
3354 set_am_attributes(new_node, &am);
3355 /* match_arguments assume that out-mode = in-mode, this isn't true here
3357 set_ia32_ls_mode(new_node, smaller_mode);
3358 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3359 new_node = fix_mem_proj(new_node, &am);
3364 * Transforms a Conv node.
3366 * @return The created ia32 Conv node
3368 static ir_node *gen_Conv(ir_node *node) {
3369 ir_node *block = get_nodes_block(node);
3370 ir_node *new_block = be_transform_node(block);
3371 ir_node *op = get_Conv_op(node);
3372 ir_node *new_op = NULL;
3373 ir_graph *irg = current_ir_graph;
3374 dbg_info *dbgi = get_irn_dbg_info(node);
3375 ir_mode *src_mode = get_irn_mode(op);
3376 ir_mode *tgt_mode = get_irn_mode(node);
3377 int src_bits = get_mode_size_bits(src_mode);
3378 int tgt_bits = get_mode_size_bits(tgt_mode);
3379 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3380 ir_node *nomem = new_rd_NoMem(irg);
3381 ir_node *res = NULL;
3383 if (src_mode == mode_b) {
3384 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3385 /* nothing to do, we already model bools as 0/1 ints */
3386 return be_transform_node(op);
3389 if (src_mode == tgt_mode) {
3390 if (get_Conv_strict(node)) {
3391 if (ia32_cg_config.use_sse2) {
3392 /* when we are in SSE mode, we can kill all strict no-op conversion */
3393 return be_transform_node(op);
3396 /* this should be optimized already, but who knows... */
3397 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3398 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3399 return be_transform_node(op);
3403 if (mode_is_float(src_mode)) {
3404 new_op = be_transform_node(op);
3405 /* we convert from float ... */
3406 if (mode_is_float(tgt_mode)) {
3407 if(src_mode == mode_E && tgt_mode == mode_D
3408 && !get_Conv_strict(node)) {
3409 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3414 if (ia32_cg_config.use_sse2) {
3415 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3416 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3418 set_ia32_ls_mode(res, tgt_mode);
3420 if(get_Conv_strict(node)) {
3421 res = gen_x87_strict_conv(tgt_mode, new_op);
3422 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3425 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3430 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3431 if (ia32_cg_config.use_sse2) {
3432 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3434 set_ia32_ls_mode(res, src_mode);
3436 return gen_x87_fp_to_gp(node);
3440 /* we convert from int ... */
3441 if (mode_is_float(tgt_mode)) {
3443 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3444 if (ia32_cg_config.use_sse2) {
3445 new_op = be_transform_node(op);
3446 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3448 set_ia32_ls_mode(res, tgt_mode);
3450 res = gen_x87_gp_to_fp(node, src_mode);
3451 if(get_Conv_strict(node)) {
3452 res = gen_x87_strict_conv(tgt_mode, res);
3453 SET_IA32_ORIG_NODE(get_Proj_pred(res),
3454 ia32_get_old_node_name(env_cg, node));
3458 } else if(tgt_mode == mode_b) {
3459 /* mode_b lowering already took care that we only have 0/1 values */
3460 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3461 src_mode, tgt_mode));
3462 return be_transform_node(op);
3465 if (src_bits == tgt_bits) {
3466 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3467 src_mode, tgt_mode));
3468 return be_transform_node(op);
3471 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3479 static int check_immediate_constraint(long val, char immediate_constraint_type)
3481 switch (immediate_constraint_type) {
3485 return val >= 0 && val <= 32;
3487 return val >= 0 && val <= 63;
3489 return val >= -128 && val <= 127;
3491 return val == 0xff || val == 0xffff;
3493 return val >= 0 && val <= 3;
3495 return val >= 0 && val <= 255;
3497 return val >= 0 && val <= 127;
3501 panic("Invalid immediate constraint found");
3505 static ir_node *try_create_Immediate(ir_node *node,
3506 char immediate_constraint_type)
3509 tarval *offset = NULL;
3510 int offset_sign = 0;
3512 ir_entity *symconst_ent = NULL;
3513 int symconst_sign = 0;
3515 ir_node *cnst = NULL;
3516 ir_node *symconst = NULL;
3519 mode = get_irn_mode(node);
3520 if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3524 if(is_Minus(node)) {
3526 node = get_Minus_op(node);
3529 if(is_Const(node)) {
3532 offset_sign = minus;
3533 } else if(is_SymConst(node)) {
3536 symconst_sign = minus;
3537 } else if(is_Add(node)) {
3538 ir_node *left = get_Add_left(node);
3539 ir_node *right = get_Add_right(node);
3540 if(is_Const(left) && is_SymConst(right)) {
3543 symconst_sign = minus;
3544 offset_sign = minus;
3545 } else if(is_SymConst(left) && is_Const(right)) {
3548 symconst_sign = minus;
3549 offset_sign = minus;
3551 } else if(is_Sub(node)) {
3552 ir_node *left = get_Sub_left(node);
3553 ir_node *right = get_Sub_right(node);
3554 if(is_Const(left) && is_SymConst(right)) {
3557 symconst_sign = !minus;
3558 offset_sign = minus;
3559 } else if(is_SymConst(left) && is_Const(right)) {
3562 symconst_sign = minus;
3563 offset_sign = !minus;
3570 offset = get_Const_tarval(cnst);
3571 if(tarval_is_long(offset)) {
3572 val = get_tarval_long(offset);
3574 ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3579 if(!check_immediate_constraint(val, immediate_constraint_type))
3582 if(symconst != NULL) {
3583 if(immediate_constraint_type != 0) {
3584 /* we need full 32bits for symconsts */
3588 /* unfortunately the assembler/linker doesn't support -symconst */
3592 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3594 symconst_ent = get_SymConst_entity(symconst);
3596 if(cnst == NULL && symconst == NULL)
3599 if(offset_sign && offset != NULL) {
3600 offset = tarval_neg(offset);
3603 new_node = create_Immediate(symconst_ent, symconst_sign, val);
3608 static ir_node *create_immediate_or_transform(ir_node *node,
3609 char immediate_constraint_type)
3611 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3612 if (new_node == NULL) {
3613 new_node = be_transform_node(node);
3618 static const arch_register_req_t no_register_req = {
3619 arch_register_req_type_none,
3620 NULL, /* regclass */
3621 NULL, /* limit bitset */
3623 0 /* different pos */
3627 * An assembler constraint.
3629 typedef struct constraint_t constraint_t;
3630 struct constraint_t {
3633 const arch_register_req_t **out_reqs;
3635 const arch_register_req_t *req;
3636 unsigned immediate_possible;
3637 char immediate_type;
3640 static void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
3642 int immediate_possible = 0;
3643 char immediate_type = 0;
3644 unsigned limited = 0;
3645 const arch_register_class_t *cls = NULL;
3646 ir_graph *irg = current_ir_graph;
3647 struct obstack *obst = get_irg_obstack(irg);
3648 arch_register_req_t *req;
3649 unsigned *limited_ptr = NULL;
3653 /* TODO: replace all the asserts with nice error messages */
3656 /* a memory constraint: no need to do anything in backend about it
3657 * (the dependencies are already respected by the memory edge of
3659 constraint->req = &no_register_req;
3671 assert(cls == NULL ||
3672 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3673 cls = &ia32_reg_classes[CLASS_ia32_gp];
3674 limited |= 1 << REG_EAX;
3677 assert(cls == NULL ||
3678 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3679 cls = &ia32_reg_classes[CLASS_ia32_gp];
3680 limited |= 1 << REG_EBX;
3683 assert(cls == NULL ||
3684 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3685 cls = &ia32_reg_classes[CLASS_ia32_gp];
3686 limited |= 1 << REG_ECX;
3689 assert(cls == NULL ||
3690 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3691 cls = &ia32_reg_classes[CLASS_ia32_gp];
3692 limited |= 1 << REG_EDX;
3695 assert(cls == NULL ||
3696 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3697 cls = &ia32_reg_classes[CLASS_ia32_gp];
3698 limited |= 1 << REG_EDI;
3701 assert(cls == NULL ||
3702 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3703 cls = &ia32_reg_classes[CLASS_ia32_gp];
3704 limited |= 1 << REG_ESI;
3707 case 'q': /* q means lower part of the regs only, this makes no
3708 * difference to Q for us (we only assigne whole registers) */
3709 assert(cls == NULL ||
3710 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3711 cls = &ia32_reg_classes[CLASS_ia32_gp];
3712 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3716 assert(cls == NULL ||
3717 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3718 cls = &ia32_reg_classes[CLASS_ia32_gp];
3719 limited |= 1 << REG_EAX | 1 << REG_EDX;
3722 assert(cls == NULL ||
3723 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3724 cls = &ia32_reg_classes[CLASS_ia32_gp];
3725 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3726 1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3733 assert(cls == NULL);
3734 cls = &ia32_reg_classes[CLASS_ia32_gp];
3740 /* TODO: mark values so the x87 simulator knows about t and u */
3741 assert(cls == NULL);
3742 cls = &ia32_reg_classes[CLASS_ia32_vfp];
3747 assert(cls == NULL);
3748 /* TODO: check that sse2 is supported */
3749 cls = &ia32_reg_classes[CLASS_ia32_xmm];
3759 assert(!immediate_possible);
3760 immediate_possible = 1;
3761 immediate_type = *c;
3765 assert(!immediate_possible);
3766 immediate_possible = 1;
3770 assert(!immediate_possible && cls == NULL);
3771 immediate_possible = 1;
3772 cls = &ia32_reg_classes[CLASS_ia32_gp];
3785 assert(constraint->is_in && "can only specify same constraint "
3788 sscanf(c, "%d%n", &same_as, &p);
3796 /* memory constraint no need to do anything in backend about it
3797 * (the dependencies are already respected by the memory edge of
3799 constraint->req = &no_register_req;
3802 case 'E': /* no float consts yet */
3803 case 'F': /* no float consts yet */
3804 case 's': /* makes no sense on x86 */
3805 case 'X': /* we can't support that in firm */
3808 case '<': /* no autodecrement on x86 */
3809 case '>': /* no autoincrement on x86 */
3810 case 'C': /* sse constant not supported yet */
3811 case 'G': /* 80387 constant not supported yet */
3812 case 'y': /* we don't support mmx registers yet */
3813 case 'Z': /* not available in 32 bit mode */
3814 case 'e': /* not available in 32 bit mode */
3815 panic("unsupported asm constraint '%c' found in (%+F)",
3816 *c, current_ir_graph);
3819 panic("unknown asm constraint '%c' found in (%+F)", *c,
3827 const arch_register_req_t *other_constr;
3829 assert(cls == NULL && "same as and register constraint not supported");
3830 assert(!immediate_possible && "same as and immediate constraint not "
3832 assert(same_as < constraint->n_outs && "wrong constraint number in "
3833 "same_as constraint");
3835 other_constr = constraint->out_reqs[same_as];
3837 req = obstack_alloc(obst, sizeof(req[0]));
3838 req->cls = other_constr->cls;
3839 req->type = arch_register_req_type_should_be_same;
3840 req->limited = NULL;
3841 req->other_same = 1U << pos;
3842 req->other_different = 0;
3844 /* switch constraints. This is because in firm we have same_as
3845 * constraints on the output constraints while in the gcc asm syntax
3846 * they are specified on the input constraints */
3847 constraint->req = other_constr;
3848 constraint->out_reqs[same_as] = req;
3849 constraint->immediate_possible = 0;
3853 if(immediate_possible && cls == NULL) {
3854 cls = &ia32_reg_classes[CLASS_ia32_gp];
3856 assert(!immediate_possible || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3857 assert(cls != NULL);
3859 if(immediate_possible) {
3860 assert(constraint->is_in
3861 && "immediate make no sense for output constraints");
3863 /* todo: check types (no float input on 'r' constrained in and such... */
3866 req = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3867 limited_ptr = (unsigned*) (req+1);
3869 req = obstack_alloc(obst, sizeof(req[0]));
3871 memset(req, 0, sizeof(req[0]));
3874 req->type = arch_register_req_type_limited;
3875 *limited_ptr = limited;
3876 req->limited = limited_ptr;
3878 req->type = arch_register_req_type_normal;
3882 constraint->req = req;
3883 constraint->immediate_possible = immediate_possible;
3884 constraint->immediate_type = immediate_type;
3887 static void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
3888 const char *clobber)
3890 ir_graph *irg = get_irn_irg(node);
3891 struct obstack *obst = get_irg_obstack(irg);
3892 const arch_register_t *reg = NULL;
3895 arch_register_req_t *req;
3896 const arch_register_class_t *cls;
3901 /* TODO: construct a hashmap instead of doing linear search for clobber
3903 for(c = 0; c < N_CLASSES; ++c) {
3904 cls = & ia32_reg_classes[c];
3905 for(r = 0; r < cls->n_regs; ++r) {
3906 const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3907 if(strcmp(temp_reg->name, clobber) == 0
3908 || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3917 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3921 assert(reg->index < 32);
3923 limited = obstack_alloc(obst, sizeof(limited[0]));
3924 *limited = 1 << reg->index;
3926 req = obstack_alloc(obst, sizeof(req[0]));
3927 memset(req, 0, sizeof(req[0]));
3928 req->type = arch_register_req_type_limited;
3930 req->limited = limited;
3932 constraint->req = req;
3933 constraint->immediate_possible = 0;
3934 constraint->immediate_type = 0;
3937 static int is_memory_op(const ir_asm_constraint *constraint)
3939 ident *id = constraint->constraint;
3940 const char *str = get_id_str(id);
3943 for(c = str; *c != '\0'; ++c) {
3952 * generates code for a ASM node
3954 static ir_node *gen_ASM(ir_node *node)
3957 ir_graph *irg = current_ir_graph;
3958 ir_node *block = get_nodes_block(node);
3959 ir_node *new_block = be_transform_node(block);
3960 dbg_info *dbgi = get_irn_dbg_info(node);
3964 int n_out_constraints;
3966 const arch_register_req_t **out_reg_reqs;
3967 const arch_register_req_t **in_reg_reqs;
3968 ia32_asm_reg_t *register_map;
3969 unsigned reg_map_size = 0;
3970 struct obstack *obst;
3971 const ir_asm_constraint *in_constraints;
3972 const ir_asm_constraint *out_constraints;
3974 constraint_t parsed_constraint;
3976 arity = get_irn_arity(node);
3977 in = alloca(arity * sizeof(in[0]));
3978 memset(in, 0, arity * sizeof(in[0]));
3980 n_out_constraints = get_ASM_n_output_constraints(node);
3981 n_clobbers = get_ASM_n_clobbers(node);
3982 out_arity = n_out_constraints + n_clobbers;
3983 /* hack to keep space for mem proj */
3987 in_constraints = get_ASM_input_constraints(node);
3988 out_constraints = get_ASM_output_constraints(node);
3989 clobbers = get_ASM_clobbers(node);
3991 /* construct output constraints */
3992 obst = get_irg_obstack(irg);
3993 out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
3994 parsed_constraint.out_reqs = out_reg_reqs;
3995 parsed_constraint.n_outs = n_out_constraints;
3996 parsed_constraint.is_in = 0;
3998 for(i = 0; i < out_arity; ++i) {
4001 if(i < n_out_constraints) {
4002 const ir_asm_constraint *constraint = &out_constraints[i];
4003 c = get_id_str(constraint->constraint);
4004 parse_asm_constraint(i, &parsed_constraint, c);
4006 if(constraint->pos > reg_map_size)
4007 reg_map_size = constraint->pos;
4009 out_reg_reqs[i] = parsed_constraint.req;
4010 } else if(i < out_arity - 1) {
4011 ident *glob_id = clobbers [i - n_out_constraints];
4012 assert(glob_id != NULL);
4013 c = get_id_str(glob_id);
4014 parse_clobber(node, i, &parsed_constraint, c);
4016 out_reg_reqs[i+1] = parsed_constraint.req;
4020 out_reg_reqs[n_out_constraints] = &no_register_req;
4022 /* construct input constraints */
4023 in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
4024 parsed_constraint.is_in = 1;
4025 for(i = 0; i < arity; ++i) {
4026 const ir_asm_constraint *constraint = &in_constraints[i];
4027 ident *constr_id = constraint->constraint;
4028 const char *c = get_id_str(constr_id);
4030 parse_asm_constraint(i, &parsed_constraint, c);
4031 in_reg_reqs[i] = parsed_constraint.req;
4033 if(constraint->pos > reg_map_size)
4034 reg_map_size = constraint->pos;
4036 if(parsed_constraint.immediate_possible) {
4037 ir_node *pred = get_irn_n(node, i);
4038 char imm_type = parsed_constraint.immediate_type;
4039 ir_node *immediate = try_create_Immediate(pred, imm_type);
4041 if(immediate != NULL) {
4048 register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
4049 memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
4051 for(i = 0; i < n_out_constraints; ++i) {
4052 const ir_asm_constraint *constraint = &out_constraints[i];
4053 unsigned pos = constraint->pos;
4055 assert(pos < reg_map_size);
4056 register_map[pos].use_input = 0;
4057 register_map[pos].valid = 1;
4058 register_map[pos].memory = is_memory_op(constraint);
4059 register_map[pos].inout_pos = i;
4060 register_map[pos].mode = constraint->mode;
4063 /* transform inputs */
4064 for(i = 0; i < arity; ++i) {
4065 const ir_asm_constraint *constraint = &in_constraints[i];
4066 unsigned pos = constraint->pos;
4067 ir_node *pred = get_irn_n(node, i);
4068 ir_node *transformed;
4070 assert(pos < reg_map_size);
4071 register_map[pos].use_input = 1;
4072 register_map[pos].valid = 1;
4073 register_map[pos].memory = is_memory_op(constraint);
4074 register_map[pos].inout_pos = i;
4075 register_map[pos].mode = constraint->mode;
4080 transformed = be_transform_node(pred);
4081 in[i] = transformed;
4084 new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
4085 get_ASM_text(node), register_map);
4087 set_ia32_out_req_all(new_node, out_reg_reqs);
4088 set_ia32_in_req_all(new_node, in_reg_reqs);
4090 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4096 * Transforms a FrameAddr into an ia32 Add.
4098 static ir_node *gen_be_FrameAddr(ir_node *node) {
4099 ir_node *block = be_transform_node(get_nodes_block(node));
4100 ir_node *op = be_get_FrameAddr_frame(node);
4101 ir_node *new_op = be_transform_node(op);
4102 ir_graph *irg = current_ir_graph;
4103 dbg_info *dbgi = get_irn_dbg_info(node);
4104 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4107 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
4108 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
4109 set_ia32_use_frame(new_node);
4111 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4117 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
4119 static ir_node *gen_be_Return(ir_node *node) {
4120 ir_graph *irg = current_ir_graph;
4121 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
4122 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
4123 ir_entity *ent = get_irg_entity(irg);
4124 ir_type *tp = get_entity_type(ent);
4129 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
4130 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
4133 int pn_ret_val, pn_ret_mem, arity, i;
4135 assert(ret_val != NULL);
4136 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4137 return be_duplicate_node(node);
4140 res_type = get_method_res_type(tp, 0);
4142 if (! is_Primitive_type(res_type)) {
4143 return be_duplicate_node(node);
4146 mode = get_type_mode(res_type);
4147 if (! mode_is_float(mode)) {
4148 return be_duplicate_node(node);
4151 assert(get_method_n_ress(tp) == 1);
4153 pn_ret_val = get_Proj_proj(ret_val);
4154 pn_ret_mem = get_Proj_proj(ret_mem);
4156 /* get the Barrier */
4157 barrier = get_Proj_pred(ret_val);
4159 /* get result input of the Barrier */
4160 ret_val = get_irn_n(barrier, pn_ret_val);
4161 new_ret_val = be_transform_node(ret_val);
4163 /* get memory input of the Barrier */
4164 ret_mem = get_irn_n(barrier, pn_ret_mem);
4165 new_ret_mem = be_transform_node(ret_mem);
4167 frame = get_irg_frame(irg);
4169 dbgi = get_irn_dbg_info(barrier);
4170 block = be_transform_node(get_nodes_block(barrier));
4172 noreg = ia32_new_NoReg_gp(env_cg);
4174 /* store xmm0 onto stack */
4175 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
4176 new_ret_mem, new_ret_val);
4177 set_ia32_ls_mode(sse_store, mode);
4178 set_ia32_op_type(sse_store, ia32_AddrModeD);
4179 set_ia32_use_frame(sse_store);
4181 /* load into x87 register */
4182 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
4183 set_ia32_op_type(fld, ia32_AddrModeS);
4184 set_ia32_use_frame(fld);
4186 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
4187 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
4189 /* create a new barrier */
4190 arity = get_irn_arity(barrier);
4191 in = alloca(arity * sizeof(in[0]));
4192 for (i = 0; i < arity; ++i) {
4195 if (i == pn_ret_val) {
4197 } else if (i == pn_ret_mem) {
4200 ir_node *in = get_irn_n(barrier, i);
4201 new_in = be_transform_node(in);
4206 new_barrier = new_ir_node(dbgi, irg, block,
4207 get_irn_op(barrier), get_irn_mode(barrier),
4209 copy_node_attr(barrier, new_barrier);
4210 be_duplicate_deps(barrier, new_barrier);
4211 be_set_transformed_node(barrier, new_barrier);
4212 mark_irn_visited(barrier);
4214 /* transform normally */
4215 return be_duplicate_node(node);
4219 * Transform a be_AddSP into an ia32_SubSP.
4221 static ir_node *gen_be_AddSP(ir_node *node)
4223 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4224 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4226 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
4230 * Transform a be_SubSP into an ia32_AddSP
4232 static ir_node *gen_be_SubSP(ir_node *node)
4234 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4235 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4237 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
4241 * This function just sets the register for the Unknown node
4242 * as this is not done during register allocation because Unknown
4243 * is an "ignore" node.
4245 static ir_node *gen_Unknown(ir_node *node) {
4246 ir_mode *mode = get_irn_mode(node);
4248 if (mode_is_float(mode)) {
4249 if (ia32_cg_config.use_sse2) {
4250 return ia32_new_Unknown_xmm(env_cg);
4252 /* Unknown nodes are buggy in x87 simulator, use zero for now... */
4253 ir_graph *irg = current_ir_graph;
4254 dbg_info *dbgi = get_irn_dbg_info(node);
4255 ir_node *block = get_irg_start_block(irg);
4256 ir_node *ret = new_rd_ia32_vfldz(dbgi, irg, block);
4258 /* Const Nodes before the initial IncSP are a bad idea, because
4259 * they could be spilled and we have no SP ready at that point yet.
4260 * So add a dependency to the initial frame pointer calculation to
4261 * avoid that situation.
4263 add_irn_dep(ret, get_irg_frame(irg));
4266 } else if (mode_needs_gp_reg(mode)) {
4267 return ia32_new_Unknown_gp(env_cg);
4269 panic("unsupported Unknown-Mode");
4275 * Change some phi modes
4277 static ir_node *gen_Phi(ir_node *node) {
4278 ir_node *block = be_transform_node(get_nodes_block(node));
4279 ir_graph *irg = current_ir_graph;
4280 dbg_info *dbgi = get_irn_dbg_info(node);
4281 ir_mode *mode = get_irn_mode(node);
4284 if(mode_needs_gp_reg(mode)) {
4285 /* we shouldn't have any 64bit stuff around anymore */
4286 assert(get_mode_size_bits(mode) <= 32);
4287 /* all integer operations are on 32bit registers now */
4289 } else if(mode_is_float(mode)) {
4290 if (ia32_cg_config.use_sse2) {
4297 /* phi nodes allow loops, so we use the old arguments for now
4298 * and fix this later */
4299 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4300 get_irn_in(node) + 1);
4301 copy_node_attr(node, phi);
4302 be_duplicate_deps(node, phi);
4304 be_set_transformed_node(node, phi);
4305 be_enqueue_preds(node);
4313 static ir_node *gen_IJmp(ir_node *node)
4315 ir_node *block = get_nodes_block(node);
4316 ir_node *new_block = be_transform_node(block);
4317 ir_graph *irg = current_ir_graph;
4318 dbg_info *dbgi = get_irn_dbg_info(node);
4319 ir_node *op = get_IJmp_target(node);
4321 ia32_address_mode_t am;
4322 ia32_address_t *addr = &am.addr;
4324 assert(get_irn_mode(op) == mode_P);
4326 match_arguments(&am, block, NULL, op, NULL,
4327 match_am | match_8bit_am | match_16bit_am |
4328 match_immediate | match_8bit | match_16bit);
4330 new_node = new_rd_ia32_IJmp(dbgi, irg, new_block, addr->base, addr->index,
4331 addr->mem, am.new_op2);
4332 set_am_attributes(new_node, &am);
4333 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4335 new_node = fix_mem_proj(new_node, &am);
4340 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4343 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4344 ir_node *val, ir_node *mem);
4347 * Transforms a lowered Load into a "real" one.
4349 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4351 ir_node *block = be_transform_node(get_nodes_block(node));
4352 ir_node *ptr = get_irn_n(node, 0);
4353 ir_node *new_ptr = be_transform_node(ptr);
4354 ir_node *mem = get_irn_n(node, 1);
4355 ir_node *new_mem = be_transform_node(mem);
4356 ir_graph *irg = current_ir_graph;
4357 dbg_info *dbgi = get_irn_dbg_info(node);
4358 ir_mode *mode = get_ia32_ls_mode(node);
4359 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4362 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4364 set_ia32_op_type(new_op, ia32_AddrModeS);
4365 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4366 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4367 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4368 if (is_ia32_am_sc_sign(node))
4369 set_ia32_am_sc_sign(new_op);
4370 set_ia32_ls_mode(new_op, mode);
4371 if (is_ia32_use_frame(node)) {
4372 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4373 set_ia32_use_frame(new_op);
4376 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4382 * Transforms a lowered Store into a "real" one.
4384 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4386 ir_node *block = be_transform_node(get_nodes_block(node));
4387 ir_node *ptr = get_irn_n(node, 0);
4388 ir_node *new_ptr = be_transform_node(ptr);
4389 ir_node *val = get_irn_n(node, 1);
4390 ir_node *new_val = be_transform_node(val);
4391 ir_node *mem = get_irn_n(node, 2);
4392 ir_node *new_mem = be_transform_node(mem);
4393 ir_graph *irg = current_ir_graph;
4394 dbg_info *dbgi = get_irn_dbg_info(node);
4395 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4396 ir_mode *mode = get_ia32_ls_mode(node);
4400 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4402 am_offs = get_ia32_am_offs_int(node);
4403 add_ia32_am_offs_int(new_op, am_offs);
4405 set_ia32_op_type(new_op, ia32_AddrModeD);
4406 set_ia32_ls_mode(new_op, mode);
4407 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4408 set_ia32_use_frame(new_op);
4410 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4415 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4417 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4418 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4420 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4421 match_immediate | match_mode_neutral);
4424 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4426 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4427 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4428 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4432 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4434 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4435 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4436 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4440 static ir_node *gen_ia32_l_Add(ir_node *node) {
4441 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4442 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4443 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4444 match_commutative | match_am | match_immediate |
4445 match_mode_neutral);
4447 if(is_Proj(lowered)) {
4448 lowered = get_Proj_pred(lowered);
4450 assert(is_ia32_Add(lowered));
4451 set_irn_mode(lowered, mode_T);
4457 static ir_node *gen_ia32_l_Adc(ir_node *node)
4459 return gen_binop_flags(node, new_rd_ia32_Adc,
4460 match_commutative | match_am | match_immediate |
4461 match_mode_neutral);
4465 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4467 * @param node The node to transform
4468 * @return the created ia32 vfild node
4470 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4471 return gen_lowered_Load(node, new_rd_ia32_vfild);
4475 * Transforms an ia32_l_Load into a "real" ia32_Load node
4477 * @param node The node to transform
4478 * @return the created ia32 Load node
4480 static ir_node *gen_ia32_l_Load(ir_node *node) {
4481 return gen_lowered_Load(node, new_rd_ia32_Load);
4485 * Transforms an ia32_l_Store into a "real" ia32_Store node
4487 * @param node The node to transform
4488 * @return the created ia32 Store node
4490 static ir_node *gen_ia32_l_Store(ir_node *node) {
4491 return gen_lowered_Store(node, new_rd_ia32_Store);
4495 * Transforms a l_vfist into a "real" vfist node.
4497 * @param node The node to transform
4498 * @return the created ia32 vfist node
4500 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4501 ir_node *block = be_transform_node(get_nodes_block(node));
4502 ir_node *ptr = get_irn_n(node, 0);
4503 ir_node *new_ptr = be_transform_node(ptr);
4504 ir_node *val = get_irn_n(node, 1);
4505 ir_node *new_val = be_transform_node(val);
4506 ir_node *mem = get_irn_n(node, 2);
4507 ir_node *new_mem = be_transform_node(mem);
4508 ir_graph *irg = current_ir_graph;
4509 dbg_info *dbgi = get_irn_dbg_info(node);
4510 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4511 ir_mode *mode = get_ia32_ls_mode(node);
4512 ir_node *memres, *fist;
4515 memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
4516 am_offs = get_ia32_am_offs_int(node);
4517 add_ia32_am_offs_int(fist, am_offs);
4519 set_ia32_op_type(fist, ia32_AddrModeD);
4520 set_ia32_ls_mode(fist, mode);
4521 set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
4522 set_ia32_use_frame(fist);
4524 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4530 * Transforms a l_MulS into a "real" MulS node.
4532 * @return the created ia32 Mul node
4534 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4535 ir_node *left = get_binop_left(node);
4536 ir_node *right = get_binop_right(node);
4538 return gen_binop(node, left, right, new_rd_ia32_Mul,
4539 match_commutative | match_am | match_mode_neutral);
4543 * Transforms a l_IMulS into a "real" IMul1OPS node.
4545 * @return the created ia32 IMul1OP node
4547 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4548 ir_node *left = get_binop_left(node);
4549 ir_node *right = get_binop_right(node);
4551 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4552 match_commutative | match_am | match_mode_neutral);
4555 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4556 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4557 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4558 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4559 match_am | match_immediate | match_mode_neutral);
4561 if(is_Proj(lowered)) {
4562 lowered = get_Proj_pred(lowered);
4564 assert(is_ia32_Sub(lowered));
4565 set_irn_mode(lowered, mode_T);
4571 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4572 return gen_binop_flags(node, new_rd_ia32_Sbb,
4573 match_am | match_immediate | match_mode_neutral);
4577 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4578 * op1 - target to be shifted
4579 * op2 - contains bits to be shifted into target
4581 * Only op3 can be an immediate.
4583 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4584 ir_node *low, ir_node *count)
4586 ir_node *block = get_nodes_block(node);
4587 ir_node *new_block = be_transform_node(block);
4588 ir_graph *irg = current_ir_graph;
4589 dbg_info *dbgi = get_irn_dbg_info(node);
4590 ir_node *new_high = be_transform_node(high);
4591 ir_node *new_low = be_transform_node(low);
4595 /* the shift amount can be any mode that is bigger than 5 bits, since all
4596 * other bits are ignored anyway */
4597 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4598 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4599 count = get_Conv_op(count);
4601 new_count = create_immediate_or_transform(count, 0);
4603 if (is_ia32_l_ShlD(node)) {
4604 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4607 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4610 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4615 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4617 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4618 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4619 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4620 return gen_lowered_64bit_shifts(node, high, low, count);
4623 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4625 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4626 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4627 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4628 return gen_lowered_64bit_shifts(node, high, low, count);
4631 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4632 ir_node *src_block = get_nodes_block(node);
4633 ir_node *block = be_transform_node(src_block);
4634 ir_graph *irg = current_ir_graph;
4635 dbg_info *dbgi = get_irn_dbg_info(node);
4636 ir_node *frame = get_irg_frame(irg);
4637 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4638 ir_node *nomem = new_NoMem();
4639 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4640 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4641 ir_node *new_val_low = be_transform_node(val_low);
4642 ir_node *new_val_high = be_transform_node(val_high);
4647 ir_node *store_high;
4649 if(!mode_is_signed(get_irn_mode(val_high))) {
4650 panic("unsigned long long -> float not supported yet (%+F)", node);
4654 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4656 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4658 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4659 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4661 set_ia32_use_frame(store_low);
4662 set_ia32_use_frame(store_high);
4663 set_ia32_op_type(store_low, ia32_AddrModeD);
4664 set_ia32_op_type(store_high, ia32_AddrModeD);
4665 set_ia32_ls_mode(store_low, mode_Iu);
4666 set_ia32_ls_mode(store_high, mode_Is);
4667 add_ia32_am_offs_int(store_high, 4);
4671 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4674 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4676 set_ia32_use_frame(fild);
4677 set_ia32_op_type(fild, ia32_AddrModeS);
4678 set_ia32_ls_mode(fild, mode_Ls);
4680 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4682 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4685 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4686 ir_node *src_block = get_nodes_block(node);
4687 ir_node *block = be_transform_node(src_block);
4688 ir_graph *irg = current_ir_graph;
4689 dbg_info *dbgi = get_irn_dbg_info(node);
4690 ir_node *frame = get_irg_frame(irg);
4691 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4692 ir_node *nomem = new_NoMem();
4693 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4694 ir_node *new_val = be_transform_node(val);
4695 ir_node *fist, *mem;
4697 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4698 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4699 set_ia32_use_frame(fist);
4700 set_ia32_op_type(fist, ia32_AddrModeD);
4701 set_ia32_ls_mode(fist, mode_Ls);
4707 * the BAD transformer.
4709 static ir_node *bad_transform(ir_node *node) {
4710 panic("No transform function for %+F available.\n", node);
4714 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4715 ir_graph *irg = current_ir_graph;
4716 ir_node *block = be_transform_node(get_nodes_block(node));
4717 ir_node *pred = get_Proj_pred(node);
4718 ir_node *new_pred = be_transform_node(pred);
4719 ir_node *frame = get_irg_frame(irg);
4720 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4721 dbg_info *dbgi = get_irn_dbg_info(node);
4722 long pn = get_Proj_proj(node);
4727 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4728 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4729 set_ia32_use_frame(load);
4730 set_ia32_op_type(load, ia32_AddrModeS);
4731 set_ia32_ls_mode(load, mode_Iu);
4732 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4733 * 32 bit from it with this particular load */
4734 attr = get_ia32_attr(load);
4735 attr->data.need_64bit_stackent = 1;
4737 if (pn == pn_ia32_l_FloattoLL_res_high) {
4738 add_ia32_am_offs_int(load, 4);
4740 assert(pn == pn_ia32_l_FloattoLL_res_low);
4743 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4749 * Transform the Projs of an AddSP.
4751 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4752 ir_node *block = be_transform_node(get_nodes_block(node));
4753 ir_node *pred = get_Proj_pred(node);
4754 ir_node *new_pred = be_transform_node(pred);
4755 ir_graph *irg = current_ir_graph;
4756 dbg_info *dbgi = get_irn_dbg_info(node);
4757 long proj = get_Proj_proj(node);
4759 if (proj == pn_be_AddSP_sp) {
4760 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4761 pn_ia32_SubSP_stack);
4762 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4764 } else if(proj == pn_be_AddSP_res) {
4765 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4766 pn_ia32_SubSP_addr);
4767 } else if (proj == pn_be_AddSP_M) {
4768 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4772 return new_rd_Unknown(irg, get_irn_mode(node));
4776 * Transform the Projs of a SubSP.
4778 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4779 ir_node *block = be_transform_node(get_nodes_block(node));
4780 ir_node *pred = get_Proj_pred(node);
4781 ir_node *new_pred = be_transform_node(pred);
4782 ir_graph *irg = current_ir_graph;
4783 dbg_info *dbgi = get_irn_dbg_info(node);
4784 long proj = get_Proj_proj(node);
4786 if (proj == pn_be_SubSP_sp) {
4787 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4788 pn_ia32_AddSP_stack);
4789 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4791 } else if (proj == pn_be_SubSP_M) {
4792 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4796 return new_rd_Unknown(irg, get_irn_mode(node));
4800 * Transform and renumber the Projs from a Load.
4802 static ir_node *gen_Proj_Load(ir_node *node) {
4804 ir_node *block = be_transform_node(get_nodes_block(node));
4805 ir_node *pred = get_Proj_pred(node);
4806 ir_graph *irg = current_ir_graph;
4807 dbg_info *dbgi = get_irn_dbg_info(node);
4808 long proj = get_Proj_proj(node);
4810 /* loads might be part of source address mode matches, so we don't
4811 * transform the ProjMs yet (with the exception of loads whose result is
4814 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4817 /* this is needed, because sometimes we have loops that are only
4818 reachable through the ProjM */
4819 be_enqueue_preds(node);
4820 /* do it in 2 steps, to silence firm verifier */
4821 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4822 set_Proj_proj(res, pn_ia32_mem);
4826 /* renumber the proj */
4827 new_pred = be_transform_node(pred);
4828 if (is_ia32_Load(new_pred)) {
4831 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4833 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4834 case pn_Load_X_regular:
4835 return new_rd_Jmp(dbgi, irg, block);
4836 case pn_Load_X_except:
4837 /* This Load might raise an exception. Mark it. */
4838 set_ia32_exc_label(new_pred, 1);
4839 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4843 } else if (is_ia32_Conv_I2I(new_pred) ||
4844 is_ia32_Conv_I2I8Bit(new_pred)) {
4845 set_irn_mode(new_pred, mode_T);
4846 if (proj == pn_Load_res) {
4847 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4848 } else if (proj == pn_Load_M) {
4849 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4851 } else if (is_ia32_xLoad(new_pred)) {
4854 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4856 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4857 case pn_Load_X_regular:
4858 return new_rd_Jmp(dbgi, irg, block);
4859 case pn_Load_X_except:
4860 /* This Load might raise an exception. Mark it. */
4861 set_ia32_exc_label(new_pred, 1);
4862 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4866 } else if (is_ia32_vfld(new_pred)) {
4869 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4871 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4872 case pn_Load_X_regular:
4873 return new_rd_Jmp(dbgi, irg, block);
4874 case pn_Load_X_except:
4875 /* This Load might raise an exception. Mark it. */
4876 set_ia32_exc_label(new_pred, 1);
4877 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4882 /* can happen for ProJMs when source address mode happened for the
4885 /* however it should not be the result proj, as that would mean the
4886 load had multiple users and should not have been used for
4888 if (proj != pn_Load_M) {
4889 panic("internal error: transformed node not a Load");
4891 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4895 return new_rd_Unknown(irg, get_irn_mode(node));
4899 * Transform and renumber the Projs from a DivMod like instruction.
4901 static ir_node *gen_Proj_DivMod(ir_node *node) {
4902 ir_node *block = be_transform_node(get_nodes_block(node));
4903 ir_node *pred = get_Proj_pred(node);
4904 ir_node *new_pred = be_transform_node(pred);
4905 ir_graph *irg = current_ir_graph;
4906 dbg_info *dbgi = get_irn_dbg_info(node);
4907 ir_mode *mode = get_irn_mode(node);
4908 long proj = get_Proj_proj(node);
4910 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4912 switch (get_irn_opcode(pred)) {
4916 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4918 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4919 case pn_Div_X_regular:
4920 return new_rd_Jmp(dbgi, irg, block);
4921 case pn_Div_X_except:
4922 set_ia32_exc_label(new_pred, 1);
4923 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4931 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4933 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4934 case pn_Mod_X_except:
4935 set_ia32_exc_label(new_pred, 1);
4936 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4944 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4945 case pn_DivMod_res_div:
4946 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4947 case pn_DivMod_res_mod:
4948 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4949 case pn_DivMod_X_regular:
4950 return new_rd_Jmp(dbgi, irg, block);
4951 case pn_DivMod_X_except:
4952 set_ia32_exc_label(new_pred, 1);
4953 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4963 return new_rd_Unknown(irg, mode);
4967 * Transform and renumber the Projs from a CopyB.
4969 static ir_node *gen_Proj_CopyB(ir_node *node) {
4970 ir_node *block = be_transform_node(get_nodes_block(node));
4971 ir_node *pred = get_Proj_pred(node);
4972 ir_node *new_pred = be_transform_node(pred);
4973 ir_graph *irg = current_ir_graph;
4974 dbg_info *dbgi = get_irn_dbg_info(node);
4975 ir_mode *mode = get_irn_mode(node);
4976 long proj = get_Proj_proj(node);
4979 case pn_CopyB_M_regular:
4980 if (is_ia32_CopyB_i(new_pred)) {
4981 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4982 } else if (is_ia32_CopyB(new_pred)) {
4983 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4991 return new_rd_Unknown(irg, mode);
4995 * Transform and renumber the Projs from a Quot.
4997 static ir_node *gen_Proj_Quot(ir_node *node) {
4998 ir_node *block = be_transform_node(get_nodes_block(node));
4999 ir_node *pred = get_Proj_pred(node);
5000 ir_node *new_pred = be_transform_node(pred);
5001 ir_graph *irg = current_ir_graph;
5002 dbg_info *dbgi = get_irn_dbg_info(node);
5003 ir_mode *mode = get_irn_mode(node);
5004 long proj = get_Proj_proj(node);
5008 if (is_ia32_xDiv(new_pred)) {
5009 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
5010 } else if (is_ia32_vfdiv(new_pred)) {
5011 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
5015 if (is_ia32_xDiv(new_pred)) {
5016 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
5017 } else if (is_ia32_vfdiv(new_pred)) {
5018 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
5021 case pn_Quot_X_regular:
5022 case pn_Quot_X_except:
5028 return new_rd_Unknown(irg, mode);
5032 * Transform the Thread Local Storage Proj.
5034 static ir_node *gen_Proj_tls(ir_node *node) {
5035 ir_node *block = be_transform_node(get_nodes_block(node));
5036 ir_graph *irg = current_ir_graph;
5037 dbg_info *dbgi = NULL;
5038 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
5043 static ir_node *gen_be_Call(ir_node *node) {
5044 ir_node *res = be_duplicate_node(node);
5045 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5050 static ir_node *gen_be_IncSP(ir_node *node) {
5051 ir_node *res = be_duplicate_node(node);
5052 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5058 * Transform the Projs from a be_Call.
5060 static ir_node *gen_Proj_be_Call(ir_node *node) {
5061 ir_node *block = be_transform_node(get_nodes_block(node));
5062 ir_node *call = get_Proj_pred(node);
5063 ir_node *new_call = be_transform_node(call);
5064 ir_graph *irg = current_ir_graph;
5065 dbg_info *dbgi = get_irn_dbg_info(node);
5066 ir_type *method_type = be_Call_get_type(call);
5067 int n_res = get_method_n_ress(method_type);
5068 long proj = get_Proj_proj(node);
5069 ir_mode *mode = get_irn_mode(node);
5071 const arch_register_class_t *cls;
5073 /* The following is kinda tricky: If we're using SSE, then we have to
5074 * move the result value of the call in floating point registers to an
5075 * xmm register, we therefore construct a GetST0 -> xLoad sequence
5076 * after the call, we have to make sure to correctly make the
5077 * MemProj and the result Proj use these 2 nodes
5079 if (proj == pn_be_Call_M_regular) {
5080 // get new node for result, are we doing the sse load/store hack?
5081 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5082 ir_node *call_res_new;
5083 ir_node *call_res_pred = NULL;
5085 if (call_res != NULL) {
5086 call_res_new = be_transform_node(call_res);
5087 call_res_pred = get_Proj_pred(call_res_new);
5090 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
5091 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5092 pn_be_Call_M_regular);
5094 assert(is_ia32_xLoad(call_res_pred));
5095 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5099 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5100 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5102 ir_node *frame = get_irg_frame(irg);
5103 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
5105 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5108 /* in case there is no memory output: create one to serialize the copy
5110 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5111 pn_be_Call_M_regular);
5112 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5113 pn_be_Call_first_res);
5115 /* store st(0) onto stack */
5116 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
5118 set_ia32_op_type(fstp, ia32_AddrModeD);
5119 set_ia32_use_frame(fstp);
5121 /* load into SSE register */
5122 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5124 set_ia32_op_type(sse_load, ia32_AddrModeS);
5125 set_ia32_use_frame(sse_load);
5127 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5133 /* transform call modes */
5134 if (mode_is_data(mode)) {
5135 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5139 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5143 * Transform the Projs from a Cmp.
5145 static ir_node *gen_Proj_Cmp(ir_node *node)
5147 /* this probably means not all mode_b nodes were lowered... */
5148 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5153 * Transform and potentially renumber Proj nodes.
5155 static ir_node *gen_Proj(ir_node *node) {
5156 ir_node *pred = get_Proj_pred(node);
5157 if (is_Store(pred)) {
5158 long proj = get_Proj_proj(node);
5159 if (proj == pn_Store_M) {
5160 return be_transform_node(pred);
5163 return new_r_Bad(current_ir_graph);
5165 } else if (is_Load(pred)) {
5166 return gen_Proj_Load(node);
5167 } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
5168 return gen_Proj_DivMod(node);
5169 } else if (is_CopyB(pred)) {
5170 return gen_Proj_CopyB(node);
5171 } else if (is_Quot(pred)) {
5172 return gen_Proj_Quot(node);
5173 } else if (be_is_SubSP(pred)) {
5174 return gen_Proj_be_SubSP(node);
5175 } else if (be_is_AddSP(pred)) {
5176 return gen_Proj_be_AddSP(node);
5177 } else if (be_is_Call(pred)) {
5178 return gen_Proj_be_Call(node);
5179 } else if (is_Cmp(pred)) {
5180 return gen_Proj_Cmp(node);
5181 } else if (get_irn_op(pred) == op_Start) {
5182 long proj = get_Proj_proj(node);
5183 if (proj == pn_Start_X_initial_exec) {
5184 ir_node *block = get_nodes_block(pred);
5185 dbg_info *dbgi = get_irn_dbg_info(node);
5188 /* we exchange the ProjX with a jump */
5189 block = be_transform_node(block);
5190 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
5193 if (node == be_get_old_anchor(anchor_tls)) {
5194 return gen_Proj_tls(node);
5196 } else if (is_ia32_l_FloattoLL(pred)) {
5197 return gen_Proj_l_FloattoLL(node);
5199 } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5203 ir_mode *mode = get_irn_mode(node);
5204 if (mode_needs_gp_reg(mode)) {
5205 ir_node *new_pred = be_transform_node(pred);
5206 ir_node *block = be_transform_node(get_nodes_block(node));
5207 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5208 mode_Iu, get_Proj_proj(node));
5209 #ifdef DEBUG_libfirm
5210 new_proj->node_nr = node->node_nr;
5216 return be_duplicate_node(node);
5220 * Enters all transform functions into the generic pointer
5222 static void register_transformers(void)
5226 /* first clear the generic function pointer for all ops */
5227 clear_irp_opcodes_generic_func();
5229 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5230 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5268 /* transform ops from intrinsic lowering */
5284 GEN(ia32_l_LLtoFloat);
5285 GEN(ia32_l_FloattoLL);
5291 /* we should never see these nodes */
5306 /* handle generic backend nodes */
5315 op_Mulh = get_op_Mulh();
5324 * Pre-transform all unknown and noreg nodes.
5326 static void ia32_pretransform_node(void *arch_cg) {
5327 ia32_code_gen_t *cg = arch_cg;
5329 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5330 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5331 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5332 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5333 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5334 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5339 * Walker, checks if all ia32 nodes producing more than one result have
5340 * its Projs, otherwise creates new Projs and keep them using a be_Keep node.
5342 static void add_missing_keep_walker(ir_node *node, void *data)
5345 unsigned found_projs = 0;
5346 const ir_edge_t *edge;
5347 ir_mode *mode = get_irn_mode(node);
5352 if(!is_ia32_irn(node))
5355 n_outs = get_ia32_n_res(node);
5358 if(is_ia32_SwitchJmp(node))
5361 assert(n_outs < (int) sizeof(unsigned) * 8);
5362 foreach_out_edge(node, edge) {
5363 ir_node *proj = get_edge_src_irn(edge);
5364 int pn = get_Proj_proj(proj);
5366 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
5367 found_projs |= 1 << pn;
5371 /* are keeps missing? */
5373 for(i = 0; i < n_outs; ++i) {
5376 const arch_register_req_t *req;
5377 const arch_register_class_t *cls;
5379 if(found_projs & (1 << i)) {
5383 req = get_ia32_out_req(node, i);
5388 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
5392 block = get_nodes_block(node);
5393 in[0] = new_r_Proj(current_ir_graph, block, node,
5394 arch_register_class_mode(cls), i);
5395 if(last_keep != NULL) {
5396 be_Keep_add_node(last_keep, cls, in[0]);
5398 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
5399 if(sched_is_scheduled(node)) {
5400 sched_add_after(node, last_keep);
5407 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5410 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5412 ir_graph *irg = be_get_birg_irg(cg->birg);
5413 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5416 /* do the transformation */
5417 void ia32_transform_graph(ia32_code_gen_t *cg) {
5419 ir_graph *irg = cg->irg;
5421 register_transformers();
5423 initial_fpcw = NULL;
5425 BE_TIMER_PUSH(t_heights);
5426 heights = heights_new(irg);
5427 BE_TIMER_POP(t_heights);
5428 ia32_calculate_non_address_mode_nodes(cg->birg);
5430 /* the transform phase is not safe for CSE (yet) because several nodes get
5431 * attributes set after their creation */
5432 cse_last = get_opt_cse();
5435 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5437 set_opt_cse(cse_last);
5439 ia32_free_non_address_mode_nodes();
5440 heights_free(heights);
5444 void ia32_init_transform(void)
5446 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");