2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
35 #include "irgraph_t.h"
40 #include "iredges_t.h"
52 #include "../benode_t.h"
53 #include "../besched.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
60 #include "bearch_ia32_t.h"
61 #include "ia32_nodes_attr.h"
62 #include "ia32_transform.h"
63 #include "ia32_new_nodes.h"
64 #include "ia32_map_regs.h"
65 #include "ia32_dbg_stat.h"
66 #include "ia32_optimize.h"
67 #include "ia32_util.h"
68 #include "ia32_address_mode.h"
69 #include "ia32_architecture.h"
71 #include "gen_ia32_regalloc_if.h"
73 #define SFP_SIGN "0x80000000"
74 #define DFP_SIGN "0x8000000000000000"
75 #define SFP_ABS "0x7FFFFFFF"
76 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
77 #define DFP_INTMAX "9223372036854775807"
79 #define TP_SFP_SIGN "ia32_sfp_sign"
80 #define TP_DFP_SIGN "ia32_dfp_sign"
81 #define TP_SFP_ABS "ia32_sfp_abs"
82 #define TP_DFP_ABS "ia32_dfp_abs"
83 #define TP_INT_MAX "ia32_int_max"
85 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
86 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
87 #define ENT_SFP_ABS "IA32_SFP_ABS"
88 #define ENT_DFP_ABS "IA32_DFP_ABS"
89 #define ENT_INT_MAX "IA32_INT_MAX"
91 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
92 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
94 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
96 /** hold the current code generator during transformation */
97 static ia32_code_gen_t *env_cg = NULL;
98 static ir_node *initial_fpcw = NULL;
99 static heights_t *heights = NULL;
101 extern ir_op *get_op_Mulh(void);
103 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
104 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
105 ir_node *op1, ir_node *op2);
107 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
108 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
109 ir_node *op1, ir_node *op2, ir_node *flags);
111 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
112 ir_node *block, ir_node *op1, ir_node *op2);
114 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
115 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
118 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
119 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
121 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
122 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
123 ir_node *op1, ir_node *op2, ir_node *fpcw);
125 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
126 ir_node *block, ir_node *op);
128 static ir_node *try_create_Immediate(ir_node *node,
129 char immediate_constraint_type);
131 static ir_node *create_immediate_or_transform(ir_node *node,
132 char immediate_constraint_type);
134 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
135 dbg_info *dbgi, ir_node *block,
136 ir_node *op, ir_node *orig_node);
139 * Return true if a mode can be stored in the GP register set
141 static INLINE int mode_needs_gp_reg(ir_mode *mode) {
142 if(mode == mode_fpcw)
144 if(get_mode_size_bits(mode) > 32)
146 return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b;
150 * creates a unique ident by adding a number to a tag
152 * @param tag the tag string, must contain a %d if a number
155 static ident *unique_id(const char *tag)
157 static unsigned id = 0;
160 snprintf(str, sizeof(str), tag, ++id);
161 return new_id_from_str(str);
165 * Get a primitive type for a mode.
167 static ir_type *get_prim_type(pmap *types, ir_mode *mode)
169 pmap_entry *e = pmap_find(types, mode);
174 snprintf(buf, sizeof(buf), "prim_type_%s", get_mode_name(mode));
175 res = new_type_primitive(new_id_from_str(buf), mode);
176 set_type_alignment_bytes(res, 16);
177 pmap_insert(types, mode, res);
185 * Creates an immediate.
187 * @param symconst if set, create a SymConst immediate
188 * @param symconst_sign sign for the symconst
189 * @param val integer value for the immediate
191 static ir_node *create_Immediate(ir_entity *symconst, int symconst_sign, long val)
193 ir_graph *irg = current_ir_graph;
194 ir_node *start_block = get_irg_start_block(irg);
195 ir_node *immediate = new_rd_ia32_Immediate(NULL, irg, start_block,
196 symconst, symconst_sign, val);
197 arch_set_irn_register(env_cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]);
203 * Get an atomic entity that is initialized with a tarval forming
206 * @param cnst the node representing the constant
208 static ir_entity *create_float_const_entity(ir_node *cnst)
210 ia32_isa_t *isa = env_cg->isa;
211 tarval *key = get_Const_tarval(cnst);
212 pmap_entry *e = pmap_find(isa->tv_ent, key);
218 ir_mode *mode = get_tarval_mode(tv);
221 if (! ia32_cg_config.use_sse2) {
222 /* try to reduce the mode to produce smaller sized entities */
223 if (mode != mode_F) {
224 if (tarval_ieee754_can_conv_lossless(tv, mode_F)) {
226 tv = tarval_convert_to(tv, mode);
227 } else if (mode != mode_D) {
228 if (tarval_ieee754_can_conv_lossless(tv, mode_D)) {
230 tv = tarval_convert_to(tv, mode);
236 if (mode == get_irn_mode(cnst)) {
237 /* mode was not changed */
238 tp = get_Const_type(cnst);
239 if (tp == firm_unknown_type)
240 tp = get_prim_type(isa->types, mode);
242 tp = get_prim_type(isa->types, mode);
244 res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);
246 set_entity_ld_ident(res, get_entity_ident(res));
247 set_entity_visibility(res, visibility_local);
248 set_entity_variability(res, variability_constant);
249 set_entity_allocation(res, allocation_static);
251 /* we create a new entity here: It's initialization must resist on the
253 rem = current_ir_graph;
254 current_ir_graph = get_const_code_irg();
255 set_atomic_ent_value(res, new_Const_type(tv, tp));
256 current_ir_graph = rem;
258 pmap_insert(isa->tv_ent, key, res);
266 static int is_Const_0(ir_node *node) {
267 return is_Const(node) && is_Const_null(node);
270 static int is_Const_1(ir_node *node) {
271 return is_Const(node) && is_Const_one(node);
274 static int is_Const_Minus_1(ir_node *node) {
275 return is_Const(node) && is_Const_all_one(node);
279 * returns true if constant can be created with a simple float command
281 static int is_simple_x87_Const(ir_node *node)
283 tarval *tv = get_Const_tarval(node);
284 if (tarval_is_null(tv) || tarval_is_one(tv))
287 /* TODO: match all the other float constants */
292 * returns true if constant can be created with a simple float command
294 static int is_simple_sse_Const(ir_node *node)
296 tarval *tv = get_Const_tarval(node);
297 ir_mode *mode = get_tarval_mode(tv);
302 if (tarval_is_null(tv) || tarval_is_one(tv))
305 if (mode == mode_D) {
306 unsigned val = get_tarval_sub_bits(tv, 0) |
307 (get_tarval_sub_bits(tv, 1) << 8) |
308 (get_tarval_sub_bits(tv, 2) << 16) |
309 (get_tarval_sub_bits(tv, 3) << 24);
311 /* lower 32bit are zero, really a 32bit constant */
315 /* TODO: match all the other float constants */
320 * Transforms a Const.
322 static ir_node *gen_Const(ir_node *node) {
323 ir_graph *irg = current_ir_graph;
324 ir_node *old_block = get_nodes_block(node);
325 ir_node *block = be_transform_node(old_block);
326 dbg_info *dbgi = get_irn_dbg_info(node);
327 ir_mode *mode = get_irn_mode(node);
329 assert(is_Const(node));
331 if (mode_is_float(mode)) {
333 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
334 ir_node *nomem = new_NoMem();
338 if (ia32_cg_config.use_sse2) {
339 tarval *tv = get_Const_tarval(node);
340 if (tarval_is_null(tv)) {
341 load = new_rd_ia32_xZero(dbgi, irg, block);
342 set_ia32_ls_mode(load, mode);
344 } else if (tarval_is_one(tv)) {
345 int cnst = mode == mode_F ? 26 : 55;
346 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
347 ir_node *imm2 = create_Immediate(NULL, 0, 2);
348 ir_node *pslld, *psrld;
350 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
351 set_ia32_ls_mode(load, mode);
352 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
353 set_ia32_ls_mode(pslld, mode);
354 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
355 set_ia32_ls_mode(psrld, mode);
357 } else if (mode == mode_F) {
358 /* we can place any 32bit constant by using a movd gp, sse */
359 unsigned val = get_tarval_sub_bits(tv, 0) |
360 (get_tarval_sub_bits(tv, 1) << 8) |
361 (get_tarval_sub_bits(tv, 2) << 16) |
362 (get_tarval_sub_bits(tv, 3) << 24);
363 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
364 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
365 set_ia32_ls_mode(load, mode);
368 if (mode == mode_D) {
369 unsigned val = get_tarval_sub_bits(tv, 0) |
370 (get_tarval_sub_bits(tv, 1) << 8) |
371 (get_tarval_sub_bits(tv, 2) << 16) |
372 (get_tarval_sub_bits(tv, 3) << 24);
374 ir_node *imm32 = create_Immediate(NULL, 0, 32);
375 ir_node *cnst, *psllq;
377 /* fine, lower 32bit are zero, produce 32bit value */
378 val = get_tarval_sub_bits(tv, 4) |
379 (get_tarval_sub_bits(tv, 5) << 8) |
380 (get_tarval_sub_bits(tv, 6) << 16) |
381 (get_tarval_sub_bits(tv, 7) << 24);
382 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
383 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
384 set_ia32_ls_mode(load, mode);
385 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
386 set_ia32_ls_mode(psllq, mode);
391 floatent = create_float_const_entity(node);
393 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
395 set_ia32_op_type(load, ia32_AddrModeS);
396 set_ia32_am_sc(load, floatent);
397 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
398 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
401 if (is_Const_null(node)) {
402 load = new_rd_ia32_vfldz(dbgi, irg, block);
404 set_ia32_ls_mode(load, mode);
405 } else if (is_Const_one(node)) {
406 load = new_rd_ia32_vfld1(dbgi, irg, block);
408 set_ia32_ls_mode(load, mode);
410 floatent = create_float_const_entity(node);
412 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
413 set_ia32_op_type(load, ia32_AddrModeS);
414 set_ia32_am_sc(load, floatent);
415 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
416 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
417 /* take the mode from the entity */
418 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
422 /* Const Nodes before the initial IncSP are a bad idea, because
423 * they could be spilled and we have no SP ready at that point yet.
424 * So add a dependency to the initial frame pointer calculation to
425 * avoid that situation.
427 if (get_irg_start_block(irg) == block) {
428 add_irn_dep(load, get_irg_frame(irg));
431 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
433 } else { /* non-float mode */
435 tarval *tv = get_Const_tarval(node);
438 tv = tarval_convert_to(tv, mode_Iu);
440 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
442 panic("couldn't convert constant tarval (%+F)", node);
444 val = get_tarval_long(tv);
446 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
447 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
450 if (get_irg_start_block(irg) == block) {
451 add_irn_dep(cnst, get_irg_frame(irg));
459 * Transforms a SymConst.
461 static ir_node *gen_SymConst(ir_node *node) {
462 ir_graph *irg = current_ir_graph;
463 ir_node *old_block = get_nodes_block(node);
464 ir_node *block = be_transform_node(old_block);
465 dbg_info *dbgi = get_irn_dbg_info(node);
466 ir_mode *mode = get_irn_mode(node);
469 if (mode_is_float(mode)) {
470 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
471 ir_node *nomem = new_NoMem();
473 if (ia32_cg_config.use_sse2)
474 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
476 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
477 set_ia32_am_sc(cnst, get_SymConst_entity(node));
478 set_ia32_use_frame(cnst);
482 if(get_SymConst_kind(node) != symconst_addr_ent) {
483 panic("backend only support symconst_addr_ent (at %+F)", node);
485 entity = get_SymConst_entity(node);
486 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
489 /* Const Nodes before the initial IncSP are a bad idea, because
490 * they could be spilled and we have no SP ready at that point yet
492 if (get_irg_start_block(irg) == block) {
493 add_irn_dep(cnst, get_irg_frame(irg));
496 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
501 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
502 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
503 static const struct {
505 const char *ent_name;
506 const char *cnst_str;
509 } names [ia32_known_const_max] = {
510 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
511 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
512 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
513 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
514 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
516 static ir_entity *ent_cache[ia32_known_const_max];
518 const char *tp_name, *ent_name, *cnst_str;
526 ent_name = names[kct].ent_name;
527 if (! ent_cache[kct]) {
528 tp_name = names[kct].tp_name;
529 cnst_str = names[kct].cnst_str;
531 switch (names[kct].mode) {
532 case 0: mode = mode_Iu; break;
533 case 1: mode = mode_Lu; break;
534 default: mode = mode_F; break;
536 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
537 tp = new_type_primitive(new_id_from_str(tp_name), mode);
538 /* set the specified alignment */
539 set_type_alignment_bytes(tp, names[kct].align);
541 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
543 set_entity_ld_ident(ent, get_entity_ident(ent));
544 set_entity_visibility(ent, visibility_local);
545 set_entity_variability(ent, variability_constant);
546 set_entity_allocation(ent, allocation_static);
548 /* we create a new entity here: It's initialization must resist on the
550 rem = current_ir_graph;
551 current_ir_graph = get_const_code_irg();
552 cnst = new_Const(mode, tv);
553 current_ir_graph = rem;
555 set_atomic_ent_value(ent, cnst);
557 /* cache the entry */
558 ent_cache[kct] = ent;
561 return ent_cache[kct];
566 * Prints the old node name on cg obst and returns a pointer to it.
568 const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
569 ia32_isa_t *isa = (ia32_isa_t *)cg->arch_env->isa;
571 lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
572 obstack_1grow(isa->name_obst, 0);
573 return obstack_finish(isa->name_obst);
578 * return true if the node is a Proj(Load) and could be used in source address
579 * mode for another node. Will return only true if the @p other node is not
580 * dependent on the memory of the Load (for binary operations use the other
581 * input here, for unary operations use NULL).
583 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
584 ir_node *other, ir_node *other2, 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);
764 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
766 ir_mode *mode = get_irn_mode(node);
771 if(mode_is_signed(mode)) {
776 block = get_nodes_block(node);
777 dbgi = get_irn_dbg_info(node);
779 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
784 * matches operands of a node into ia32 addressing/operand modes. This covers
785 * usage of source address mode, immediates, operations with non 32-bit modes,
787 * The resulting data is filled into the @p am struct. block is the block
788 * of the node whose arguments are matched. op1, op2 are the first and second
789 * input that are matched (op1 may be NULL). other_op is another unrelated
790 * input that is not matched! but which is needed sometimes to check if AM
791 * for op1/op2 is legal.
792 * @p flags describes the supported modes of the operation in detail.
794 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
795 ir_node *op1, ir_node *op2, ir_node *other_op,
798 ia32_address_t *addr = &am->addr;
799 ir_mode *mode = get_irn_mode(op2);
800 int mode_bits = get_mode_size_bits(mode);
801 ir_node *noreg_gp, *new_op1, *new_op2;
803 unsigned commutative;
804 int use_am_and_immediates;
807 memset(am, 0, sizeof(am[0]));
809 commutative = (flags & match_commutative) != 0;
810 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
811 use_am = (flags & match_am) != 0;
812 use_immediate = (flags & match_immediate) != 0;
813 assert(!use_am_and_immediates || use_immediate);
816 assert(!commutative || op1 != NULL);
817 assert(use_am || !(flags & match_8bit_am));
818 assert(use_am || !(flags & match_16bit_am));
820 if (mode_bits == 8) {
821 if (!(flags & match_8bit_am))
823 /* we don't automatically add upconvs yet */
824 assert((flags & match_mode_neutral) || (flags & match_8bit));
825 } else if (mode_bits == 16) {
826 if (!(flags & match_16bit_am))
828 /* we don't automatically add upconvs yet */
829 assert((flags & match_mode_neutral) || (flags & match_16bit));
832 /* we can simply skip downconvs for mode neutral nodes: the upper bits
833 * can be random for these operations */
834 if (flags & match_mode_neutral) {
835 op2 = ia32_skip_downconv(op2);
837 op1 = ia32_skip_downconv(op1);
841 /* match immediates. firm nodes are normalized: constants are always on the
844 if (!(flags & match_try_am) && use_immediate) {
845 new_op2 = try_create_Immediate(op2, 0);
848 noreg_gp = ia32_new_NoReg_gp(env_cg);
849 if (new_op2 == NULL &&
850 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
851 build_address(am, op2);
852 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
853 if (mode_is_float(mode)) {
854 new_op2 = ia32_new_NoReg_vfp(env_cg);
858 am->op_type = ia32_AddrModeS;
859 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
861 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
863 build_address(am, op1);
865 if (mode_is_float(mode)) {
866 noreg = ia32_new_NoReg_vfp(env_cg);
871 if (new_op2 != NULL) {
874 new_op1 = be_transform_node(op2);
876 am->ins_permuted = 1;
878 am->op_type = ia32_AddrModeS;
880 if (flags & match_try_am) {
883 am->op_type = ia32_Normal;
887 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
889 new_op2 = be_transform_node(op2);
890 am->op_type = ia32_Normal;
891 am->ls_mode = get_irn_mode(op2);
892 if (flags & match_mode_neutral)
893 am->ls_mode = mode_Iu;
895 if (addr->base == NULL)
896 addr->base = noreg_gp;
897 if (addr->index == NULL)
898 addr->index = noreg_gp;
899 if (addr->mem == NULL)
900 addr->mem = new_NoMem();
902 am->new_op1 = new_op1;
903 am->new_op2 = new_op2;
904 am->commutative = commutative;
907 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
912 if (am->mem_proj == NULL)
915 /* we have to create a mode_T so the old MemProj can attach to us */
916 mode = get_irn_mode(node);
917 load = get_Proj_pred(am->mem_proj);
919 mark_irn_visited(load);
920 be_set_transformed_node(load, node);
922 if (mode != mode_T) {
923 set_irn_mode(node, mode_T);
924 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
931 * Construct a standard binary operation, set AM and immediate if required.
933 * @param node The original node for which the binop is created
934 * @param op1 The first operand
935 * @param op2 The second operand
936 * @param func The node constructor function
937 * @return The constructed ia32 node.
939 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
940 construct_binop_func *func, match_flags_t flags)
943 ir_node *block, *new_block, *new_node;
944 ia32_address_mode_t am;
945 ia32_address_t *addr = &am.addr;
947 block = get_nodes_block(node);
948 match_arguments(&am, block, op1, op2, NULL, flags);
950 dbgi = get_irn_dbg_info(node);
951 new_block = be_transform_node(block);
952 new_node = func(dbgi, current_ir_graph, new_block,
953 addr->base, addr->index, addr->mem,
954 am.new_op1, am.new_op2);
955 set_am_attributes(new_node, &am);
956 /* we can't use source address mode anymore when using immediates */
957 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
958 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
959 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
961 new_node = fix_mem_proj(new_node, &am);
968 n_ia32_l_binop_right,
969 n_ia32_l_binop_eflags
971 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
972 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
973 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
974 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
975 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
976 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
979 * Construct a binary operation which also consumes the eflags.
981 * @param node The node to transform
982 * @param func The node constructor function
983 * @param flags The match flags
984 * @return The constructor ia32 node
986 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
989 ir_node *src_block = get_nodes_block(node);
990 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
991 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
993 ir_node *block, *new_node, *eflags, *new_eflags;
994 ia32_address_mode_t am;
995 ia32_address_t *addr = &am.addr;
997 match_arguments(&am, src_block, op1, op2, NULL, flags);
999 dbgi = get_irn_dbg_info(node);
1000 block = be_transform_node(src_block);
1001 eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1002 new_eflags = be_transform_node(eflags);
1003 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
1004 addr->mem, am.new_op1, am.new_op2, new_eflags);
1005 set_am_attributes(new_node, &am);
1006 /* we can't use source address mode anymore when using immediates */
1007 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1008 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1009 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1011 new_node = fix_mem_proj(new_node, &am);
1016 static ir_node *get_fpcw(void)
1019 if (initial_fpcw != NULL)
1020 return initial_fpcw;
1022 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
1023 &ia32_fp_cw_regs[REG_FPCW]);
1024 initial_fpcw = be_transform_node(fpcw);
1026 return initial_fpcw;
1030 * Construct a standard binary operation, set AM and immediate if required.
1032 * @param op1 The first operand
1033 * @param op2 The second operand
1034 * @param func The node constructor function
1035 * @return The constructed ia32 node.
1037 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1038 construct_binop_float_func *func,
1039 match_flags_t flags)
1041 ir_mode *mode = get_irn_mode(node);
1043 ir_node *block, *new_block, *new_node;
1044 ia32_address_mode_t am;
1045 ia32_address_t *addr = &am.addr;
1047 /* cannot use address mode with long double on x87 */
1048 if (get_mode_size_bits(mode) > 64)
1051 block = get_nodes_block(node);
1052 match_arguments(&am, block, op1, op2, NULL, flags);
1054 dbgi = get_irn_dbg_info(node);
1055 new_block = be_transform_node(block);
1056 new_node = func(dbgi, current_ir_graph, new_block,
1057 addr->base, addr->index, addr->mem,
1058 am.new_op1, am.new_op2, get_fpcw());
1059 set_am_attributes(new_node, &am);
1061 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1063 new_node = fix_mem_proj(new_node, &am);
1069 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1071 * @param op1 The first operand
1072 * @param op2 The second operand
1073 * @param func The node constructor function
1074 * @return The constructed ia32 node.
1076 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1077 construct_shift_func *func,
1078 match_flags_t flags)
1081 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1083 assert(! mode_is_float(get_irn_mode(node)));
1084 assert(flags & match_immediate);
1085 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1087 if (flags & match_mode_neutral) {
1088 op1 = ia32_skip_downconv(op1);
1089 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1090 panic("right shifting of non-32bit values not supported, yet");
1092 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 RotL.
1670 * @param op1 The first operator
1671 * @param op2 The second operator
1672 * @return The created ia32 RotL node
1674 static ir_node *gen_RotL(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 RotR.
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_RotR(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_Rot(ir_node *node) {
1701 ir_node *rotate = NULL;
1702 ir_node *op1 = get_Rot_left(node);
1703 ir_node *op2 = get_Rot_right(node);
1705 /* Firm has only Rot (which is a 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 */
1709 if (get_irn_op(op2) == op_Add) {
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 (get_irn_op(left) == op_Minus &&
1719 tarval_is_long(tv) &&
1720 get_tarval_long(tv) == bits &&
1723 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1724 rotate = gen_RotR(node, op1, get_Minus_op(left));
1729 if (rotate == NULL) {
1730 rotate = gen_RotL(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_Rot_left(val);
2315 op2 = get_Rot_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(get_Conv_op(val))) {
2519 val = get_Conv_op(val);
2521 new_val = be_transform_node(val);
2522 if (ia32_cg_config.use_sse2) {
2523 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2524 addr.index, addr.mem, new_val);
2526 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2527 addr.index, addr.mem, new_val, mode);
2530 } else if (is_float_to_int32_conv(val)) {
2531 val = get_Conv_op(val);
2533 /* convs (and strict-convs) before stores are unnecessary if the mode
2535 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2536 val = get_Conv_op(val);
2538 new_val = be_transform_node(val);
2539 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2541 new_val = create_immediate_or_transform(val, 0);
2542 assert(mode != mode_b);
2544 if (get_mode_size_bits(mode) == 8) {
2545 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2546 addr.index, addr.mem, new_val);
2548 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2549 addr.index, addr.mem, new_val);
2554 set_irn_pinned(store, get_irn_pinned(node));
2555 set_ia32_op_type(store, ia32_AddrModeD);
2556 set_ia32_ls_mode(store, mode);
2558 set_address(store, &addr);
2559 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2565 * Transforms a Store.
2567 * @return the created ia32 Store node
2569 static ir_node *gen_Store(ir_node *node)
2571 ir_node *val = get_Store_value(node);
2572 ir_mode *mode = get_irn_mode(val);
2574 if (mode_is_float(mode) && is_Const(val)) {
2577 /* we are storing a floating point constant */
2578 if (ia32_cg_config.use_sse2) {
2579 transform = !is_simple_sse_Const(val);
2581 transform = !is_simple_x87_Const(val);
2584 return gen_float_const_Store(node, val);
2586 return gen_normal_Store(node);
2590 * Transforms a Switch.
2592 * @return the created ia32 SwitchJmp node
2594 static ir_node *create_Switch(ir_node *node)
2596 ir_graph *irg = current_ir_graph;
2597 dbg_info *dbgi = get_irn_dbg_info(node);
2598 ir_node *block = be_transform_node(get_nodes_block(node));
2599 ir_node *sel = get_Cond_selector(node);
2600 ir_node *new_sel = be_transform_node(sel);
2601 int switch_min = INT_MAX;
2602 int switch_max = INT_MIN;
2603 long default_pn = get_Cond_defaultProj(node);
2605 const ir_edge_t *edge;
2607 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2609 /* determine the smallest switch case value */
2610 foreach_out_edge(node, edge) {
2611 ir_node *proj = get_edge_src_irn(edge);
2612 long pn = get_Proj_proj(proj);
2613 if(pn == default_pn)
2622 if((unsigned) (switch_max - switch_min) > 256000) {
2623 panic("Size of switch %+F bigger than 256000", node);
2626 if (switch_min != 0) {
2627 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2629 /* if smallest switch case is not 0 we need an additional sub */
2630 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2631 add_ia32_am_offs_int(new_sel, -switch_min);
2632 set_ia32_op_type(new_sel, ia32_AddrModeS);
2634 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2637 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2638 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2644 * Transform a Cond node.
2646 static ir_node *gen_Cond(ir_node *node) {
2647 ir_node *block = get_nodes_block(node);
2648 ir_node *new_block = be_transform_node(block);
2649 ir_graph *irg = current_ir_graph;
2650 dbg_info *dbgi = get_irn_dbg_info(node);
2651 ir_node *sel = get_Cond_selector(node);
2652 ir_mode *sel_mode = get_irn_mode(sel);
2653 ir_node *flags = NULL;
2657 if (sel_mode != mode_b) {
2658 return create_Switch(node);
2661 /* we get flags from a Cmp */
2662 flags = get_flags_node(sel, &pnc);
2664 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2665 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2671 * Transforms a CopyB node.
2673 * @return The transformed node.
2675 static ir_node *gen_CopyB(ir_node *node) {
2676 ir_node *block = be_transform_node(get_nodes_block(node));
2677 ir_node *src = get_CopyB_src(node);
2678 ir_node *new_src = be_transform_node(src);
2679 ir_node *dst = get_CopyB_dst(node);
2680 ir_node *new_dst = be_transform_node(dst);
2681 ir_node *mem = get_CopyB_mem(node);
2682 ir_node *new_mem = be_transform_node(mem);
2683 ir_node *res = NULL;
2684 ir_graph *irg = current_ir_graph;
2685 dbg_info *dbgi = get_irn_dbg_info(node);
2686 int size = get_type_size_bytes(get_CopyB_type(node));
2689 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2690 /* then we need the size explicitly in ECX. */
2691 if (size >= 32 * 4) {
2692 rem = size & 0x3; /* size % 4 */
2695 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2696 add_irn_dep(res, get_irg_frame(irg));
2698 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2701 ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2704 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2707 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2712 static ir_node *gen_be_Copy(ir_node *node)
2714 ir_node *new_node = be_duplicate_node(node);
2715 ir_mode *mode = get_irn_mode(new_node);
2717 if (mode_needs_gp_reg(mode)) {
2718 set_irn_mode(new_node, mode_Iu);
2724 static ir_node *create_Fucom(ir_node *node)
2726 ir_graph *irg = current_ir_graph;
2727 dbg_info *dbgi = get_irn_dbg_info(node);
2728 ir_node *block = get_nodes_block(node);
2729 ir_node *new_block = be_transform_node(block);
2730 ir_node *left = get_Cmp_left(node);
2731 ir_node *new_left = be_transform_node(left);
2732 ir_node *right = get_Cmp_right(node);
2736 if(ia32_cg_config.use_fucomi) {
2737 new_right = be_transform_node(right);
2738 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2740 set_ia32_commutative(new_node);
2741 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2743 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2744 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2747 new_right = be_transform_node(right);
2748 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2752 set_ia32_commutative(new_node);
2754 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2756 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2757 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2763 static ir_node *create_Ucomi(ir_node *node)
2765 ir_graph *irg = current_ir_graph;
2766 dbg_info *dbgi = get_irn_dbg_info(node);
2767 ir_node *src_block = get_nodes_block(node);
2768 ir_node *new_block = be_transform_node(src_block);
2769 ir_node *left = get_Cmp_left(node);
2770 ir_node *right = get_Cmp_right(node);
2772 ia32_address_mode_t am;
2773 ia32_address_t *addr = &am.addr;
2775 match_arguments(&am, src_block, left, right, NULL,
2776 match_commutative | match_am);
2778 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2779 addr->mem, am.new_op1, am.new_op2,
2781 set_am_attributes(new_node, &am);
2783 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2785 new_node = fix_mem_proj(new_node, &am);
2791 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2792 * to fold an and into a test node
2794 static int can_fold_test_and(ir_node *node)
2796 const ir_edge_t *edge;
2798 /** we can only have eq and lg projs */
2799 foreach_out_edge(node, edge) {
2800 ir_node *proj = get_edge_src_irn(edge);
2801 pn_Cmp pnc = get_Proj_proj(proj);
2802 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2810 * Generate code for a Cmp.
2812 static ir_node *gen_Cmp(ir_node *node)
2814 ir_graph *irg = current_ir_graph;
2815 dbg_info *dbgi = get_irn_dbg_info(node);
2816 ir_node *block = get_nodes_block(node);
2817 ir_node *new_block = be_transform_node(block);
2818 ir_node *left = get_Cmp_left(node);
2819 ir_node *right = get_Cmp_right(node);
2820 ir_mode *cmp_mode = get_irn_mode(left);
2822 ia32_address_mode_t am;
2823 ia32_address_t *addr = &am.addr;
2826 if(mode_is_float(cmp_mode)) {
2827 if (ia32_cg_config.use_sse2) {
2828 return create_Ucomi(node);
2830 return create_Fucom(node);
2834 assert(mode_needs_gp_reg(cmp_mode));
2836 /* we prefer the Test instruction where possible except cases where
2837 * we can use SourceAM */
2838 cmp_unsigned = !mode_is_signed(cmp_mode);
2839 if (is_Const_0(right)) {
2841 get_irn_n_edges(left) == 1 &&
2842 can_fold_test_and(node)) {
2843 /* Test(and_left, and_right) */
2844 ir_node *and_left = get_And_left(left);
2845 ir_node *and_right = get_And_right(left);
2846 ir_mode *mode = get_irn_mode(and_left);
2848 match_arguments(&am, block, and_left, and_right, NULL,
2850 match_am | match_8bit_am | match_16bit_am |
2851 match_am_and_immediates | match_immediate |
2852 match_8bit | match_16bit);
2853 if (get_mode_size_bits(mode) == 8) {
2854 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2855 addr->index, addr->mem, am.new_op1,
2856 am.new_op2, am.ins_permuted,
2859 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2860 addr->index, addr->mem, am.new_op1,
2861 am.new_op2, am.ins_permuted, cmp_unsigned);
2864 match_arguments(&am, block, NULL, left, NULL,
2865 match_am | match_8bit_am | match_16bit_am |
2866 match_8bit | match_16bit);
2867 if (am.op_type == ia32_AddrModeS) {
2869 ir_node *imm_zero = try_create_Immediate(right, 0);
2870 if (get_mode_size_bits(cmp_mode) == 8) {
2871 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2872 addr->index, addr->mem, am.new_op2,
2873 imm_zero, am.ins_permuted,
2876 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2877 addr->index, addr->mem, am.new_op2,
2878 imm_zero, am.ins_permuted, cmp_unsigned);
2881 /* Test(left, left) */
2882 if (get_mode_size_bits(cmp_mode) == 8) {
2883 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2884 addr->index, addr->mem, am.new_op2,
2885 am.new_op2, am.ins_permuted,
2888 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2889 addr->index, addr->mem, am.new_op2,
2890 am.new_op2, am.ins_permuted,
2896 /* Cmp(left, right) */
2897 match_arguments(&am, block, left, right, NULL,
2898 match_commutative | match_am | match_8bit_am |
2899 match_16bit_am | match_am_and_immediates |
2900 match_immediate | match_8bit | match_16bit);
2901 if (get_mode_size_bits(cmp_mode) == 8) {
2902 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2903 addr->index, addr->mem, am.new_op1,
2904 am.new_op2, am.ins_permuted,
2907 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2908 addr->index, addr->mem, am.new_op1,
2909 am.new_op2, am.ins_permuted, cmp_unsigned);
2912 set_am_attributes(new_node, &am);
2913 assert(cmp_mode != NULL);
2914 set_ia32_ls_mode(new_node, cmp_mode);
2916 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2918 new_node = fix_mem_proj(new_node, &am);
2923 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2926 ir_graph *irg = current_ir_graph;
2927 dbg_info *dbgi = get_irn_dbg_info(node);
2928 ir_node *block = get_nodes_block(node);
2929 ir_node *new_block = be_transform_node(block);
2930 ir_node *val_true = get_Psi_val(node, 0);
2931 ir_node *val_false = get_Psi_default(node);
2933 match_flags_t match_flags;
2934 ia32_address_mode_t am;
2935 ia32_address_t *addr;
2937 assert(ia32_cg_config.use_cmov);
2938 assert(mode_needs_gp_reg(get_irn_mode(val_true)));
2942 match_flags = match_commutative | match_am | match_16bit_am |
2945 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2947 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2948 addr->mem, am.new_op1, am.new_op2, new_flags,
2949 am.ins_permuted, pnc);
2950 set_am_attributes(new_node, &am);
2952 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2954 new_node = fix_mem_proj(new_node, &am);
2960 * Creates a ia32 Setcc instruction.
2962 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2963 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2966 ir_graph *irg = current_ir_graph;
2967 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2968 ir_node *nomem = new_NoMem();
2969 ir_mode *mode = get_irn_mode(orig_node);
2972 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2973 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2975 /* we might need to conv the result up */
2976 if (get_mode_size_bits(mode) > 8) {
2977 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2978 nomem, new_node, mode_Bu);
2979 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2986 * Create instruction for an unsigned Difference or Zero.
2988 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2989 ir_graph *irg = current_ir_graph;
2990 ir_mode *mode = get_irn_mode(psi);
2991 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2994 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2995 match_mode_neutral | match_am | match_immediate | match_two_users);
2997 block = get_nodes_block(new_node);
2999 if (is_Proj(new_node)) {
3000 sub = get_Proj_pred(new_node);
3001 assert(is_ia32_Sub(sub));
3004 set_irn_mode(sub, mode_T);
3005 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
3007 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3009 dbgi = get_irn_dbg_info(psi);
3010 noreg = ia32_new_NoReg_gp(env_cg);
3011 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
3012 nomem = new_NoMem();
3013 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
3015 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
3016 set_ia32_commutative(new_node);
3021 * Transforms a Psi node into CMov.
3023 * @return The transformed node.
3025 static ir_node *gen_Psi(ir_node *node)
3027 dbg_info *dbgi = get_irn_dbg_info(node);
3028 ir_node *block = get_nodes_block(node);
3029 ir_node *new_block = be_transform_node(block);
3030 ir_node *psi_true = get_Psi_val(node, 0);
3031 ir_node *psi_default = get_Psi_default(node);
3032 ir_node *cond = get_Psi_cond(node, 0);
3033 ir_mode *mode = get_irn_mode(node);
3034 ir_node *cmp = get_Proj_pred(cond);
3035 ir_node *cmp_left = get_Cmp_left(cmp);
3036 ir_node *cmp_right = get_Cmp_right(cmp);
3037 pn_Cmp pnc = get_Proj_proj(cond);
3039 assert(get_Psi_n_conds(node) == 1);
3040 assert(get_irn_mode(cond) == mode_b);
3042 /* Note: a Psi node uses a Load two times IFF it's used in the compare AND in the result */
3043 if (mode_is_float(mode)) {
3044 if (ia32_cg_config.use_sse2) {
3045 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3046 if (cmp_left == psi_true && cmp_right == psi_default) {
3047 /* psi(a <= b, a, b) => MIN */
3048 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3049 match_commutative | match_am | match_two_users);
3050 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3051 /* psi(a <= b, b, a) => MAX */
3052 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3053 match_commutative | match_am | match_two_users);
3055 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3056 if (cmp_left == psi_true && cmp_right == psi_default) {
3057 /* psi(a >= b, a, b) => MAX */
3058 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3059 match_commutative | match_am | match_two_users);
3060 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3061 /* psi(a >= b, b, a) => MIN */
3062 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3063 match_commutative | match_am | match_two_users);
3067 panic("cannot transform floating point Psi");
3073 assert(mode_needs_gp_reg(mode));
3075 /* check for unsigned Doz first */
3076 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3077 is_Const_0(psi_default) && is_Sub(psi_true) &&
3078 get_Sub_left(psi_true) == cmp_left && get_Sub_right(psi_true) == cmp_right) {
3079 /* Psi(a >=u b, a - b, 0) unsigned Doz */
3080 return create_Doz(node, cmp_left, cmp_right);
3081 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3082 is_Const_0(psi_true) && is_Sub(psi_default) &&
3083 get_Sub_left(psi_default) == cmp_left && get_Sub_right(psi_default) == cmp_right) {
3084 /* Psi(a <=u b, 0, a - b) unsigned Doz */
3085 return create_Doz(node, cmp_left, cmp_right);
3088 flags = get_flags_node(cond, &pnc);
3090 if (is_Const(psi_true) && is_Const(psi_default)) {
3091 /* both are const, good */
3092 if (is_Const_1(psi_true) && is_Const_0(psi_default)) {
3093 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3094 } else if (is_Const_0(psi_true) && is_Const_1(psi_default)) {
3095 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3097 /* Not that simple. */
3100 new_node = create_CMov(node, cond, flags, pnc);
3108 * Create a conversion from x87 state register to general purpose.
3110 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3111 ir_node *block = be_transform_node(get_nodes_block(node));
3112 ir_node *op = get_Conv_op(node);
3113 ir_node *new_op = be_transform_node(op);
3114 ia32_code_gen_t *cg = env_cg;
3115 ir_graph *irg = current_ir_graph;
3116 dbg_info *dbgi = get_irn_dbg_info(node);
3117 ir_node *noreg = ia32_new_NoReg_gp(cg);
3118 ir_mode *mode = get_irn_mode(node);
3119 ir_node *fist, *load, *mem;
3121 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3122 set_irn_pinned(fist, op_pin_state_floats);
3123 set_ia32_use_frame(fist);
3124 set_ia32_op_type(fist, ia32_AddrModeD);
3126 assert(get_mode_size_bits(mode) <= 32);
3127 /* exception we can only store signed 32 bit integers, so for unsigned
3128 we store a 64bit (signed) integer and load the lower bits */
3129 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3130 set_ia32_ls_mode(fist, mode_Ls);
3132 set_ia32_ls_mode(fist, mode_Is);
3134 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3137 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3139 set_irn_pinned(load, op_pin_state_floats);
3140 set_ia32_use_frame(load);
3141 set_ia32_op_type(load, ia32_AddrModeS);
3142 set_ia32_ls_mode(load, mode_Is);
3143 if(get_ia32_ls_mode(fist) == mode_Ls) {
3144 ia32_attr_t *attr = get_ia32_attr(load);
3145 attr->data.need_64bit_stackent = 1;
3147 ia32_attr_t *attr = get_ia32_attr(load);
3148 attr->data.need_32bit_stackent = 1;
3150 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3152 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3156 * Creates a x87 strict Conv by placing a Sore and a Load
3158 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3160 ir_node *block = get_nodes_block(node);
3161 ir_graph *irg = current_ir_graph;
3162 dbg_info *dbgi = get_irn_dbg_info(node);
3163 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3164 ir_node *nomem = new_NoMem();
3165 ir_node *frame = get_irg_frame(irg);
3166 ir_node *store, *load;
3169 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3171 set_ia32_use_frame(store);
3172 set_ia32_op_type(store, ia32_AddrModeD);
3173 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3175 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3177 set_ia32_use_frame(load);
3178 set_ia32_op_type(load, ia32_AddrModeS);
3179 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3181 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3186 * Create a conversion from general purpose to x87 register
3188 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3189 ir_node *src_block = get_nodes_block(node);
3190 ir_node *block = be_transform_node(src_block);
3191 ir_graph *irg = current_ir_graph;
3192 dbg_info *dbgi = get_irn_dbg_info(node);
3193 ir_node *op = get_Conv_op(node);
3194 ir_node *new_op = NULL;
3198 ir_mode *store_mode;
3204 /* fild can use source AM if the operand is a signed 32bit integer */
3205 if (src_mode == mode_Is) {
3206 ia32_address_mode_t am;
3208 match_arguments(&am, src_block, NULL, op, NULL,
3209 match_am | match_try_am);
3210 if (am.op_type == ia32_AddrModeS) {
3211 ia32_address_t *addr = &am.addr;
3213 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3214 addr->index, addr->mem);
3215 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3218 set_am_attributes(fild, &am);
3219 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3221 fix_mem_proj(fild, &am);
3226 if(new_op == NULL) {
3227 new_op = be_transform_node(op);
3230 noreg = ia32_new_NoReg_gp(env_cg);
3231 nomem = new_NoMem();
3232 mode = get_irn_mode(op);
3234 /* first convert to 32 bit signed if necessary */
3235 src_bits = get_mode_size_bits(src_mode);
3236 if (src_bits == 8) {
3237 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3239 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3241 } else if (src_bits < 32) {
3242 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3244 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3248 assert(get_mode_size_bits(mode) == 32);
3251 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3254 set_ia32_use_frame(store);
3255 set_ia32_op_type(store, ia32_AddrModeD);
3256 set_ia32_ls_mode(store, mode_Iu);
3258 /* exception for 32bit unsigned, do a 64bit spill+load */
3259 if(!mode_is_signed(mode)) {
3262 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3264 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3265 get_irg_frame(irg), noreg, nomem,
3268 set_ia32_use_frame(zero_store);
3269 set_ia32_op_type(zero_store, ia32_AddrModeD);
3270 add_ia32_am_offs_int(zero_store, 4);
3271 set_ia32_ls_mode(zero_store, mode_Iu);
3276 store = new_rd_Sync(dbgi, irg, block, 2, in);
3277 store_mode = mode_Ls;
3279 store_mode = mode_Is;
3283 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3285 set_ia32_use_frame(fild);
3286 set_ia32_op_type(fild, ia32_AddrModeS);
3287 set_ia32_ls_mode(fild, store_mode);
3289 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3295 * Create a conversion from one integer mode into another one
3297 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3298 dbg_info *dbgi, ir_node *block, ir_node *op,
3301 ir_graph *irg = current_ir_graph;
3302 int src_bits = get_mode_size_bits(src_mode);
3303 int tgt_bits = get_mode_size_bits(tgt_mode);
3304 ir_node *new_block = be_transform_node(block);
3306 ir_mode *smaller_mode;
3308 ia32_address_mode_t am;
3309 ia32_address_t *addr = &am.addr;
3312 if (src_bits < tgt_bits) {
3313 smaller_mode = src_mode;
3314 smaller_bits = src_bits;
3316 smaller_mode = tgt_mode;
3317 smaller_bits = tgt_bits;
3320 #ifdef DEBUG_libfirm
3322 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3327 match_arguments(&am, block, NULL, op, NULL,
3328 match_8bit | match_16bit |
3329 match_am | match_8bit_am | match_16bit_am);
3330 if (smaller_bits == 8) {
3331 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3332 addr->index, addr->mem, am.new_op2,
3335 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3336 addr->index, addr->mem, am.new_op2,
3339 set_am_attributes(new_node, &am);
3340 /* match_arguments assume that out-mode = in-mode, this isn't true here
3342 set_ia32_ls_mode(new_node, smaller_mode);
3343 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3344 new_node = fix_mem_proj(new_node, &am);
3349 * Transforms a Conv node.
3351 * @return The created ia32 Conv node
3353 static ir_node *gen_Conv(ir_node *node) {
3354 ir_node *block = get_nodes_block(node);
3355 ir_node *new_block = be_transform_node(block);
3356 ir_node *op = get_Conv_op(node);
3357 ir_node *new_op = NULL;
3358 ir_graph *irg = current_ir_graph;
3359 dbg_info *dbgi = get_irn_dbg_info(node);
3360 ir_mode *src_mode = get_irn_mode(op);
3361 ir_mode *tgt_mode = get_irn_mode(node);
3362 int src_bits = get_mode_size_bits(src_mode);
3363 int tgt_bits = get_mode_size_bits(tgt_mode);
3364 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3365 ir_node *nomem = new_rd_NoMem(irg);
3366 ir_node *res = NULL;
3368 if (src_mode == mode_b) {
3369 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3370 /* nothing to do, we already model bools as 0/1 ints */
3371 return be_transform_node(op);
3374 if (src_mode == tgt_mode) {
3375 if (get_Conv_strict(node)) {
3376 if (ia32_cg_config.use_sse2) {
3377 /* when we are in SSE mode, we can kill all strict no-op conversion */
3378 return be_transform_node(op);
3381 /* this should be optimized already, but who knows... */
3382 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3383 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3384 return be_transform_node(op);
3388 if (mode_is_float(src_mode)) {
3389 new_op = be_transform_node(op);
3390 /* we convert from float ... */
3391 if (mode_is_float(tgt_mode)) {
3392 if(src_mode == mode_E && tgt_mode == mode_D
3393 && !get_Conv_strict(node)) {
3394 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3399 if (ia32_cg_config.use_sse2) {
3400 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3401 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3403 set_ia32_ls_mode(res, tgt_mode);
3405 if(get_Conv_strict(node)) {
3406 res = gen_x87_strict_conv(tgt_mode, new_op);
3407 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3410 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3415 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3416 if (ia32_cg_config.use_sse2) {
3417 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3419 set_ia32_ls_mode(res, src_mode);
3421 return gen_x87_fp_to_gp(node);
3425 /* we convert from int ... */
3426 if (mode_is_float(tgt_mode)) {
3428 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3429 if (ia32_cg_config.use_sse2) {
3430 new_op = be_transform_node(op);
3431 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3433 set_ia32_ls_mode(res, tgt_mode);
3435 res = gen_x87_gp_to_fp(node, src_mode);
3436 if(get_Conv_strict(node)) {
3437 res = gen_x87_strict_conv(tgt_mode, res);
3438 SET_IA32_ORIG_NODE(get_Proj_pred(res),
3439 ia32_get_old_node_name(env_cg, node));
3443 } else if(tgt_mode == mode_b) {
3444 /* mode_b lowering already took care that we only have 0/1 values */
3445 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3446 src_mode, tgt_mode));
3447 return be_transform_node(op);
3450 if (src_bits == tgt_bits) {
3451 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3452 src_mode, tgt_mode));
3453 return be_transform_node(op);
3456 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3464 static int check_immediate_constraint(long val, char immediate_constraint_type)
3466 switch (immediate_constraint_type) {
3470 return val >= 0 && val <= 32;
3472 return val >= 0 && val <= 63;
3474 return val >= -128 && val <= 127;
3476 return val == 0xff || val == 0xffff;
3478 return val >= 0 && val <= 3;
3480 return val >= 0 && val <= 255;
3482 return val >= 0 && val <= 127;
3486 panic("Invalid immediate constraint found");
3490 static ir_node *try_create_Immediate(ir_node *node,
3491 char immediate_constraint_type)
3494 tarval *offset = NULL;
3495 int offset_sign = 0;
3497 ir_entity *symconst_ent = NULL;
3498 int symconst_sign = 0;
3500 ir_node *cnst = NULL;
3501 ir_node *symconst = NULL;
3504 mode = get_irn_mode(node);
3505 if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3509 if(is_Minus(node)) {
3511 node = get_Minus_op(node);
3514 if(is_Const(node)) {
3517 offset_sign = minus;
3518 } else if(is_SymConst(node)) {
3521 symconst_sign = minus;
3522 } else if(is_Add(node)) {
3523 ir_node *left = get_Add_left(node);
3524 ir_node *right = get_Add_right(node);
3525 if(is_Const(left) && is_SymConst(right)) {
3528 symconst_sign = minus;
3529 offset_sign = minus;
3530 } else if(is_SymConst(left) && is_Const(right)) {
3533 symconst_sign = minus;
3534 offset_sign = minus;
3536 } else if(is_Sub(node)) {
3537 ir_node *left = get_Sub_left(node);
3538 ir_node *right = get_Sub_right(node);
3539 if(is_Const(left) && is_SymConst(right)) {
3542 symconst_sign = !minus;
3543 offset_sign = minus;
3544 } else if(is_SymConst(left) && is_Const(right)) {
3547 symconst_sign = minus;
3548 offset_sign = !minus;
3555 offset = get_Const_tarval(cnst);
3556 if(tarval_is_long(offset)) {
3557 val = get_tarval_long(offset);
3559 ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3564 if(!check_immediate_constraint(val, immediate_constraint_type))
3567 if(symconst != NULL) {
3568 if(immediate_constraint_type != 0) {
3569 /* we need full 32bits for symconsts */
3573 /* unfortunately the assembler/linker doesn't support -symconst */
3577 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3579 symconst_ent = get_SymConst_entity(symconst);
3581 if(cnst == NULL && symconst == NULL)
3584 if(offset_sign && offset != NULL) {
3585 offset = tarval_neg(offset);
3588 new_node = create_Immediate(symconst_ent, symconst_sign, val);
3593 static ir_node *create_immediate_or_transform(ir_node *node,
3594 char immediate_constraint_type)
3596 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3597 if (new_node == NULL) {
3598 new_node = be_transform_node(node);
3603 static const arch_register_req_t no_register_req = {
3604 arch_register_req_type_none,
3605 NULL, /* regclass */
3606 NULL, /* limit bitset */
3608 0 /* different pos */
3612 * An assembler constraint.
3614 typedef struct constraint_t constraint_t;
3615 struct constraint_t {
3618 const arch_register_req_t **out_reqs;
3620 const arch_register_req_t *req;
3621 unsigned immediate_possible;
3622 char immediate_type;
3625 static void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
3627 int immediate_possible = 0;
3628 char immediate_type = 0;
3629 unsigned limited = 0;
3630 const arch_register_class_t *cls = NULL;
3631 ir_graph *irg = current_ir_graph;
3632 struct obstack *obst = get_irg_obstack(irg);
3633 arch_register_req_t *req;
3634 unsigned *limited_ptr = NULL;
3638 /* TODO: replace all the asserts with nice error messages */
3641 /* a memory constraint: no need to do anything in backend about it
3642 * (the dependencies are already respected by the memory edge of
3644 constraint->req = &no_register_req;
3656 assert(cls == NULL ||
3657 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3658 cls = &ia32_reg_classes[CLASS_ia32_gp];
3659 limited |= 1 << REG_EAX;
3662 assert(cls == NULL ||
3663 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3664 cls = &ia32_reg_classes[CLASS_ia32_gp];
3665 limited |= 1 << REG_EBX;
3668 assert(cls == NULL ||
3669 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3670 cls = &ia32_reg_classes[CLASS_ia32_gp];
3671 limited |= 1 << REG_ECX;
3674 assert(cls == NULL ||
3675 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3676 cls = &ia32_reg_classes[CLASS_ia32_gp];
3677 limited |= 1 << REG_EDX;
3680 assert(cls == NULL ||
3681 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3682 cls = &ia32_reg_classes[CLASS_ia32_gp];
3683 limited |= 1 << REG_EDI;
3686 assert(cls == NULL ||
3687 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3688 cls = &ia32_reg_classes[CLASS_ia32_gp];
3689 limited |= 1 << REG_ESI;
3692 case 'q': /* q means lower part of the regs only, this makes no
3693 * difference to Q for us (we only assigne whole registers) */
3694 assert(cls == NULL ||
3695 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3696 cls = &ia32_reg_classes[CLASS_ia32_gp];
3697 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
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_EAX | 1 << REG_EDX;
3707 assert(cls == NULL ||
3708 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3709 cls = &ia32_reg_classes[CLASS_ia32_gp];
3710 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3711 1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3718 assert(cls == NULL);
3719 cls = &ia32_reg_classes[CLASS_ia32_gp];
3725 /* TODO: mark values so the x87 simulator knows about t and u */
3726 assert(cls == NULL);
3727 cls = &ia32_reg_classes[CLASS_ia32_vfp];
3732 assert(cls == NULL);
3733 /* TODO: check that sse2 is supported */
3734 cls = &ia32_reg_classes[CLASS_ia32_xmm];
3744 assert(!immediate_possible);
3745 immediate_possible = 1;
3746 immediate_type = *c;
3750 assert(!immediate_possible);
3751 immediate_possible = 1;
3755 assert(!immediate_possible && cls == NULL);
3756 immediate_possible = 1;
3757 cls = &ia32_reg_classes[CLASS_ia32_gp];
3770 assert(constraint->is_in && "can only specify same constraint "
3773 sscanf(c, "%d%n", &same_as, &p);
3781 /* memory constraint no need to do anything in backend about it
3782 * (the dependencies are already respected by the memory edge of
3784 constraint->req = &no_register_req;
3787 case 'E': /* no float consts yet */
3788 case 'F': /* no float consts yet */
3789 case 's': /* makes no sense on x86 */
3790 case 'X': /* we can't support that in firm */
3793 case '<': /* no autodecrement on x86 */
3794 case '>': /* no autoincrement on x86 */
3795 case 'C': /* sse constant not supported yet */
3796 case 'G': /* 80387 constant not supported yet */
3797 case 'y': /* we don't support mmx registers yet */
3798 case 'Z': /* not available in 32 bit mode */
3799 case 'e': /* not available in 32 bit mode */
3800 panic("unsupported asm constraint '%c' found in (%+F)",
3801 *c, current_ir_graph);
3804 panic("unknown asm constraint '%c' found in (%+F)", *c,
3812 const arch_register_req_t *other_constr;
3814 assert(cls == NULL && "same as and register constraint not supported");
3815 assert(!immediate_possible && "same as and immediate constraint not "
3817 assert(same_as < constraint->n_outs && "wrong constraint number in "
3818 "same_as constraint");
3820 other_constr = constraint->out_reqs[same_as];
3822 req = obstack_alloc(obst, sizeof(req[0]));
3823 req->cls = other_constr->cls;
3824 req->type = arch_register_req_type_should_be_same;
3825 req->limited = NULL;
3826 req->other_same = 1U << pos;
3827 req->other_different = 0;
3829 /* switch constraints. This is because in firm we have same_as
3830 * constraints on the output constraints while in the gcc asm syntax
3831 * they are specified on the input constraints */
3832 constraint->req = other_constr;
3833 constraint->out_reqs[same_as] = req;
3834 constraint->immediate_possible = 0;
3838 if(immediate_possible && cls == NULL) {
3839 cls = &ia32_reg_classes[CLASS_ia32_gp];
3841 assert(!immediate_possible || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3842 assert(cls != NULL);
3844 if(immediate_possible) {
3845 assert(constraint->is_in
3846 && "immediate make no sense for output constraints");
3848 /* todo: check types (no float input on 'r' constrained in and such... */
3851 req = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3852 limited_ptr = (unsigned*) (req+1);
3854 req = obstack_alloc(obst, sizeof(req[0]));
3856 memset(req, 0, sizeof(req[0]));
3859 req->type = arch_register_req_type_limited;
3860 *limited_ptr = limited;
3861 req->limited = limited_ptr;
3863 req->type = arch_register_req_type_normal;
3867 constraint->req = req;
3868 constraint->immediate_possible = immediate_possible;
3869 constraint->immediate_type = immediate_type;
3872 static void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
3873 const char *clobber)
3875 ir_graph *irg = get_irn_irg(node);
3876 struct obstack *obst = get_irg_obstack(irg);
3877 const arch_register_t *reg = NULL;
3880 arch_register_req_t *req;
3881 const arch_register_class_t *cls;
3886 /* TODO: construct a hashmap instead of doing linear search for clobber
3888 for(c = 0; c < N_CLASSES; ++c) {
3889 cls = & ia32_reg_classes[c];
3890 for(r = 0; r < cls->n_regs; ++r) {
3891 const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3892 if(strcmp(temp_reg->name, clobber) == 0
3893 || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3902 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3906 assert(reg->index < 32);
3908 limited = obstack_alloc(obst, sizeof(limited[0]));
3909 *limited = 1 << reg->index;
3911 req = obstack_alloc(obst, sizeof(req[0]));
3912 memset(req, 0, sizeof(req[0]));
3913 req->type = arch_register_req_type_limited;
3915 req->limited = limited;
3917 constraint->req = req;
3918 constraint->immediate_possible = 0;
3919 constraint->immediate_type = 0;
3922 static int is_memory_op(const ir_asm_constraint *constraint)
3924 ident *id = constraint->constraint;
3925 const char *str = get_id_str(id);
3928 for(c = str; *c != '\0'; ++c) {
3937 * generates code for a ASM node
3939 static ir_node *gen_ASM(ir_node *node)
3942 ir_graph *irg = current_ir_graph;
3943 ir_node *block = get_nodes_block(node);
3944 ir_node *new_block = be_transform_node(block);
3945 dbg_info *dbgi = get_irn_dbg_info(node);
3949 int n_out_constraints;
3951 const arch_register_req_t **out_reg_reqs;
3952 const arch_register_req_t **in_reg_reqs;
3953 ia32_asm_reg_t *register_map;
3954 unsigned reg_map_size = 0;
3955 struct obstack *obst;
3956 const ir_asm_constraint *in_constraints;
3957 const ir_asm_constraint *out_constraints;
3959 constraint_t parsed_constraint;
3961 arity = get_irn_arity(node);
3962 in = alloca(arity * sizeof(in[0]));
3963 memset(in, 0, arity * sizeof(in[0]));
3965 n_out_constraints = get_ASM_n_output_constraints(node);
3966 n_clobbers = get_ASM_n_clobbers(node);
3967 out_arity = n_out_constraints + n_clobbers;
3968 /* hack to keep space for mem proj */
3972 in_constraints = get_ASM_input_constraints(node);
3973 out_constraints = get_ASM_output_constraints(node);
3974 clobbers = get_ASM_clobbers(node);
3976 /* construct output constraints */
3977 obst = get_irg_obstack(irg);
3978 out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
3979 parsed_constraint.out_reqs = out_reg_reqs;
3980 parsed_constraint.n_outs = n_out_constraints;
3981 parsed_constraint.is_in = 0;
3983 for(i = 0; i < out_arity; ++i) {
3986 if(i < n_out_constraints) {
3987 const ir_asm_constraint *constraint = &out_constraints[i];
3988 c = get_id_str(constraint->constraint);
3989 parse_asm_constraint(i, &parsed_constraint, c);
3991 if(constraint->pos > reg_map_size)
3992 reg_map_size = constraint->pos;
3994 out_reg_reqs[i] = parsed_constraint.req;
3995 } else if(i < out_arity - 1) {
3996 ident *glob_id = clobbers [i - n_out_constraints];
3997 assert(glob_id != NULL);
3998 c = get_id_str(glob_id);
3999 parse_clobber(node, i, &parsed_constraint, c);
4001 out_reg_reqs[i+1] = parsed_constraint.req;
4005 out_reg_reqs[n_out_constraints] = &no_register_req;
4007 /* construct input constraints */
4008 in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
4009 parsed_constraint.is_in = 1;
4010 for(i = 0; i < arity; ++i) {
4011 const ir_asm_constraint *constraint = &in_constraints[i];
4012 ident *constr_id = constraint->constraint;
4013 const char *c = get_id_str(constr_id);
4015 parse_asm_constraint(i, &parsed_constraint, c);
4016 in_reg_reqs[i] = parsed_constraint.req;
4018 if(constraint->pos > reg_map_size)
4019 reg_map_size = constraint->pos;
4021 if(parsed_constraint.immediate_possible) {
4022 ir_node *pred = get_irn_n(node, i);
4023 char imm_type = parsed_constraint.immediate_type;
4024 ir_node *immediate = try_create_Immediate(pred, imm_type);
4026 if(immediate != NULL) {
4033 register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
4034 memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
4036 for(i = 0; i < n_out_constraints; ++i) {
4037 const ir_asm_constraint *constraint = &out_constraints[i];
4038 unsigned pos = constraint->pos;
4040 assert(pos < reg_map_size);
4041 register_map[pos].use_input = 0;
4042 register_map[pos].valid = 1;
4043 register_map[pos].memory = is_memory_op(constraint);
4044 register_map[pos].inout_pos = i;
4045 register_map[pos].mode = constraint->mode;
4048 /* transform inputs */
4049 for(i = 0; i < arity; ++i) {
4050 const ir_asm_constraint *constraint = &in_constraints[i];
4051 unsigned pos = constraint->pos;
4052 ir_node *pred = get_irn_n(node, i);
4053 ir_node *transformed;
4055 assert(pos < reg_map_size);
4056 register_map[pos].use_input = 1;
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;
4065 transformed = be_transform_node(pred);
4066 in[i] = transformed;
4069 new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
4070 get_ASM_text(node), register_map);
4072 set_ia32_out_req_all(new_node, out_reg_reqs);
4073 set_ia32_in_req_all(new_node, in_reg_reqs);
4075 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4081 * Transforms a FrameAddr into an ia32 Add.
4083 static ir_node *gen_be_FrameAddr(ir_node *node) {
4084 ir_node *block = be_transform_node(get_nodes_block(node));
4085 ir_node *op = be_get_FrameAddr_frame(node);
4086 ir_node *new_op = be_transform_node(op);
4087 ir_graph *irg = current_ir_graph;
4088 dbg_info *dbgi = get_irn_dbg_info(node);
4089 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4092 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
4093 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
4094 set_ia32_use_frame(new_node);
4096 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4102 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
4104 static ir_node *gen_be_Return(ir_node *node) {
4105 ir_graph *irg = current_ir_graph;
4106 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
4107 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
4108 ir_entity *ent = get_irg_entity(irg);
4109 ir_type *tp = get_entity_type(ent);
4114 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
4115 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
4118 int pn_ret_val, pn_ret_mem, arity, i;
4120 assert(ret_val != NULL);
4121 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4122 return be_duplicate_node(node);
4125 res_type = get_method_res_type(tp, 0);
4127 if (! is_Primitive_type(res_type)) {
4128 return be_duplicate_node(node);
4131 mode = get_type_mode(res_type);
4132 if (! mode_is_float(mode)) {
4133 return be_duplicate_node(node);
4136 assert(get_method_n_ress(tp) == 1);
4138 pn_ret_val = get_Proj_proj(ret_val);
4139 pn_ret_mem = get_Proj_proj(ret_mem);
4141 /* get the Barrier */
4142 barrier = get_Proj_pred(ret_val);
4144 /* get result input of the Barrier */
4145 ret_val = get_irn_n(barrier, pn_ret_val);
4146 new_ret_val = be_transform_node(ret_val);
4148 /* get memory input of the Barrier */
4149 ret_mem = get_irn_n(barrier, pn_ret_mem);
4150 new_ret_mem = be_transform_node(ret_mem);
4152 frame = get_irg_frame(irg);
4154 dbgi = get_irn_dbg_info(barrier);
4155 block = be_transform_node(get_nodes_block(barrier));
4157 noreg = ia32_new_NoReg_gp(env_cg);
4159 /* store xmm0 onto stack */
4160 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
4161 new_ret_mem, new_ret_val);
4162 set_ia32_ls_mode(sse_store, mode);
4163 set_ia32_op_type(sse_store, ia32_AddrModeD);
4164 set_ia32_use_frame(sse_store);
4166 /* load into x87 register */
4167 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
4168 set_ia32_op_type(fld, ia32_AddrModeS);
4169 set_ia32_use_frame(fld);
4171 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
4172 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
4174 /* create a new barrier */
4175 arity = get_irn_arity(barrier);
4176 in = alloca(arity * sizeof(in[0]));
4177 for (i = 0; i < arity; ++i) {
4180 if (i == pn_ret_val) {
4182 } else if (i == pn_ret_mem) {
4185 ir_node *in = get_irn_n(barrier, i);
4186 new_in = be_transform_node(in);
4191 new_barrier = new_ir_node(dbgi, irg, block,
4192 get_irn_op(barrier), get_irn_mode(barrier),
4194 copy_node_attr(barrier, new_barrier);
4195 be_duplicate_deps(barrier, new_barrier);
4196 be_set_transformed_node(barrier, new_barrier);
4197 mark_irn_visited(barrier);
4199 /* transform normally */
4200 return be_duplicate_node(node);
4204 * Transform a be_AddSP into an ia32_SubSP.
4206 static ir_node *gen_be_AddSP(ir_node *node)
4208 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4209 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4211 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
4215 * Transform a be_SubSP into an ia32_AddSP
4217 static ir_node *gen_be_SubSP(ir_node *node)
4219 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4220 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4222 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
4226 * This function just sets the register for the Unknown node
4227 * as this is not done during register allocation because Unknown
4228 * is an "ignore" node.
4230 static ir_node *gen_Unknown(ir_node *node) {
4231 ir_mode *mode = get_irn_mode(node);
4233 if (mode_is_float(mode)) {
4234 if (ia32_cg_config.use_sse2) {
4235 return ia32_new_Unknown_xmm(env_cg);
4237 /* Unknown nodes are buggy in x87 simulator, use zero for now... */
4238 ir_graph *irg = current_ir_graph;
4239 dbg_info *dbgi = get_irn_dbg_info(node);
4240 ir_node *block = get_irg_start_block(irg);
4241 ir_node *ret = new_rd_ia32_vfldz(dbgi, irg, block);
4243 /* Const Nodes before the initial IncSP are a bad idea, because
4244 * they could be spilled and we have no SP ready at that point yet.
4245 * So add a dependency to the initial frame pointer calculation to
4246 * avoid that situation.
4248 add_irn_dep(ret, get_irg_frame(irg));
4251 } else if (mode_needs_gp_reg(mode)) {
4252 return ia32_new_Unknown_gp(env_cg);
4254 panic("unsupported Unknown-Mode");
4260 * Change some phi modes
4262 static ir_node *gen_Phi(ir_node *node) {
4263 ir_node *block = be_transform_node(get_nodes_block(node));
4264 ir_graph *irg = current_ir_graph;
4265 dbg_info *dbgi = get_irn_dbg_info(node);
4266 ir_mode *mode = get_irn_mode(node);
4269 if(mode_needs_gp_reg(mode)) {
4270 /* we shouldn't have any 64bit stuff around anymore */
4271 assert(get_mode_size_bits(mode) <= 32);
4272 /* all integer operations are on 32bit registers now */
4274 } else if(mode_is_float(mode)) {
4275 if (ia32_cg_config.use_sse2) {
4282 /* phi nodes allow loops, so we use the old arguments for now
4283 * and fix this later */
4284 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4285 get_irn_in(node) + 1);
4286 copy_node_attr(node, phi);
4287 be_duplicate_deps(node, phi);
4289 be_set_transformed_node(node, phi);
4290 be_enqueue_preds(node);
4298 static ir_node *gen_IJmp(ir_node *node)
4300 ir_node *block = get_nodes_block(node);
4301 ir_node *new_block = be_transform_node(block);
4302 ir_graph *irg = current_ir_graph;
4303 dbg_info *dbgi = get_irn_dbg_info(node);
4304 ir_node *op = get_IJmp_target(node);
4306 ia32_address_mode_t am;
4307 ia32_address_t *addr = &am.addr;
4309 assert(get_irn_mode(op) == mode_P);
4311 match_arguments(&am, block, NULL, op, NULL,
4312 match_am | match_8bit_am | match_16bit_am |
4313 match_immediate | match_8bit | match_16bit);
4315 new_node = new_rd_ia32_IJmp(dbgi, irg, new_block, addr->base, addr->index,
4316 addr->mem, am.new_op2);
4317 set_am_attributes(new_node, &am);
4318 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4320 new_node = fix_mem_proj(new_node, &am);
4325 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4328 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4329 ir_node *val, ir_node *mem);
4332 * Transforms a lowered Load into a "real" one.
4334 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4336 ir_node *block = be_transform_node(get_nodes_block(node));
4337 ir_node *ptr = get_irn_n(node, 0);
4338 ir_node *new_ptr = be_transform_node(ptr);
4339 ir_node *mem = get_irn_n(node, 1);
4340 ir_node *new_mem = be_transform_node(mem);
4341 ir_graph *irg = current_ir_graph;
4342 dbg_info *dbgi = get_irn_dbg_info(node);
4343 ir_mode *mode = get_ia32_ls_mode(node);
4344 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4347 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4349 set_ia32_op_type(new_op, ia32_AddrModeS);
4350 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4351 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4352 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4353 if (is_ia32_am_sc_sign(node))
4354 set_ia32_am_sc_sign(new_op);
4355 set_ia32_ls_mode(new_op, mode);
4356 if (is_ia32_use_frame(node)) {
4357 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4358 set_ia32_use_frame(new_op);
4361 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4367 * Transforms a lowered Store into a "real" one.
4369 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4371 ir_node *block = be_transform_node(get_nodes_block(node));
4372 ir_node *ptr = get_irn_n(node, 0);
4373 ir_node *new_ptr = be_transform_node(ptr);
4374 ir_node *val = get_irn_n(node, 1);
4375 ir_node *new_val = be_transform_node(val);
4376 ir_node *mem = get_irn_n(node, 2);
4377 ir_node *new_mem = be_transform_node(mem);
4378 ir_graph *irg = current_ir_graph;
4379 dbg_info *dbgi = get_irn_dbg_info(node);
4380 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4381 ir_mode *mode = get_ia32_ls_mode(node);
4385 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4387 am_offs = get_ia32_am_offs_int(node);
4388 add_ia32_am_offs_int(new_op, am_offs);
4390 set_ia32_op_type(new_op, ia32_AddrModeD);
4391 set_ia32_ls_mode(new_op, mode);
4392 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4393 set_ia32_use_frame(new_op);
4395 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4400 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4402 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4403 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4405 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4406 match_immediate | match_mode_neutral);
4409 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4411 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4412 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4413 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4417 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4419 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4420 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4421 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4425 static ir_node *gen_ia32_l_Add(ir_node *node) {
4426 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4427 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4428 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4429 match_commutative | match_am | match_immediate |
4430 match_mode_neutral);
4432 if(is_Proj(lowered)) {
4433 lowered = get_Proj_pred(lowered);
4435 assert(is_ia32_Add(lowered));
4436 set_irn_mode(lowered, mode_T);
4442 static ir_node *gen_ia32_l_Adc(ir_node *node)
4444 return gen_binop_flags(node, new_rd_ia32_Adc,
4445 match_commutative | match_am | match_immediate |
4446 match_mode_neutral);
4450 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4452 * @param node The node to transform
4453 * @return the created ia32 vfild node
4455 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4456 return gen_lowered_Load(node, new_rd_ia32_vfild);
4460 * Transforms an ia32_l_Load into a "real" ia32_Load node
4462 * @param node The node to transform
4463 * @return the created ia32 Load node
4465 static ir_node *gen_ia32_l_Load(ir_node *node) {
4466 return gen_lowered_Load(node, new_rd_ia32_Load);
4470 * Transforms an ia32_l_Store into a "real" ia32_Store node
4472 * @param node The node to transform
4473 * @return the created ia32 Store node
4475 static ir_node *gen_ia32_l_Store(ir_node *node) {
4476 return gen_lowered_Store(node, new_rd_ia32_Store);
4480 * Transforms a l_vfist into a "real" vfist node.
4482 * @param node The node to transform
4483 * @return the created ia32 vfist node
4485 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4486 ir_node *block = be_transform_node(get_nodes_block(node));
4487 ir_node *ptr = get_irn_n(node, 0);
4488 ir_node *new_ptr = be_transform_node(ptr);
4489 ir_node *val = get_irn_n(node, 1);
4490 ir_node *new_val = be_transform_node(val);
4491 ir_node *mem = get_irn_n(node, 2);
4492 ir_node *new_mem = be_transform_node(mem);
4493 ir_graph *irg = current_ir_graph;
4494 dbg_info *dbgi = get_irn_dbg_info(node);
4495 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4496 ir_mode *mode = get_ia32_ls_mode(node);
4497 ir_node *memres, *fist;
4500 memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
4501 am_offs = get_ia32_am_offs_int(node);
4502 add_ia32_am_offs_int(fist, am_offs);
4504 set_ia32_op_type(fist, ia32_AddrModeD);
4505 set_ia32_ls_mode(fist, mode);
4506 set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
4507 set_ia32_use_frame(fist);
4509 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4515 * Transforms a l_MulS into a "real" MulS node.
4517 * @return the created ia32 Mul node
4519 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4520 ir_node *left = get_binop_left(node);
4521 ir_node *right = get_binop_right(node);
4523 return gen_binop(node, left, right, new_rd_ia32_Mul,
4524 match_commutative | match_am | match_mode_neutral);
4528 * Transforms a l_IMulS into a "real" IMul1OPS node.
4530 * @return the created ia32 IMul1OP node
4532 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4533 ir_node *left = get_binop_left(node);
4534 ir_node *right = get_binop_right(node);
4536 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4537 match_commutative | match_am | match_mode_neutral);
4540 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4541 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4542 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4543 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4544 match_am | match_immediate | match_mode_neutral);
4546 if(is_Proj(lowered)) {
4547 lowered = get_Proj_pred(lowered);
4549 assert(is_ia32_Sub(lowered));
4550 set_irn_mode(lowered, mode_T);
4556 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4557 return gen_binop_flags(node, new_rd_ia32_Sbb,
4558 match_am | match_immediate | match_mode_neutral);
4562 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4563 * op1 - target to be shifted
4564 * op2 - contains bits to be shifted into target
4566 * Only op3 can be an immediate.
4568 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4569 ir_node *low, ir_node *count)
4571 ir_node *block = get_nodes_block(node);
4572 ir_node *new_block = be_transform_node(block);
4573 ir_graph *irg = current_ir_graph;
4574 dbg_info *dbgi = get_irn_dbg_info(node);
4575 ir_node *new_high = be_transform_node(high);
4576 ir_node *new_low = be_transform_node(low);
4580 /* the shift amount can be any mode that is bigger than 5 bits, since all
4581 * other bits are ignored anyway */
4582 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4583 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4584 count = get_Conv_op(count);
4586 new_count = create_immediate_or_transform(count, 0);
4588 if (is_ia32_l_ShlD(node)) {
4589 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4592 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4595 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4600 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4602 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4603 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4604 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4605 return gen_lowered_64bit_shifts(node, high, low, count);
4608 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4610 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4611 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4612 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4613 return gen_lowered_64bit_shifts(node, high, low, count);
4616 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4617 ir_node *src_block = get_nodes_block(node);
4618 ir_node *block = be_transform_node(src_block);
4619 ir_graph *irg = current_ir_graph;
4620 dbg_info *dbgi = get_irn_dbg_info(node);
4621 ir_node *frame = get_irg_frame(irg);
4622 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4623 ir_node *nomem = new_NoMem();
4624 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4625 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4626 ir_node *new_val_low = be_transform_node(val_low);
4627 ir_node *new_val_high = be_transform_node(val_high);
4632 ir_node *store_high;
4634 if(!mode_is_signed(get_irn_mode(val_high))) {
4635 panic("unsigned long long -> float not supported yet (%+F)", node);
4639 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4641 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4643 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4644 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4646 set_ia32_use_frame(store_low);
4647 set_ia32_use_frame(store_high);
4648 set_ia32_op_type(store_low, ia32_AddrModeD);
4649 set_ia32_op_type(store_high, ia32_AddrModeD);
4650 set_ia32_ls_mode(store_low, mode_Iu);
4651 set_ia32_ls_mode(store_high, mode_Is);
4652 add_ia32_am_offs_int(store_high, 4);
4656 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4659 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4661 set_ia32_use_frame(fild);
4662 set_ia32_op_type(fild, ia32_AddrModeS);
4663 set_ia32_ls_mode(fild, mode_Ls);
4665 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4667 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4670 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4671 ir_node *src_block = get_nodes_block(node);
4672 ir_node *block = be_transform_node(src_block);
4673 ir_graph *irg = current_ir_graph;
4674 dbg_info *dbgi = get_irn_dbg_info(node);
4675 ir_node *frame = get_irg_frame(irg);
4676 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4677 ir_node *nomem = new_NoMem();
4678 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4679 ir_node *new_val = be_transform_node(val);
4680 ir_node *fist, *mem;
4682 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4683 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4684 set_ia32_use_frame(fist);
4685 set_ia32_op_type(fist, ia32_AddrModeD);
4686 set_ia32_ls_mode(fist, mode_Ls);
4692 * the BAD transformer.
4694 static ir_node *bad_transform(ir_node *node) {
4695 panic("No transform function for %+F available.\n", node);
4699 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4700 ir_graph *irg = current_ir_graph;
4701 ir_node *block = be_transform_node(get_nodes_block(node));
4702 ir_node *pred = get_Proj_pred(node);
4703 ir_node *new_pred = be_transform_node(pred);
4704 ir_node *frame = get_irg_frame(irg);
4705 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4706 dbg_info *dbgi = get_irn_dbg_info(node);
4707 long pn = get_Proj_proj(node);
4712 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4713 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4714 set_ia32_use_frame(load);
4715 set_ia32_op_type(load, ia32_AddrModeS);
4716 set_ia32_ls_mode(load, mode_Iu);
4717 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4718 * 32 bit from it with this particular load */
4719 attr = get_ia32_attr(load);
4720 attr->data.need_64bit_stackent = 1;
4722 if (pn == pn_ia32_l_FloattoLL_res_high) {
4723 add_ia32_am_offs_int(load, 4);
4725 assert(pn == pn_ia32_l_FloattoLL_res_low);
4728 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4734 * Transform the Projs of an AddSP.
4736 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4737 ir_node *block = be_transform_node(get_nodes_block(node));
4738 ir_node *pred = get_Proj_pred(node);
4739 ir_node *new_pred = be_transform_node(pred);
4740 ir_graph *irg = current_ir_graph;
4741 dbg_info *dbgi = get_irn_dbg_info(node);
4742 long proj = get_Proj_proj(node);
4744 if (proj == pn_be_AddSP_sp) {
4745 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4746 pn_ia32_SubSP_stack);
4747 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4749 } else if(proj == pn_be_AddSP_res) {
4750 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4751 pn_ia32_SubSP_addr);
4752 } else if (proj == pn_be_AddSP_M) {
4753 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4757 return new_rd_Unknown(irg, get_irn_mode(node));
4761 * Transform the Projs of a SubSP.
4763 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4764 ir_node *block = be_transform_node(get_nodes_block(node));
4765 ir_node *pred = get_Proj_pred(node);
4766 ir_node *new_pred = be_transform_node(pred);
4767 ir_graph *irg = current_ir_graph;
4768 dbg_info *dbgi = get_irn_dbg_info(node);
4769 long proj = get_Proj_proj(node);
4771 if (proj == pn_be_SubSP_sp) {
4772 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4773 pn_ia32_AddSP_stack);
4774 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4776 } else if (proj == pn_be_SubSP_M) {
4777 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4781 return new_rd_Unknown(irg, get_irn_mode(node));
4785 * Transform and renumber the Projs from a Load.
4787 static ir_node *gen_Proj_Load(ir_node *node) {
4789 ir_node *block = be_transform_node(get_nodes_block(node));
4790 ir_node *pred = get_Proj_pred(node);
4791 ir_graph *irg = current_ir_graph;
4792 dbg_info *dbgi = get_irn_dbg_info(node);
4793 long proj = get_Proj_proj(node);
4796 /* loads might be part of source address mode matches, so we don't
4797 transform the ProjMs yet (with the exception of loads whose result is
4800 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4803 assert(pn_ia32_Load_M == 1); /* convention: mem-result of Source-AM
4805 /* this is needed, because sometimes we have loops that are only
4806 reachable through the ProjM */
4807 be_enqueue_preds(node);
4808 /* do it in 2 steps, to silence firm verifier */
4809 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4810 set_Proj_proj(res, pn_ia32_Load_M);
4814 /* renumber the proj */
4815 new_pred = be_transform_node(pred);
4816 if (is_ia32_Load(new_pred)) {
4819 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4821 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4822 case pn_Load_X_regular:
4823 return new_rd_Jmp(dbgi, irg, block);
4824 case pn_Load_X_except:
4825 /* This Load might raise an exception. Mark it. */
4826 set_ia32_exc_label(new_pred, 1);
4827 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4831 } else if (is_ia32_Conv_I2I(new_pred) ||
4832 is_ia32_Conv_I2I8Bit(new_pred)) {
4833 set_irn_mode(new_pred, mode_T);
4834 if (proj == pn_Load_res) {
4835 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4836 } else if (proj == pn_Load_M) {
4837 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4839 } else if (is_ia32_xLoad(new_pred)) {
4842 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4844 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4845 case pn_Load_X_regular:
4846 return new_rd_Jmp(dbgi, irg, block);
4847 case pn_Load_X_except:
4848 /* This Load might raise an exception. Mark it. */
4849 set_ia32_exc_label(new_pred, 1);
4850 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4854 } else if (is_ia32_vfld(new_pred)) {
4857 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4859 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4860 case pn_Load_X_regular:
4861 return new_rd_Jmp(dbgi, irg, block);
4862 case pn_Load_X_except:
4863 /* This Load might raise an exception. Mark it. */
4864 set_ia32_exc_label(new_pred, 1);
4865 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4870 /* can happen for ProJMs when source address mode happened for the
4873 /* however it should not be the result proj, as that would mean the
4874 load had multiple users and should not have been used for
4876 if (proj != pn_Load_M) {
4877 panic("internal error: transformed node not a Load");
4879 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4883 return new_rd_Unknown(irg, get_irn_mode(node));
4887 * Transform and renumber the Projs from a DivMod like instruction.
4889 static ir_node *gen_Proj_DivMod(ir_node *node) {
4890 ir_node *block = be_transform_node(get_nodes_block(node));
4891 ir_node *pred = get_Proj_pred(node);
4892 ir_node *new_pred = be_transform_node(pred);
4893 ir_graph *irg = current_ir_graph;
4894 dbg_info *dbgi = get_irn_dbg_info(node);
4895 ir_mode *mode = get_irn_mode(node);
4896 long proj = get_Proj_proj(node);
4898 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4900 switch (get_irn_opcode(pred)) {
4904 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4906 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4907 case pn_Div_X_regular:
4908 return new_rd_Jmp(dbgi, irg, block);
4909 case pn_Div_X_except:
4910 set_ia32_exc_label(new_pred, 1);
4911 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4919 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4921 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4922 case pn_Mod_X_except:
4923 set_ia32_exc_label(new_pred, 1);
4924 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4932 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4933 case pn_DivMod_res_div:
4934 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4935 case pn_DivMod_res_mod:
4936 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4937 case pn_DivMod_X_regular:
4938 return new_rd_Jmp(dbgi, irg, block);
4939 case pn_DivMod_X_except:
4940 set_ia32_exc_label(new_pred, 1);
4941 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4951 return new_rd_Unknown(irg, mode);
4955 * Transform and renumber the Projs from a CopyB.
4957 static ir_node *gen_Proj_CopyB(ir_node *node) {
4958 ir_node *block = be_transform_node(get_nodes_block(node));
4959 ir_node *pred = get_Proj_pred(node);
4960 ir_node *new_pred = be_transform_node(pred);
4961 ir_graph *irg = current_ir_graph;
4962 dbg_info *dbgi = get_irn_dbg_info(node);
4963 ir_mode *mode = get_irn_mode(node);
4964 long proj = get_Proj_proj(node);
4967 case pn_CopyB_M_regular:
4968 if (is_ia32_CopyB_i(new_pred)) {
4969 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4970 } else if (is_ia32_CopyB(new_pred)) {
4971 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4979 return new_rd_Unknown(irg, mode);
4983 * Transform and renumber the Projs from a Quot.
4985 static ir_node *gen_Proj_Quot(ir_node *node) {
4986 ir_node *block = be_transform_node(get_nodes_block(node));
4987 ir_node *pred = get_Proj_pred(node);
4988 ir_node *new_pred = be_transform_node(pred);
4989 ir_graph *irg = current_ir_graph;
4990 dbg_info *dbgi = get_irn_dbg_info(node);
4991 ir_mode *mode = get_irn_mode(node);
4992 long proj = get_Proj_proj(node);
4996 if (is_ia32_xDiv(new_pred)) {
4997 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4998 } else if (is_ia32_vfdiv(new_pred)) {
4999 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
5003 if (is_ia32_xDiv(new_pred)) {
5004 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
5005 } else if (is_ia32_vfdiv(new_pred)) {
5006 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
5009 case pn_Quot_X_regular:
5010 case pn_Quot_X_except:
5016 return new_rd_Unknown(irg, mode);
5020 * Transform the Thread Local Storage Proj.
5022 static ir_node *gen_Proj_tls(ir_node *node) {
5023 ir_node *block = be_transform_node(get_nodes_block(node));
5024 ir_graph *irg = current_ir_graph;
5025 dbg_info *dbgi = NULL;
5026 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
5031 static ir_node *gen_be_Call(ir_node *node) {
5032 ir_node *res = be_duplicate_node(node);
5033 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5038 static ir_node *gen_be_IncSP(ir_node *node) {
5039 ir_node *res = be_duplicate_node(node);
5040 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5046 * Transform the Projs from a be_Call.
5048 static ir_node *gen_Proj_be_Call(ir_node *node) {
5049 ir_node *block = be_transform_node(get_nodes_block(node));
5050 ir_node *call = get_Proj_pred(node);
5051 ir_node *new_call = be_transform_node(call);
5052 ir_graph *irg = current_ir_graph;
5053 dbg_info *dbgi = get_irn_dbg_info(node);
5054 ir_type *method_type = be_Call_get_type(call);
5055 int n_res = get_method_n_ress(method_type);
5056 long proj = get_Proj_proj(node);
5057 ir_mode *mode = get_irn_mode(node);
5059 const arch_register_class_t *cls;
5061 /* The following is kinda tricky: If we're using SSE, then we have to
5062 * move the result value of the call in floating point registers to an
5063 * xmm register, we therefore construct a GetST0 -> xLoad sequence
5064 * after the call, we have to make sure to correctly make the
5065 * MemProj and the result Proj use these 2 nodes
5067 if (proj == pn_be_Call_M_regular) {
5068 // get new node for result, are we doing the sse load/store hack?
5069 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5070 ir_node *call_res_new;
5071 ir_node *call_res_pred = NULL;
5073 if (call_res != NULL) {
5074 call_res_new = be_transform_node(call_res);
5075 call_res_pred = get_Proj_pred(call_res_new);
5078 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
5079 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5080 pn_be_Call_M_regular);
5082 assert(is_ia32_xLoad(call_res_pred));
5083 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5087 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5088 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5090 ir_node *frame = get_irg_frame(irg);
5091 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
5093 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5096 /* in case there is no memory output: create one to serialize the copy
5098 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5099 pn_be_Call_M_regular);
5100 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5101 pn_be_Call_first_res);
5103 /* store st(0) onto stack */
5104 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
5106 set_ia32_op_type(fstp, ia32_AddrModeD);
5107 set_ia32_use_frame(fstp);
5109 /* load into SSE register */
5110 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5112 set_ia32_op_type(sse_load, ia32_AddrModeS);
5113 set_ia32_use_frame(sse_load);
5115 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5121 /* transform call modes */
5122 if (mode_is_data(mode)) {
5123 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5127 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5131 * Transform the Projs from a Cmp.
5133 static ir_node *gen_Proj_Cmp(ir_node *node)
5135 /* this probably means not all mode_b nodes were lowered... */
5136 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5141 * Transform and potentially renumber Proj nodes.
5143 static ir_node *gen_Proj(ir_node *node) {
5144 ir_node *pred = get_Proj_pred(node);
5145 if (is_Store(pred)) {
5146 long proj = get_Proj_proj(node);
5147 if (proj == pn_Store_M) {
5148 return be_transform_node(pred);
5151 return new_r_Bad(current_ir_graph);
5153 } else if (is_Load(pred)) {
5154 return gen_Proj_Load(node);
5155 } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
5156 return gen_Proj_DivMod(node);
5157 } else if (is_CopyB(pred)) {
5158 return gen_Proj_CopyB(node);
5159 } else if (is_Quot(pred)) {
5160 return gen_Proj_Quot(node);
5161 } else if (be_is_SubSP(pred)) {
5162 return gen_Proj_be_SubSP(node);
5163 } else if (be_is_AddSP(pred)) {
5164 return gen_Proj_be_AddSP(node);
5165 } else if (be_is_Call(pred)) {
5166 return gen_Proj_be_Call(node);
5167 } else if (is_Cmp(pred)) {
5168 return gen_Proj_Cmp(node);
5169 } else if (get_irn_op(pred) == op_Start) {
5170 long proj = get_Proj_proj(node);
5171 if (proj == pn_Start_X_initial_exec) {
5172 ir_node *block = get_nodes_block(pred);
5173 dbg_info *dbgi = get_irn_dbg_info(node);
5176 /* we exchange the ProjX with a jump */
5177 block = be_transform_node(block);
5178 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
5181 if (node == be_get_old_anchor(anchor_tls)) {
5182 return gen_Proj_tls(node);
5184 } else if (is_ia32_l_FloattoLL(pred)) {
5185 return gen_Proj_l_FloattoLL(node);
5187 } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5191 ir_mode *mode = get_irn_mode(node);
5192 if (mode_needs_gp_reg(mode)) {
5193 ir_node *new_pred = be_transform_node(pred);
5194 ir_node *block = be_transform_node(get_nodes_block(node));
5195 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5196 mode_Iu, get_Proj_proj(node));
5197 #ifdef DEBUG_libfirm
5198 new_proj->node_nr = node->node_nr;
5204 return be_duplicate_node(node);
5208 * Enters all transform functions into the generic pointer
5210 static void register_transformers(void)
5214 /* first clear the generic function pointer for all ops */
5215 clear_irp_opcodes_generic_func();
5217 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5218 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5256 /* transform ops from intrinsic lowering */
5272 GEN(ia32_l_LLtoFloat);
5273 GEN(ia32_l_FloattoLL);
5279 /* we should never see these nodes */
5294 /* handle generic backend nodes */
5303 op_Mulh = get_op_Mulh();
5312 * Pre-transform all unknown and noreg nodes.
5314 static void ia32_pretransform_node(void *arch_cg) {
5315 ia32_code_gen_t *cg = arch_cg;
5317 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5318 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5319 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5320 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5321 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5322 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5327 * Walker, checks if all ia32 nodes producing more than one result have
5328 * its Projs, other wise creates new projs and keep them using a be_Keep node.
5330 static void add_missing_keep_walker(ir_node *node, void *data)
5333 unsigned found_projs = 0;
5334 const ir_edge_t *edge;
5335 ir_mode *mode = get_irn_mode(node);
5340 if(!is_ia32_irn(node))
5343 n_outs = get_ia32_n_res(node);
5346 if(is_ia32_SwitchJmp(node))
5349 assert(n_outs < (int) sizeof(unsigned) * 8);
5350 foreach_out_edge(node, edge) {
5351 ir_node *proj = get_edge_src_irn(edge);
5352 int pn = get_Proj_proj(proj);
5354 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
5355 found_projs |= 1 << pn;
5359 /* are keeps missing? */
5361 for(i = 0; i < n_outs; ++i) {
5364 const arch_register_req_t *req;
5365 const arch_register_class_t *class;
5367 if(found_projs & (1 << i)) {
5371 req = get_ia32_out_req(node, i);
5376 if(class == &ia32_reg_classes[CLASS_ia32_flags]) {
5380 block = get_nodes_block(node);
5381 in[0] = new_r_Proj(current_ir_graph, block, node,
5382 arch_register_class_mode(class), i);
5383 if(last_keep != NULL) {
5384 be_Keep_add_node(last_keep, class, in[0]);
5386 last_keep = be_new_Keep(class, current_ir_graph, block, 1, in);
5387 if(sched_is_scheduled(node)) {
5388 sched_add_after(node, last_keep);
5395 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5398 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5400 ir_graph *irg = be_get_birg_irg(cg->birg);
5401 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5404 /* do the transformation */
5405 void ia32_transform_graph(ia32_code_gen_t *cg) {
5407 ir_graph *irg = cg->irg;
5409 register_transformers();
5411 initial_fpcw = NULL;
5413 BE_TIMER_PUSH(t_heights);
5414 heights = heights_new(irg);
5415 BE_TIMER_POP(t_heights);
5416 ia32_calculate_non_address_mode_nodes(cg->birg);
5418 /* the transform phase is not safe for CSE (yet) because several nodes get
5419 * attributes set after their creation */
5420 cse_last = get_opt_cse();
5423 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5425 set_opt_cse(cse_last);
5427 ia32_free_non_address_mode_nodes();
5428 heights_free(heights);
5432 void ia32_init_transform(void)
5434 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");