2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
35 #include "irgraph_t.h"
40 #include "iredges_t.h"
52 #include "../benode_t.h"
53 #include "../besched.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
60 #include "bearch_ia32_t.h"
61 #include "ia32_nodes_attr.h"
62 #include "ia32_transform.h"
63 #include "ia32_new_nodes.h"
64 #include "ia32_map_regs.h"
65 #include "ia32_dbg_stat.h"
66 #include "ia32_optimize.h"
67 #include "ia32_util.h"
68 #include "ia32_address_mode.h"
69 #include "ia32_architecture.h"
71 #include "gen_ia32_regalloc_if.h"
73 #define SFP_SIGN "0x80000000"
74 #define DFP_SIGN "0x8000000000000000"
75 #define SFP_ABS "0x7FFFFFFF"
76 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
77 #define DFP_INTMAX "9223372036854775807"
79 #define TP_SFP_SIGN "ia32_sfp_sign"
80 #define TP_DFP_SIGN "ia32_dfp_sign"
81 #define TP_SFP_ABS "ia32_sfp_abs"
82 #define TP_DFP_ABS "ia32_dfp_abs"
83 #define TP_INT_MAX "ia32_int_max"
85 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
86 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
87 #define ENT_SFP_ABS "IA32_SFP_ABS"
88 #define ENT_DFP_ABS "IA32_DFP_ABS"
89 #define ENT_INT_MAX "IA32_INT_MAX"
91 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
92 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
94 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
96 /** hold the current code generator during transformation */
97 static ia32_code_gen_t *env_cg = NULL;
98 static ir_node *initial_fpcw = NULL;
99 static heights_t *heights = NULL;
101 extern ir_op *get_op_Mulh(void);
103 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
104 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
105 ir_node *op1, ir_node *op2);
107 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
108 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
109 ir_node *op1, ir_node *op2, ir_node *flags);
111 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
112 ir_node *block, ir_node *op1, ir_node *op2);
114 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
115 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
118 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
119 ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
121 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
122 ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
123 ir_node *op1, ir_node *op2, ir_node *fpcw);
125 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
126 ir_node *block, ir_node *op);
128 static ir_node *try_create_Immediate(ir_node *node,
129 char immediate_constraint_type);
131 static ir_node *create_immediate_or_transform(ir_node *node,
132 char immediate_constraint_type);
134 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
135 dbg_info *dbgi, ir_node *block,
136 ir_node *op, ir_node *orig_node);
139 * Return true if a mode can be stored in the GP register set
141 static INLINE int mode_needs_gp_reg(ir_mode *mode) {
142 if(mode == mode_fpcw)
144 if(get_mode_size_bits(mode) > 32)
146 return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b;
150 * creates a unique ident by adding a number to a tag
152 * @param tag the tag string, must contain a %d if a number
155 static ident *unique_id(const char *tag)
157 static unsigned id = 0;
160 snprintf(str, sizeof(str), tag, ++id);
161 return new_id_from_str(str);
165 * Get a primitive type for a mode.
167 static ir_type *get_prim_type(pmap *types, ir_mode *mode)
169 pmap_entry *e = pmap_find(types, mode);
174 snprintf(buf, sizeof(buf), "prim_type_%s", get_mode_name(mode));
175 res = new_type_primitive(new_id_from_str(buf), mode);
176 set_type_alignment_bytes(res, 16);
177 pmap_insert(types, mode, res);
185 * Creates an immediate.
187 * @param symconst if set, create a SymConst immediate
188 * @param symconst_sign sign for the symconst
189 * @param val integer value for the immediate
191 static ir_node *create_Immediate(ir_entity *symconst, int symconst_sign, long val)
193 ir_graph *irg = current_ir_graph;
194 ir_node *start_block = get_irg_start_block(irg);
195 ir_node *immediate = new_rd_ia32_Immediate(NULL, irg, start_block,
196 symconst, symconst_sign, val);
197 arch_set_irn_register(env_cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]);
203 * Get an atomic entity that is initialized with a tarval forming
206 * @param cnst the node representing the constant
208 static ir_entity *create_float_const_entity(ir_node *cnst)
210 ia32_isa_t *isa = env_cg->isa;
211 tarval *key = get_Const_tarval(cnst);
212 pmap_entry *e = pmap_find(isa->tv_ent, key);
218 ir_mode *mode = get_tarval_mode(tv);
221 if (! ia32_cg_config.use_sse2) {
222 /* try to reduce the mode to produce smaller sized entities */
223 if (mode != mode_F) {
224 if (tarval_ieee754_can_conv_lossless(tv, mode_F)) {
226 tv = tarval_convert_to(tv, mode);
227 } else if (mode != mode_D) {
228 if (tarval_ieee754_can_conv_lossless(tv, mode_D)) {
230 tv = tarval_convert_to(tv, mode);
236 if (mode == get_irn_mode(cnst)) {
237 /* mode was not changed */
238 tp = get_Const_type(cnst);
239 if (tp == firm_unknown_type)
240 tp = get_prim_type(isa->types, mode);
242 tp = get_prim_type(isa->types, mode);
244 res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);
246 set_entity_ld_ident(res, get_entity_ident(res));
247 set_entity_visibility(res, visibility_local);
248 set_entity_variability(res, variability_constant);
249 set_entity_allocation(res, allocation_static);
251 /* we create a new entity here: It's initialization must resist on the
253 rem = current_ir_graph;
254 current_ir_graph = get_const_code_irg();
255 set_atomic_ent_value(res, new_Const_type(tv, tp));
256 current_ir_graph = rem;
258 pmap_insert(isa->tv_ent, key, res);
266 static int is_Const_0(ir_node *node) {
267 return is_Const(node) && is_Const_null(node);
270 static int is_Const_1(ir_node *node) {
271 return is_Const(node) && is_Const_one(node);
274 static int is_Const_Minus_1(ir_node *node) {
275 return is_Const(node) && is_Const_all_one(node);
279 * returns true if constant can be created with a simple float command
281 static int is_simple_x87_Const(ir_node *node)
283 tarval *tv = get_Const_tarval(node);
284 if (tarval_is_null(tv) || tarval_is_one(tv))
287 /* TODO: match all the other float constants */
292 * returns true if constant can be created with a simple float command
294 static int is_simple_sse_Const(ir_node *node)
296 tarval *tv = get_Const_tarval(node);
297 ir_mode *mode = get_tarval_mode(tv);
302 if (tarval_is_null(tv) || tarval_is_one(tv))
305 if (mode == mode_D) {
306 unsigned val = get_tarval_sub_bits(tv, 0) |
307 (get_tarval_sub_bits(tv, 1) << 8) |
308 (get_tarval_sub_bits(tv, 2) << 16) |
309 (get_tarval_sub_bits(tv, 3) << 24);
311 /* lower 32bit are zero, really a 32bit constant */
315 /* TODO: match all the other float constants */
320 * Transforms a Const.
322 static ir_node *gen_Const(ir_node *node) {
323 ir_graph *irg = current_ir_graph;
324 ir_node *old_block = get_nodes_block(node);
325 ir_node *block = be_transform_node(old_block);
326 dbg_info *dbgi = get_irn_dbg_info(node);
327 ir_mode *mode = get_irn_mode(node);
329 assert(is_Const(node));
331 if (mode_is_float(mode)) {
333 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
334 ir_node *nomem = new_NoMem();
338 if (ia32_cg_config.use_sse2) {
339 tarval *tv = get_Const_tarval(node);
340 if (tarval_is_null(tv)) {
341 load = new_rd_ia32_xZero(dbgi, irg, block);
342 set_ia32_ls_mode(load, mode);
344 } else if (tarval_is_one(tv)) {
345 int cnst = mode == mode_F ? 26 : 55;
346 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
347 ir_node *imm2 = create_Immediate(NULL, 0, 2);
348 ir_node *pslld, *psrld;
350 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
351 set_ia32_ls_mode(load, mode);
352 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
353 set_ia32_ls_mode(pslld, mode);
354 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
355 set_ia32_ls_mode(psrld, mode);
357 } else if (mode == mode_F) {
358 /* we can place any 32bit constant by using a movd gp, sse */
359 unsigned val = get_tarval_sub_bits(tv, 0) |
360 (get_tarval_sub_bits(tv, 1) << 8) |
361 (get_tarval_sub_bits(tv, 2) << 16) |
362 (get_tarval_sub_bits(tv, 3) << 24);
363 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
364 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
365 set_ia32_ls_mode(load, mode);
368 if (mode == mode_D) {
369 unsigned val = get_tarval_sub_bits(tv, 0) |
370 (get_tarval_sub_bits(tv, 1) << 8) |
371 (get_tarval_sub_bits(tv, 2) << 16) |
372 (get_tarval_sub_bits(tv, 3) << 24);
374 ir_node *imm32 = create_Immediate(NULL, 0, 32);
375 ir_node *cnst, *psllq;
377 /* fine, lower 32bit are zero, produce 32bit value */
378 val = get_tarval_sub_bits(tv, 4) |
379 (get_tarval_sub_bits(tv, 5) << 8) |
380 (get_tarval_sub_bits(tv, 6) << 16) |
381 (get_tarval_sub_bits(tv, 7) << 24);
382 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
383 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
384 set_ia32_ls_mode(load, mode);
385 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
386 set_ia32_ls_mode(psllq, mode);
391 floatent = create_float_const_entity(node);
393 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
395 set_ia32_op_type(load, ia32_AddrModeS);
396 set_ia32_am_sc(load, floatent);
397 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
398 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
401 if (is_Const_null(node)) {
402 load = new_rd_ia32_vfldz(dbgi, irg, block);
404 set_ia32_ls_mode(load, mode);
405 } else if (is_Const_one(node)) {
406 load = new_rd_ia32_vfld1(dbgi, irg, block);
408 set_ia32_ls_mode(load, mode);
410 floatent = create_float_const_entity(node);
412 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
413 set_ia32_op_type(load, ia32_AddrModeS);
414 set_ia32_am_sc(load, floatent);
415 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
416 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
417 /* take the mode from the entity */
418 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
422 /* Const Nodes before the initial IncSP are a bad idea, because
423 * they could be spilled and we have no SP ready at that point yet.
424 * So add a dependency to the initial frame pointer calculation to
425 * avoid that situation.
427 if (get_irg_start_block(irg) == block) {
428 add_irn_dep(load, get_irg_frame(irg));
431 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
433 } else { /* non-float mode */
435 tarval *tv = get_Const_tarval(node);
438 tv = tarval_convert_to(tv, mode_Iu);
440 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
442 panic("couldn't convert constant tarval (%+F)", node);
444 val = get_tarval_long(tv);
446 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
447 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
450 if (get_irg_start_block(irg) == block) {
451 add_irn_dep(cnst, get_irg_frame(irg));
459 * Transforms a SymConst.
461 static ir_node *gen_SymConst(ir_node *node) {
462 ir_graph *irg = current_ir_graph;
463 ir_node *old_block = get_nodes_block(node);
464 ir_node *block = be_transform_node(old_block);
465 dbg_info *dbgi = get_irn_dbg_info(node);
466 ir_mode *mode = get_irn_mode(node);
469 if (mode_is_float(mode)) {
470 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
471 ir_node *nomem = new_NoMem();
473 if (ia32_cg_config.use_sse2)
474 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
476 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
477 set_ia32_am_sc(cnst, get_SymConst_entity(node));
478 set_ia32_use_frame(cnst);
482 if(get_SymConst_kind(node) != symconst_addr_ent) {
483 panic("backend only support symconst_addr_ent (at %+F)", node);
485 entity = get_SymConst_entity(node);
486 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
489 /* Const Nodes before the initial IncSP are a bad idea, because
490 * they could be spilled and we have no SP ready at that point yet
492 if (get_irg_start_block(irg) == block) {
493 add_irn_dep(cnst, get_irg_frame(irg));
496 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
501 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
502 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
503 static const struct {
505 const char *ent_name;
506 const char *cnst_str;
509 } names [ia32_known_const_max] = {
510 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
511 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
512 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
513 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
514 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
516 static ir_entity *ent_cache[ia32_known_const_max];
518 const char *tp_name, *ent_name, *cnst_str;
526 ent_name = names[kct].ent_name;
527 if (! ent_cache[kct]) {
528 tp_name = names[kct].tp_name;
529 cnst_str = names[kct].cnst_str;
531 switch (names[kct].mode) {
532 case 0: mode = mode_Iu; break;
533 case 1: mode = mode_Lu; break;
534 default: mode = mode_F; break;
536 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
537 tp = new_type_primitive(new_id_from_str(tp_name), mode);
538 /* set the specified alignment */
539 set_type_alignment_bytes(tp, names[kct].align);
541 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
543 set_entity_ld_ident(ent, get_entity_ident(ent));
544 set_entity_visibility(ent, visibility_local);
545 set_entity_variability(ent, variability_constant);
546 set_entity_allocation(ent, allocation_static);
548 /* we create a new entity here: It's initialization must resist on the
550 rem = current_ir_graph;
551 current_ir_graph = get_const_code_irg();
552 cnst = new_Const(mode, tv);
553 current_ir_graph = rem;
555 set_atomic_ent_value(ent, cnst);
557 /* cache the entry */
558 ent_cache[kct] = ent;
561 return ent_cache[kct];
566 * Prints the old node name on cg obst and returns a pointer to it.
568 const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
569 ia32_isa_t *isa = (ia32_isa_t*) cg->arch_env;
571 lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
572 obstack_1grow(isa->name_obst, 0);
573 return obstack_finish(isa->name_obst);
578 * return true if the node is a Proj(Load) and could be used in source address
579 * mode for another node. Will return only true if the @p other node is not
580 * dependent on the memory of the Load (for binary operations use the other
581 * input here, for unary operations use NULL).
583 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
584 ir_node *other, ir_node *other2, match_flags_t flags)
589 /* float constants are always available */
590 if (is_Const(node)) {
591 ir_mode *mode = get_irn_mode(node);
592 if (mode_is_float(mode)) {
593 if (ia32_cg_config.use_sse2) {
594 if (is_simple_sse_Const(node))
597 if (is_simple_x87_Const(node))
600 if (get_irn_n_edges(node) > 1)
608 load = get_Proj_pred(node);
609 pn = get_Proj_proj(node);
610 if (!is_Load(load) || pn != pn_Load_res)
612 if (get_nodes_block(load) != block)
614 /* we only use address mode if we're the only user of the load */
615 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
617 /* in some edge cases with address mode we might reach the load normally
618 * and through some AM sequence, if it is already materialized then we
619 * can't create an AM node from it */
620 if (be_is_transformed(node))
623 /* don't do AM if other node inputs depend on the load (via mem-proj) */
624 if (other != NULL && get_nodes_block(other) == block &&
625 heights_reachable_in_block(heights, other, load))
627 if (other2 != NULL && get_nodes_block(other2) == block &&
628 heights_reachable_in_block(heights, other2, load))
634 typedef struct ia32_address_mode_t ia32_address_mode_t;
635 struct ia32_address_mode_t {
639 ia32_op_type_t op_type;
643 unsigned commutative : 1;
644 unsigned ins_permuted : 1;
647 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
651 /* construct load address */
652 memset(addr, 0, sizeof(addr[0]));
653 ia32_create_address_mode(addr, ptr, /*force=*/0);
655 noreg_gp = ia32_new_NoReg_gp(env_cg);
656 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
657 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
658 addr->mem = be_transform_node(mem);
661 static void build_address(ia32_address_mode_t *am, ir_node *node)
663 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
664 ia32_address_t *addr = &am->addr;
670 if (is_Const(node)) {
671 ir_entity *entity = create_float_const_entity(node);
672 addr->base = noreg_gp;
673 addr->index = noreg_gp;
674 addr->mem = new_NoMem();
675 addr->symconst_ent = entity;
677 am->ls_mode = get_type_mode(get_entity_type(entity));
678 am->pinned = op_pin_state_floats;
682 load = get_Proj_pred(node);
683 ptr = get_Load_ptr(load);
684 mem = get_Load_mem(load);
685 new_mem = be_transform_node(mem);
686 am->pinned = get_irn_pinned(load);
687 am->ls_mode = get_Load_mode(load);
688 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
690 /* construct load address */
691 ia32_create_address_mode(addr, ptr, /*force=*/0);
693 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
694 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
698 static void set_address(ir_node *node, const ia32_address_t *addr)
700 set_ia32_am_scale(node, addr->scale);
701 set_ia32_am_sc(node, addr->symconst_ent);
702 set_ia32_am_offs_int(node, addr->offset);
703 if(addr->symconst_sign)
704 set_ia32_am_sc_sign(node);
706 set_ia32_use_frame(node);
707 set_ia32_frame_ent(node, addr->frame_entity);
711 * Apply attributes of a given address mode to a node.
713 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
715 set_address(node, &am->addr);
717 set_ia32_op_type(node, am->op_type);
718 set_ia32_ls_mode(node, am->ls_mode);
719 if (am->pinned == op_pin_state_pinned) {
720 set_irn_pinned(node, am->pinned);
723 set_ia32_commutative(node);
727 * Check, if a given node is a Down-Conv, ie. a integer Conv
728 * from a mode with a mode with more bits to a mode with lesser bits.
729 * Moreover, we return only true if the node has not more than 1 user.
731 * @param node the node
732 * @return non-zero if node is a Down-Conv
734 static int is_downconv(const ir_node *node)
742 /* we only want to skip the conv when we're the only user
743 * (not optimal but for now...)
745 if(get_irn_n_edges(node) > 1)
748 src_mode = get_irn_mode(get_Conv_op(node));
749 dest_mode = get_irn_mode(node);
750 return mode_needs_gp_reg(src_mode)
751 && mode_needs_gp_reg(dest_mode)
752 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
755 /* Skip all Down-Conv's on a given node and return the resulting node. */
756 ir_node *ia32_skip_downconv(ir_node *node) {
757 while (is_downconv(node))
758 node = get_Conv_op(node);
763 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
765 ir_mode *mode = get_irn_mode(node);
770 if(mode_is_signed(mode)) {
775 block = get_nodes_block(node);
776 dbgi = get_irn_dbg_info(node);
778 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
782 * matches operands of a node into ia32 addressing/operand modes. This covers
783 * usage of source address mode, immediates, operations with non 32-bit modes,
785 * The resulting data is filled into the @p am struct. block is the block
786 * of the node whose arguments are matched. op1, op2 are the first and second
787 * input that are matched (op1 may be NULL). other_op is another unrelated
788 * input that is not matched! but which is needed sometimes to check if AM
789 * for op1/op2 is legal.
790 * @p flags describes the supported modes of the operation in detail.
792 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
793 ir_node *op1, ir_node *op2, ir_node *other_op,
796 ia32_address_t *addr = &am->addr;
797 ir_mode *mode = get_irn_mode(op2);
798 int mode_bits = get_mode_size_bits(mode);
799 ir_node *noreg_gp, *new_op1, *new_op2;
801 unsigned commutative;
802 int use_am_and_immediates;
805 memset(am, 0, sizeof(am[0]));
807 commutative = (flags & match_commutative) != 0;
808 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
809 use_am = (flags & match_am) != 0;
810 use_immediate = (flags & match_immediate) != 0;
811 assert(!use_am_and_immediates || use_immediate);
814 assert(!commutative || op1 != NULL);
815 assert(use_am || !(flags & match_8bit_am));
816 assert(use_am || !(flags & match_16bit_am));
818 if (mode_bits == 8) {
819 if (!(flags & match_8bit_am))
821 /* we don't automatically add upconvs yet */
822 assert((flags & match_mode_neutral) || (flags & match_8bit));
823 } else if (mode_bits == 16) {
824 if (!(flags & match_16bit_am))
826 /* we don't automatically add upconvs yet */
827 assert((flags & match_mode_neutral) || (flags & match_16bit));
830 /* we can simply skip downconvs for mode neutral nodes: the upper bits
831 * can be random for these operations */
832 if (flags & match_mode_neutral) {
833 op2 = ia32_skip_downconv(op2);
835 op1 = ia32_skip_downconv(op1);
839 /* match immediates. firm nodes are normalized: constants are always on the
842 if (!(flags & match_try_am) && use_immediate) {
843 new_op2 = try_create_Immediate(op2, 0);
846 noreg_gp = ia32_new_NoReg_gp(env_cg);
847 if (new_op2 == NULL &&
848 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
849 build_address(am, op2);
850 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
851 if (mode_is_float(mode)) {
852 new_op2 = ia32_new_NoReg_vfp(env_cg);
856 am->op_type = ia32_AddrModeS;
857 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
859 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
861 build_address(am, op1);
863 if (mode_is_float(mode)) {
864 noreg = ia32_new_NoReg_vfp(env_cg);
869 if (new_op2 != NULL) {
872 new_op1 = be_transform_node(op2);
874 am->ins_permuted = 1;
876 am->op_type = ia32_AddrModeS;
878 if (flags & match_try_am) {
881 am->op_type = ia32_Normal;
885 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
887 new_op2 = be_transform_node(op2);
888 am->op_type = ia32_Normal;
889 am->ls_mode = get_irn_mode(op2);
890 if (flags & match_mode_neutral)
891 am->ls_mode = mode_Iu;
893 if (addr->base == NULL)
894 addr->base = noreg_gp;
895 if (addr->index == NULL)
896 addr->index = noreg_gp;
897 if (addr->mem == NULL)
898 addr->mem = new_NoMem();
900 am->new_op1 = new_op1;
901 am->new_op2 = new_op2;
902 am->commutative = commutative;
905 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
910 if (am->mem_proj == NULL)
913 /* we have to create a mode_T so the old MemProj can attach to us */
914 mode = get_irn_mode(node);
915 load = get_Proj_pred(am->mem_proj);
917 mark_irn_visited(load);
918 be_set_transformed_node(load, node);
920 if (mode != mode_T) {
921 set_irn_mode(node, mode_T);
922 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
929 * Construct a standard binary operation, set AM and immediate if required.
931 * @param node The original node for which the binop is created
932 * @param op1 The first operand
933 * @param op2 The second operand
934 * @param func The node constructor function
935 * @return The constructed ia32 node.
937 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
938 construct_binop_func *func, match_flags_t flags)
941 ir_node *block, *new_block, *new_node;
942 ia32_address_mode_t am;
943 ia32_address_t *addr = &am.addr;
945 block = get_nodes_block(node);
946 match_arguments(&am, block, op1, op2, NULL, flags);
948 dbgi = get_irn_dbg_info(node);
949 new_block = be_transform_node(block);
950 new_node = func(dbgi, current_ir_graph, new_block,
951 addr->base, addr->index, addr->mem,
952 am.new_op1, am.new_op2);
953 set_am_attributes(new_node, &am);
954 /* we can't use source address mode anymore when using immediates */
955 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
956 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
957 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
959 new_node = fix_mem_proj(new_node, &am);
966 n_ia32_l_binop_right,
967 n_ia32_l_binop_eflags
969 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
970 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
971 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
972 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
973 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
974 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
977 * Construct a binary operation which also consumes the eflags.
979 * @param node The node to transform
980 * @param func The node constructor function
981 * @param flags The match flags
982 * @return The constructor ia32 node
984 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
987 ir_node *src_block = get_nodes_block(node);
988 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
989 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
991 ir_node *block, *new_node, *eflags, *new_eflags;
992 ia32_address_mode_t am;
993 ia32_address_t *addr = &am.addr;
995 match_arguments(&am, src_block, op1, op2, NULL, flags);
997 dbgi = get_irn_dbg_info(node);
998 block = be_transform_node(src_block);
999 eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1000 new_eflags = be_transform_node(eflags);
1001 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
1002 addr->mem, am.new_op1, am.new_op2, new_eflags);
1003 set_am_attributes(new_node, &am);
1004 /* we can't use source address mode anymore when using immediates */
1005 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1006 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1007 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1009 new_node = fix_mem_proj(new_node, &am);
1014 static ir_node *get_fpcw(void)
1017 if (initial_fpcw != NULL)
1018 return initial_fpcw;
1020 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
1021 &ia32_fp_cw_regs[REG_FPCW]);
1022 initial_fpcw = be_transform_node(fpcw);
1024 return initial_fpcw;
1028 * Construct a standard binary operation, set AM and immediate if required.
1030 * @param op1 The first operand
1031 * @param op2 The second operand
1032 * @param func The node constructor function
1033 * @return The constructed ia32 node.
1035 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1036 construct_binop_float_func *func,
1037 match_flags_t flags)
1039 ir_mode *mode = get_irn_mode(node);
1041 ir_node *block, *new_block, *new_node;
1042 ia32_address_mode_t am;
1043 ia32_address_t *addr = &am.addr;
1045 /* cannot use address mode with long double on x87 */
1046 if (get_mode_size_bits(mode) > 64)
1049 block = get_nodes_block(node);
1050 match_arguments(&am, block, op1, op2, NULL, flags);
1052 dbgi = get_irn_dbg_info(node);
1053 new_block = be_transform_node(block);
1054 new_node = func(dbgi, current_ir_graph, new_block,
1055 addr->base, addr->index, addr->mem,
1056 am.new_op1, am.new_op2, get_fpcw());
1057 set_am_attributes(new_node, &am);
1059 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1061 new_node = fix_mem_proj(new_node, &am);
1067 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1069 * @param op1 The first operand
1070 * @param op2 The second operand
1071 * @param func The node constructor function
1072 * @return The constructed ia32 node.
1074 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1075 construct_shift_func *func,
1076 match_flags_t flags)
1079 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1081 assert(! mode_is_float(get_irn_mode(node)));
1082 assert(flags & match_immediate);
1083 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1085 if (flags & match_mode_neutral) {
1086 op1 = ia32_skip_downconv(op1);
1087 new_op1 = be_transform_node(op1);
1088 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1089 new_op1 = create_upconv(op1, node);
1091 new_op1 = be_transform_node(op1);
1094 /* the shift amount can be any mode that is bigger than 5 bits, since all
1095 * other bits are ignored anyway */
1096 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1097 op2 = get_Conv_op(op2);
1098 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1100 new_op2 = create_immediate_or_transform(op2, 0);
1102 dbgi = get_irn_dbg_info(node);
1103 block = get_nodes_block(node);
1104 new_block = be_transform_node(block);
1105 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1106 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1108 /* lowered shift instruction may have a dependency operand, handle it here */
1109 if (get_irn_arity(node) == 3) {
1110 /* we have a dependency */
1111 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1112 add_irn_dep(new_node, new_dep);
1120 * Construct a standard unary operation, set AM and immediate if required.
1122 * @param op The operand
1123 * @param func The node constructor function
1124 * @return The constructed ia32 node.
1126 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1127 match_flags_t flags)
1130 ir_node *block, *new_block, *new_op, *new_node;
1132 assert(flags == 0 || flags == match_mode_neutral);
1133 if (flags & match_mode_neutral) {
1134 op = ia32_skip_downconv(op);
1137 new_op = be_transform_node(op);
1138 dbgi = get_irn_dbg_info(node);
1139 block = get_nodes_block(node);
1140 new_block = be_transform_node(block);
1141 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1143 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1148 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1149 ia32_address_t *addr)
1151 ir_node *base, *index, *res;
1155 base = ia32_new_NoReg_gp(env_cg);
1157 base = be_transform_node(base);
1160 index = addr->index;
1161 if (index == NULL) {
1162 index = ia32_new_NoReg_gp(env_cg);
1164 index = be_transform_node(index);
1167 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1168 set_address(res, addr);
1174 * Returns non-zero if a given address mode has a symbolic or
1175 * numerical offset != 0.
1177 static int am_has_immediates(const ia32_address_t *addr)
1179 return addr->offset != 0 || addr->symconst_ent != NULL
1180 || addr->frame_entity || addr->use_frame;
1184 * Creates an ia32 Add.
1186 * @return the created ia32 Add node
1188 static ir_node *gen_Add(ir_node *node) {
1189 ir_mode *mode = get_irn_mode(node);
1190 ir_node *op1 = get_Add_left(node);
1191 ir_node *op2 = get_Add_right(node);
1193 ir_node *block, *new_block, *new_node, *add_immediate_op;
1194 ia32_address_t addr;
1195 ia32_address_mode_t am;
1197 if (mode_is_float(mode)) {
1198 if (ia32_cg_config.use_sse2)
1199 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1200 match_commutative | match_am);
1202 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1203 match_commutative | match_am);
1206 ia32_mark_non_am(node);
1208 op2 = ia32_skip_downconv(op2);
1209 op1 = ia32_skip_downconv(op1);
1213 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1214 * 1. Add with immediate -> Lea
1215 * 2. Add with possible source address mode -> Add
1216 * 3. Otherwise -> Lea
1218 memset(&addr, 0, sizeof(addr));
1219 ia32_create_address_mode(&addr, node, /*force=*/1);
1220 add_immediate_op = NULL;
1222 dbgi = get_irn_dbg_info(node);
1223 block = get_nodes_block(node);
1224 new_block = be_transform_node(block);
1227 if(addr.base == NULL && addr.index == NULL) {
1228 ir_graph *irg = current_ir_graph;
1229 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1230 addr.symconst_sign, addr.offset);
1231 add_irn_dep(new_node, get_irg_frame(irg));
1232 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1235 /* add with immediate? */
1236 if(addr.index == NULL) {
1237 add_immediate_op = addr.base;
1238 } else if(addr.base == NULL && addr.scale == 0) {
1239 add_immediate_op = addr.index;
1242 if(add_immediate_op != NULL) {
1243 if(!am_has_immediates(&addr)) {
1244 #ifdef DEBUG_libfirm
1245 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1248 return be_transform_node(add_immediate_op);
1251 new_node = create_lea_from_address(dbgi, new_block, &addr);
1252 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1256 /* test if we can use source address mode */
1257 match_arguments(&am, block, op1, op2, NULL, match_commutative
1258 | match_mode_neutral | match_am | match_immediate | match_try_am);
1260 /* construct an Add with source address mode */
1261 if (am.op_type == ia32_AddrModeS) {
1262 ir_graph *irg = current_ir_graph;
1263 ia32_address_t *am_addr = &am.addr;
1264 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1265 am_addr->index, am_addr->mem, am.new_op1,
1267 set_am_attributes(new_node, &am);
1268 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1270 new_node = fix_mem_proj(new_node, &am);
1275 /* otherwise construct a lea */
1276 new_node = create_lea_from_address(dbgi, new_block, &addr);
1277 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1282 * Creates an ia32 Mul.
1284 * @return the created ia32 Mul node
1286 static ir_node *gen_Mul(ir_node *node) {
1287 ir_node *op1 = get_Mul_left(node);
1288 ir_node *op2 = get_Mul_right(node);
1289 ir_mode *mode = get_irn_mode(node);
1291 if (mode_is_float(mode)) {
1292 if (ia32_cg_config.use_sse2)
1293 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1294 match_commutative | match_am);
1296 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1297 match_commutative | match_am);
1299 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1300 match_commutative | match_am | match_mode_neutral |
1301 match_immediate | match_am_and_immediates);
1305 * Creates an ia32 Mulh.
1306 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1307 * this result while Mul returns the lower 32 bit.
1309 * @return the created ia32 Mulh node
1311 static ir_node *gen_Mulh(ir_node *node)
1313 ir_node *block = get_nodes_block(node);
1314 ir_node *new_block = be_transform_node(block);
1315 ir_graph *irg = current_ir_graph;
1316 dbg_info *dbgi = get_irn_dbg_info(node);
1317 ir_mode *mode = get_irn_mode(node);
1318 ir_node *op1 = get_Mulh_left(node);
1319 ir_node *op2 = get_Mulh_right(node);
1320 ir_node *proj_res_high;
1322 ia32_address_mode_t am;
1323 ia32_address_t *addr = &am.addr;
1325 assert(!mode_is_float(mode) && "Mulh with float not supported");
1326 assert(get_mode_size_bits(mode) == 32);
1328 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1330 if (mode_is_signed(mode)) {
1331 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1332 addr->index, addr->mem, am.new_op1,
1335 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1336 addr->index, addr->mem, am.new_op1,
1340 set_am_attributes(new_node, &am);
1341 /* we can't use source address mode anymore when using immediates */
1342 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1343 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1344 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1346 assert(get_irn_mode(new_node) == mode_T);
1348 fix_mem_proj(new_node, &am);
1350 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1351 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1352 mode_Iu, pn_ia32_IMul1OP_res_high);
1354 return proj_res_high;
1360 * Creates an ia32 And.
1362 * @return The created ia32 And node
1364 static ir_node *gen_And(ir_node *node) {
1365 ir_node *op1 = get_And_left(node);
1366 ir_node *op2 = get_And_right(node);
1367 assert(! mode_is_float(get_irn_mode(node)));
1369 /* is it a zero extension? */
1370 if (is_Const(op2)) {
1371 tarval *tv = get_Const_tarval(op2);
1372 long v = get_tarval_long(tv);
1374 if (v == 0xFF || v == 0xFFFF) {
1375 dbg_info *dbgi = get_irn_dbg_info(node);
1376 ir_node *block = get_nodes_block(node);
1383 assert(v == 0xFFFF);
1386 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1391 return gen_binop(node, op1, op2, new_rd_ia32_And,
1392 match_commutative | match_mode_neutral | match_am
1399 * Creates an ia32 Or.
1401 * @return The created ia32 Or node
1403 static ir_node *gen_Or(ir_node *node) {
1404 ir_node *op1 = get_Or_left(node);
1405 ir_node *op2 = get_Or_right(node);
1407 assert (! mode_is_float(get_irn_mode(node)));
1408 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1409 | match_mode_neutral | match_am | match_immediate);
1415 * Creates an ia32 Eor.
1417 * @return The created ia32 Eor node
1419 static ir_node *gen_Eor(ir_node *node) {
1420 ir_node *op1 = get_Eor_left(node);
1421 ir_node *op2 = get_Eor_right(node);
1423 assert(! mode_is_float(get_irn_mode(node)));
1424 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1425 | match_mode_neutral | match_am | match_immediate);
1430 * Creates an ia32 Sub.
1432 * @return The created ia32 Sub node
1434 static ir_node *gen_Sub(ir_node *node) {
1435 ir_node *op1 = get_Sub_left(node);
1436 ir_node *op2 = get_Sub_right(node);
1437 ir_mode *mode = get_irn_mode(node);
1439 if (mode_is_float(mode)) {
1440 if (ia32_cg_config.use_sse2)
1441 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1443 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1447 if (is_Const(op2)) {
1448 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1452 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1453 | match_am | match_immediate);
1457 * Generates an ia32 DivMod with additional infrastructure for the
1458 * register allocator if needed.
1460 static ir_node *create_Div(ir_node *node)
1462 ir_graph *irg = current_ir_graph;
1463 dbg_info *dbgi = get_irn_dbg_info(node);
1464 ir_node *block = get_nodes_block(node);
1465 ir_node *new_block = be_transform_node(block);
1472 ir_node *sign_extension;
1473 ia32_address_mode_t am;
1474 ia32_address_t *addr = &am.addr;
1476 /* the upper bits have random contents for smaller modes */
1477 switch (get_irn_opcode(node)) {
1479 op1 = get_Div_left(node);
1480 op2 = get_Div_right(node);
1481 mem = get_Div_mem(node);
1482 mode = get_Div_resmode(node);
1485 op1 = get_Mod_left(node);
1486 op2 = get_Mod_right(node);
1487 mem = get_Mod_mem(node);
1488 mode = get_Mod_resmode(node);
1491 op1 = get_DivMod_left(node);
1492 op2 = get_DivMod_right(node);
1493 mem = get_DivMod_mem(node);
1494 mode = get_DivMod_resmode(node);
1497 panic("invalid divmod node %+F", node);
1500 match_arguments(&am, block, op1, op2, NULL, match_am);
1502 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1503 is the memory of the consumed address. We can have only the second op as address
1504 in Div nodes, so check only op2. */
1505 if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1506 new_mem = be_transform_node(mem);
1507 if(!is_NoMem(addr->mem)) {
1511 new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1514 new_mem = addr->mem;
1517 if (mode_is_signed(mode)) {
1518 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1519 add_irn_dep(produceval, get_irg_frame(irg));
1520 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1523 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1524 addr->index, new_mem, am.new_op2,
1525 am.new_op1, sign_extension);
1527 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1528 add_irn_dep(sign_extension, get_irg_frame(irg));
1530 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1531 addr->index, new_mem, am.new_op2,
1532 am.new_op1, sign_extension);
1535 set_irn_pinned(new_node, get_irn_pinned(node));
1537 set_am_attributes(new_node, &am);
1538 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1540 new_node = fix_mem_proj(new_node, &am);
1546 static ir_node *gen_Mod(ir_node *node) {
1547 return create_Div(node);
1550 static ir_node *gen_Div(ir_node *node) {
1551 return create_Div(node);
1554 static ir_node *gen_DivMod(ir_node *node) {
1555 return create_Div(node);
1561 * Creates an ia32 floating Div.
1563 * @return The created ia32 xDiv node
1565 static ir_node *gen_Quot(ir_node *node)
1567 ir_node *op1 = get_Quot_left(node);
1568 ir_node *op2 = get_Quot_right(node);
1570 if (ia32_cg_config.use_sse2) {
1571 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1573 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1579 * Creates an ia32 Shl.
1581 * @return The created ia32 Shl node
1583 static ir_node *gen_Shl(ir_node *node) {
1584 ir_node *left = get_Shl_left(node);
1585 ir_node *right = get_Shl_right(node);
1587 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1588 match_mode_neutral | match_immediate);
1592 * Creates an ia32 Shr.
1594 * @return The created ia32 Shr node
1596 static ir_node *gen_Shr(ir_node *node) {
1597 ir_node *left = get_Shr_left(node);
1598 ir_node *right = get_Shr_right(node);
1600 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1606 * Creates an ia32 Sar.
1608 * @return The created ia32 Shrs node
1610 static ir_node *gen_Shrs(ir_node *node) {
1611 ir_node *left = get_Shrs_left(node);
1612 ir_node *right = get_Shrs_right(node);
1613 ir_mode *mode = get_irn_mode(node);
1615 if(is_Const(right) && mode == mode_Is) {
1616 tarval *tv = get_Const_tarval(right);
1617 long val = get_tarval_long(tv);
1619 /* this is a sign extension */
1620 ir_graph *irg = current_ir_graph;
1621 dbg_info *dbgi = get_irn_dbg_info(node);
1622 ir_node *block = be_transform_node(get_nodes_block(node));
1624 ir_node *new_op = be_transform_node(op);
1625 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1626 add_irn_dep(pval, get_irg_frame(irg));
1628 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1632 /* 8 or 16 bit sign extension? */
1633 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1634 ir_node *shl_left = get_Shl_left(left);
1635 ir_node *shl_right = get_Shl_right(left);
1636 if(is_Const(shl_right)) {
1637 tarval *tv1 = get_Const_tarval(right);
1638 tarval *tv2 = get_Const_tarval(shl_right);
1639 if(tv1 == tv2 && tarval_is_long(tv1)) {
1640 long val = get_tarval_long(tv1);
1641 if(val == 16 || val == 24) {
1642 dbg_info *dbgi = get_irn_dbg_info(node);
1643 ir_node *block = get_nodes_block(node);
1653 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1662 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1668 * Creates an ia32 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 if (ia32_cg_config.use_sse2) {
2517 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2519 while (is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2520 val = get_Conv_op(val);
2522 new_val = be_transform_node(val);
2523 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2524 addr.index, addr.mem, new_val);
2526 /* We can skip ALL float Convs (and strict-Convs) before stores. */
2527 while (is_Conv(val) &&
2528 mode_is_float(get_irn_mode(get_Conv_op(val)))) {
2529 val = get_Conv_op(val);
2531 new_val = be_transform_node(val);
2532 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2533 addr.index, addr.mem, new_val, mode);
2536 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2537 val = get_Conv_op(val);
2539 /* We can skip ALL Convs (and strict-Convs) before stores. */
2540 while (is_Conv(val)) {
2541 val = get_Conv_op(val);
2543 new_val = be_transform_node(val);
2544 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2546 new_val = create_immediate_or_transform(val, 0);
2547 assert(mode != mode_b);
2549 if (get_mode_size_bits(mode) == 8) {
2550 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2551 addr.index, addr.mem, new_val);
2553 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2554 addr.index, addr.mem, new_val);
2559 set_irn_pinned(store, get_irn_pinned(node));
2560 set_ia32_op_type(store, ia32_AddrModeD);
2561 set_ia32_ls_mode(store, mode);
2563 set_address(store, &addr);
2564 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2570 * Transforms a Store.
2572 * @return the created ia32 Store node
2574 static ir_node *gen_Store(ir_node *node)
2576 ir_node *val = get_Store_value(node);
2577 ir_mode *mode = get_irn_mode(val);
2579 if (mode_is_float(mode) && is_Const(val)) {
2582 /* we are storing a floating point constant */
2583 if (ia32_cg_config.use_sse2) {
2584 transform = !is_simple_sse_Const(val);
2586 transform = !is_simple_x87_Const(val);
2589 return gen_float_const_Store(node, val);
2591 return gen_normal_Store(node);
2595 * Transforms a Switch.
2597 * @return the created ia32 SwitchJmp node
2599 static ir_node *create_Switch(ir_node *node)
2601 ir_graph *irg = current_ir_graph;
2602 dbg_info *dbgi = get_irn_dbg_info(node);
2603 ir_node *block = be_transform_node(get_nodes_block(node));
2604 ir_node *sel = get_Cond_selector(node);
2605 ir_node *new_sel = be_transform_node(sel);
2606 int switch_min = INT_MAX;
2607 int switch_max = INT_MIN;
2608 long default_pn = get_Cond_defaultProj(node);
2610 const ir_edge_t *edge;
2612 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2614 /* determine the smallest switch case value */
2615 foreach_out_edge(node, edge) {
2616 ir_node *proj = get_edge_src_irn(edge);
2617 long pn = get_Proj_proj(proj);
2618 if(pn == default_pn)
2627 if((unsigned) (switch_max - switch_min) > 256000) {
2628 panic("Size of switch %+F bigger than 256000", node);
2631 if (switch_min != 0) {
2632 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2634 /* if smallest switch case is not 0 we need an additional sub */
2635 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2636 add_ia32_am_offs_int(new_sel, -switch_min);
2637 set_ia32_op_type(new_sel, ia32_AddrModeS);
2639 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2642 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2643 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2649 * Transform a Cond node.
2651 static ir_node *gen_Cond(ir_node *node) {
2652 ir_node *block = get_nodes_block(node);
2653 ir_node *new_block = be_transform_node(block);
2654 ir_graph *irg = current_ir_graph;
2655 dbg_info *dbgi = get_irn_dbg_info(node);
2656 ir_node *sel = get_Cond_selector(node);
2657 ir_mode *sel_mode = get_irn_mode(sel);
2658 ir_node *flags = NULL;
2662 if (sel_mode != mode_b) {
2663 return create_Switch(node);
2666 /* we get flags from a Cmp */
2667 flags = get_flags_node(sel, &pnc);
2669 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2670 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2676 * Transforms a CopyB node.
2678 * @return The transformed node.
2680 static ir_node *gen_CopyB(ir_node *node) {
2681 ir_node *block = be_transform_node(get_nodes_block(node));
2682 ir_node *src = get_CopyB_src(node);
2683 ir_node *new_src = be_transform_node(src);
2684 ir_node *dst = get_CopyB_dst(node);
2685 ir_node *new_dst = be_transform_node(dst);
2686 ir_node *mem = get_CopyB_mem(node);
2687 ir_node *new_mem = be_transform_node(mem);
2688 ir_node *res = NULL;
2689 ir_graph *irg = current_ir_graph;
2690 dbg_info *dbgi = get_irn_dbg_info(node);
2691 int size = get_type_size_bytes(get_CopyB_type(node));
2694 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2695 /* then we need the size explicitly in ECX. */
2696 if (size >= 32 * 4) {
2697 rem = size & 0x3; /* size % 4 */
2700 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2701 add_irn_dep(res, get_irg_frame(irg));
2703 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2706 ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2709 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2712 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2717 static ir_node *gen_be_Copy(ir_node *node)
2719 ir_node *new_node = be_duplicate_node(node);
2720 ir_mode *mode = get_irn_mode(new_node);
2722 if (mode_needs_gp_reg(mode)) {
2723 set_irn_mode(new_node, mode_Iu);
2729 static ir_node *create_Fucom(ir_node *node)
2731 ir_graph *irg = current_ir_graph;
2732 dbg_info *dbgi = get_irn_dbg_info(node);
2733 ir_node *block = get_nodes_block(node);
2734 ir_node *new_block = be_transform_node(block);
2735 ir_node *left = get_Cmp_left(node);
2736 ir_node *new_left = be_transform_node(left);
2737 ir_node *right = get_Cmp_right(node);
2741 if(ia32_cg_config.use_fucomi) {
2742 new_right = be_transform_node(right);
2743 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2745 set_ia32_commutative(new_node);
2746 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2748 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2749 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2752 new_right = be_transform_node(right);
2753 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2757 set_ia32_commutative(new_node);
2759 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2761 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2762 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2768 static ir_node *create_Ucomi(ir_node *node)
2770 ir_graph *irg = current_ir_graph;
2771 dbg_info *dbgi = get_irn_dbg_info(node);
2772 ir_node *src_block = get_nodes_block(node);
2773 ir_node *new_block = be_transform_node(src_block);
2774 ir_node *left = get_Cmp_left(node);
2775 ir_node *right = get_Cmp_right(node);
2777 ia32_address_mode_t am;
2778 ia32_address_t *addr = &am.addr;
2780 match_arguments(&am, src_block, left, right, NULL,
2781 match_commutative | match_am);
2783 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2784 addr->mem, am.new_op1, am.new_op2,
2786 set_am_attributes(new_node, &am);
2788 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2790 new_node = fix_mem_proj(new_node, &am);
2796 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2797 * to fold an and into a test node
2799 static int can_fold_test_and(ir_node *node)
2801 const ir_edge_t *edge;
2803 /** we can only have eq and lg projs */
2804 foreach_out_edge(node, edge) {
2805 ir_node *proj = get_edge_src_irn(edge);
2806 pn_Cmp pnc = get_Proj_proj(proj);
2807 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2815 * Generate code for a Cmp.
2817 static ir_node *gen_Cmp(ir_node *node)
2819 ir_graph *irg = current_ir_graph;
2820 dbg_info *dbgi = get_irn_dbg_info(node);
2821 ir_node *block = get_nodes_block(node);
2822 ir_node *new_block = be_transform_node(block);
2823 ir_node *left = get_Cmp_left(node);
2824 ir_node *right = get_Cmp_right(node);
2825 ir_mode *cmp_mode = get_irn_mode(left);
2827 ia32_address_mode_t am;
2828 ia32_address_t *addr = &am.addr;
2831 if(mode_is_float(cmp_mode)) {
2832 if (ia32_cg_config.use_sse2) {
2833 return create_Ucomi(node);
2835 return create_Fucom(node);
2839 assert(mode_needs_gp_reg(cmp_mode));
2841 /* we prefer the Test instruction where possible except cases where
2842 * we can use SourceAM */
2843 cmp_unsigned = !mode_is_signed(cmp_mode);
2844 if (is_Const_0(right)) {
2846 get_irn_n_edges(left) == 1 &&
2847 can_fold_test_and(node)) {
2848 /* Test(and_left, and_right) */
2849 ir_node *and_left = get_And_left(left);
2850 ir_node *and_right = get_And_right(left);
2851 ir_mode *mode = get_irn_mode(and_left);
2853 match_arguments(&am, block, and_left, and_right, NULL,
2855 match_am | match_8bit_am | match_16bit_am |
2856 match_am_and_immediates | match_immediate |
2857 match_8bit | match_16bit);
2858 if (get_mode_size_bits(mode) == 8) {
2859 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2860 addr->index, addr->mem, am.new_op1,
2861 am.new_op2, am.ins_permuted,
2864 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2865 addr->index, addr->mem, am.new_op1,
2866 am.new_op2, am.ins_permuted, cmp_unsigned);
2869 match_arguments(&am, block, NULL, left, NULL,
2870 match_am | match_8bit_am | match_16bit_am |
2871 match_8bit | match_16bit);
2872 if (am.op_type == ia32_AddrModeS) {
2874 ir_node *imm_zero = try_create_Immediate(right, 0);
2875 if (get_mode_size_bits(cmp_mode) == 8) {
2876 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2877 addr->index, addr->mem, am.new_op2,
2878 imm_zero, am.ins_permuted,
2881 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2882 addr->index, addr->mem, am.new_op2,
2883 imm_zero, am.ins_permuted, cmp_unsigned);
2886 /* Test(left, left) */
2887 if (get_mode_size_bits(cmp_mode) == 8) {
2888 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2889 addr->index, addr->mem, am.new_op2,
2890 am.new_op2, am.ins_permuted,
2893 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2894 addr->index, addr->mem, am.new_op2,
2895 am.new_op2, am.ins_permuted,
2901 /* Cmp(left, right) */
2902 match_arguments(&am, block, left, right, NULL,
2903 match_commutative | match_am | match_8bit_am |
2904 match_16bit_am | match_am_and_immediates |
2905 match_immediate | match_8bit | match_16bit);
2906 if (get_mode_size_bits(cmp_mode) == 8) {
2907 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2908 addr->index, addr->mem, am.new_op1,
2909 am.new_op2, am.ins_permuted,
2912 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2913 addr->index, addr->mem, am.new_op1,
2914 am.new_op2, am.ins_permuted, cmp_unsigned);
2917 set_am_attributes(new_node, &am);
2918 assert(cmp_mode != NULL);
2919 set_ia32_ls_mode(new_node, cmp_mode);
2921 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2923 new_node = fix_mem_proj(new_node, &am);
2928 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2931 ir_graph *irg = current_ir_graph;
2932 dbg_info *dbgi = get_irn_dbg_info(node);
2933 ir_node *block = get_nodes_block(node);
2934 ir_node *new_block = be_transform_node(block);
2935 ir_node *val_true = get_Psi_val(node, 0);
2936 ir_node *val_false = get_Psi_default(node);
2938 match_flags_t match_flags;
2939 ia32_address_mode_t am;
2940 ia32_address_t *addr;
2942 assert(ia32_cg_config.use_cmov);
2943 assert(mode_needs_gp_reg(get_irn_mode(val_true)));
2947 match_flags = match_commutative | match_am | match_16bit_am |
2950 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2952 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2953 addr->mem, am.new_op1, am.new_op2, new_flags,
2954 am.ins_permuted, pnc);
2955 set_am_attributes(new_node, &am);
2957 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2959 new_node = fix_mem_proj(new_node, &am);
2965 * Creates a ia32 Setcc instruction.
2967 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2968 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2971 ir_graph *irg = current_ir_graph;
2972 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2973 ir_node *nomem = new_NoMem();
2974 ir_mode *mode = get_irn_mode(orig_node);
2977 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2978 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2980 /* we might need to conv the result up */
2981 if (get_mode_size_bits(mode) > 8) {
2982 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2983 nomem, new_node, mode_Bu);
2984 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2991 * Create instruction for an unsigned Difference or Zero.
2993 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2994 ir_graph *irg = current_ir_graph;
2995 ir_mode *mode = get_irn_mode(psi);
2996 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2999 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
3000 match_mode_neutral | match_am | match_immediate | match_two_users);
3002 block = get_nodes_block(new_node);
3004 if (is_Proj(new_node)) {
3005 sub = get_Proj_pred(new_node);
3006 assert(is_ia32_Sub(sub));
3009 set_irn_mode(sub, mode_T);
3010 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
3012 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3014 dbgi = get_irn_dbg_info(psi);
3015 noreg = ia32_new_NoReg_gp(env_cg);
3016 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
3017 nomem = new_NoMem();
3018 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
3020 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
3021 set_ia32_commutative(new_node);
3026 * Transforms a Psi node into CMov.
3028 * @return The transformed node.
3030 static ir_node *gen_Psi(ir_node *node)
3032 dbg_info *dbgi = get_irn_dbg_info(node);
3033 ir_node *block = get_nodes_block(node);
3034 ir_node *new_block = be_transform_node(block);
3035 ir_node *psi_true = get_Psi_val(node, 0);
3036 ir_node *psi_default = get_Psi_default(node);
3037 ir_node *cond = get_Psi_cond(node, 0);
3038 ir_mode *mode = get_irn_mode(node);
3041 assert(get_Psi_n_conds(node) == 1);
3042 assert(get_irn_mode(cond) == mode_b);
3044 /* Note: a Psi node uses a Load two times IFF it's used in the compare AND in the result */
3045 if (mode_is_float(mode)) {
3046 ir_node *cmp = get_Proj_pred(cond);
3047 ir_node *cmp_left = get_Cmp_left(cmp);
3048 ir_node *cmp_right = get_Cmp_right(cmp);
3049 pn_Cmp pnc = get_Proj_proj(cond);
3051 if (ia32_cg_config.use_sse2) {
3052 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3053 if (cmp_left == psi_true && cmp_right == psi_default) {
3054 /* psi(a <= b, a, b) => MIN */
3055 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3056 match_commutative | match_am | match_two_users);
3057 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3058 /* psi(a <= b, b, a) => MAX */
3059 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3060 match_commutative | match_am | match_two_users);
3062 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3063 if (cmp_left == psi_true && cmp_right == psi_default) {
3064 /* psi(a >= b, a, b) => MAX */
3065 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3066 match_commutative | match_am | match_two_users);
3067 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3068 /* psi(a >= b, b, a) => MIN */
3069 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3070 match_commutative | match_am | match_two_users);
3074 panic("cannot transform floating point Psi");
3080 assert(mode_needs_gp_reg(mode));
3082 if (is_Proj(cond)) {
3083 ir_node *cmp = get_Proj_pred(cond);
3085 ir_node *cmp_left = get_Cmp_left(cmp);
3086 ir_node *cmp_right = get_Cmp_right(cmp);
3087 pn_Cmp pnc = get_Proj_proj(cond);
3089 /* check for unsigned Doz first */
3090 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3091 is_Const_0(psi_default) && is_Sub(psi_true) &&
3092 get_Sub_left(psi_true) == cmp_left && get_Sub_right(psi_true) == cmp_right) {
3093 /* Psi(a >=u b, a - b, 0) unsigned Doz */
3094 return create_Doz(node, cmp_left, cmp_right);
3095 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3096 is_Const_0(psi_true) && is_Sub(psi_default) &&
3097 get_Sub_left(psi_default) == cmp_left && get_Sub_right(psi_default) == cmp_right) {
3098 /* Psi(a <=u b, 0, a - b) unsigned Doz */
3099 return create_Doz(node, cmp_left, cmp_right);
3104 flags = get_flags_node(cond, &pnc);
3106 if (is_Const(psi_true) && is_Const(psi_default)) {
3107 /* both are const, good */
3108 if (is_Const_1(psi_true) && is_Const_0(psi_default)) {
3109 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3110 } else if (is_Const_0(psi_true) && is_Const_1(psi_default)) {
3111 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3113 /* Not that simple. */
3118 new_node = create_CMov(node, cond, flags, pnc);
3126 * Create a conversion from x87 state register to general purpose.
3128 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3129 ir_node *block = be_transform_node(get_nodes_block(node));
3130 ir_node *op = get_Conv_op(node);
3131 ir_node *new_op = be_transform_node(op);
3132 ia32_code_gen_t *cg = env_cg;
3133 ir_graph *irg = current_ir_graph;
3134 dbg_info *dbgi = get_irn_dbg_info(node);
3135 ir_node *noreg = ia32_new_NoReg_gp(cg);
3136 ir_mode *mode = get_irn_mode(node);
3137 ir_node *fist, *load, *mem;
3139 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3140 set_irn_pinned(fist, op_pin_state_floats);
3141 set_ia32_use_frame(fist);
3142 set_ia32_op_type(fist, ia32_AddrModeD);
3144 assert(get_mode_size_bits(mode) <= 32);
3145 /* exception we can only store signed 32 bit integers, so for unsigned
3146 we store a 64bit (signed) integer and load the lower bits */
3147 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3148 set_ia32_ls_mode(fist, mode_Ls);
3150 set_ia32_ls_mode(fist, mode_Is);
3152 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3155 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3157 set_irn_pinned(load, op_pin_state_floats);
3158 set_ia32_use_frame(load);
3159 set_ia32_op_type(load, ia32_AddrModeS);
3160 set_ia32_ls_mode(load, mode_Is);
3161 if(get_ia32_ls_mode(fist) == mode_Ls) {
3162 ia32_attr_t *attr = get_ia32_attr(load);
3163 attr->data.need_64bit_stackent = 1;
3165 ia32_attr_t *attr = get_ia32_attr(load);
3166 attr->data.need_32bit_stackent = 1;
3168 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3170 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3174 * Creates a x87 strict Conv by placing a Sore and a Load
3176 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3178 ir_node *block = get_nodes_block(node);
3179 ir_graph *irg = current_ir_graph;
3180 dbg_info *dbgi = get_irn_dbg_info(node);
3181 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3182 ir_node *nomem = new_NoMem();
3183 ir_node *frame = get_irg_frame(irg);
3184 ir_node *store, *load;
3187 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3189 set_ia32_use_frame(store);
3190 set_ia32_op_type(store, ia32_AddrModeD);
3191 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3193 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3195 set_ia32_use_frame(load);
3196 set_ia32_op_type(load, ia32_AddrModeS);
3197 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3199 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3204 * Create a conversion from general purpose to x87 register
3206 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3207 ir_node *src_block = get_nodes_block(node);
3208 ir_node *block = be_transform_node(src_block);
3209 ir_graph *irg = current_ir_graph;
3210 dbg_info *dbgi = get_irn_dbg_info(node);
3211 ir_node *op = get_Conv_op(node);
3212 ir_node *new_op = NULL;
3216 ir_mode *store_mode;
3222 /* fild can use source AM if the operand is a signed 32bit integer */
3223 if (src_mode == mode_Is) {
3224 ia32_address_mode_t am;
3226 match_arguments(&am, src_block, NULL, op, NULL,
3227 match_am | match_try_am);
3228 if (am.op_type == ia32_AddrModeS) {
3229 ia32_address_t *addr = &am.addr;
3231 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3232 addr->index, addr->mem);
3233 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3236 set_am_attributes(fild, &am);
3237 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3239 fix_mem_proj(fild, &am);
3244 if(new_op == NULL) {
3245 new_op = be_transform_node(op);
3248 noreg = ia32_new_NoReg_gp(env_cg);
3249 nomem = new_NoMem();
3250 mode = get_irn_mode(op);
3252 /* first convert to 32 bit signed if necessary */
3253 src_bits = get_mode_size_bits(src_mode);
3254 if (src_bits == 8) {
3255 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3257 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3259 } else if (src_bits < 32) {
3260 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3262 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3266 assert(get_mode_size_bits(mode) == 32);
3269 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3272 set_ia32_use_frame(store);
3273 set_ia32_op_type(store, ia32_AddrModeD);
3274 set_ia32_ls_mode(store, mode_Iu);
3276 /* exception for 32bit unsigned, do a 64bit spill+load */
3277 if(!mode_is_signed(mode)) {
3280 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3282 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3283 get_irg_frame(irg), noreg, nomem,
3286 set_ia32_use_frame(zero_store);
3287 set_ia32_op_type(zero_store, ia32_AddrModeD);
3288 add_ia32_am_offs_int(zero_store, 4);
3289 set_ia32_ls_mode(zero_store, mode_Iu);
3294 store = new_rd_Sync(dbgi, irg, block, 2, in);
3295 store_mode = mode_Ls;
3297 store_mode = mode_Is;
3301 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3303 set_ia32_use_frame(fild);
3304 set_ia32_op_type(fild, ia32_AddrModeS);
3305 set_ia32_ls_mode(fild, store_mode);
3307 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3313 * Create a conversion from one integer mode into another one
3315 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3316 dbg_info *dbgi, ir_node *block, ir_node *op,
3319 ir_graph *irg = current_ir_graph;
3320 int src_bits = get_mode_size_bits(src_mode);
3321 int tgt_bits = get_mode_size_bits(tgt_mode);
3322 ir_node *new_block = be_transform_node(block);
3324 ir_mode *smaller_mode;
3326 ia32_address_mode_t am;
3327 ia32_address_t *addr = &am.addr;
3330 if (src_bits < tgt_bits) {
3331 smaller_mode = src_mode;
3332 smaller_bits = src_bits;
3334 smaller_mode = tgt_mode;
3335 smaller_bits = tgt_bits;
3338 #ifdef DEBUG_libfirm
3340 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3345 match_arguments(&am, block, NULL, op, NULL,
3346 match_8bit | match_16bit |
3347 match_am | match_8bit_am | match_16bit_am);
3348 if (smaller_bits == 8) {
3349 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3350 addr->index, addr->mem, am.new_op2,
3353 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3354 addr->index, addr->mem, am.new_op2,
3357 set_am_attributes(new_node, &am);
3358 /* match_arguments assume that out-mode = in-mode, this isn't true here
3360 set_ia32_ls_mode(new_node, smaller_mode);
3361 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3362 new_node = fix_mem_proj(new_node, &am);
3367 * Transforms a Conv node.
3369 * @return The created ia32 Conv node
3371 static ir_node *gen_Conv(ir_node *node) {
3372 ir_node *block = get_nodes_block(node);
3373 ir_node *new_block = be_transform_node(block);
3374 ir_node *op = get_Conv_op(node);
3375 ir_node *new_op = NULL;
3376 ir_graph *irg = current_ir_graph;
3377 dbg_info *dbgi = get_irn_dbg_info(node);
3378 ir_mode *src_mode = get_irn_mode(op);
3379 ir_mode *tgt_mode = get_irn_mode(node);
3380 int src_bits = get_mode_size_bits(src_mode);
3381 int tgt_bits = get_mode_size_bits(tgt_mode);
3382 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3383 ir_node *nomem = new_rd_NoMem(irg);
3384 ir_node *res = NULL;
3386 if (src_mode == mode_b) {
3387 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3388 /* nothing to do, we already model bools as 0/1 ints */
3389 return be_transform_node(op);
3392 if (src_mode == tgt_mode) {
3393 if (get_Conv_strict(node)) {
3394 if (ia32_cg_config.use_sse2) {
3395 /* when we are in SSE mode, we can kill all strict no-op conversion */
3396 return be_transform_node(op);
3399 /* this should be optimized already, but who knows... */
3400 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3401 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3402 return be_transform_node(op);
3406 if (mode_is_float(src_mode)) {
3407 new_op = be_transform_node(op);
3408 /* we convert from float ... */
3409 if (mode_is_float(tgt_mode)) {
3410 if(src_mode == mode_E && tgt_mode == mode_D
3411 && !get_Conv_strict(node)) {
3412 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3417 if (ia32_cg_config.use_sse2) {
3418 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3419 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3421 set_ia32_ls_mode(res, tgt_mode);
3423 if(get_Conv_strict(node)) {
3424 res = gen_x87_strict_conv(tgt_mode, new_op);
3425 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3428 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3433 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3434 if (ia32_cg_config.use_sse2) {
3435 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3437 set_ia32_ls_mode(res, src_mode);
3439 return gen_x87_fp_to_gp(node);
3443 /* we convert from int ... */
3444 if (mode_is_float(tgt_mode)) {
3446 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3447 if (ia32_cg_config.use_sse2) {
3448 new_op = be_transform_node(op);
3449 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3451 set_ia32_ls_mode(res, tgt_mode);
3453 res = gen_x87_gp_to_fp(node, src_mode);
3454 if(get_Conv_strict(node)) {
3455 res = gen_x87_strict_conv(tgt_mode, res);
3456 SET_IA32_ORIG_NODE(get_Proj_pred(res),
3457 ia32_get_old_node_name(env_cg, node));
3461 } else if(tgt_mode == mode_b) {
3462 /* mode_b lowering already took care that we only have 0/1 values */
3463 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3464 src_mode, tgt_mode));
3465 return be_transform_node(op);
3468 if (src_bits == tgt_bits) {
3469 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3470 src_mode, tgt_mode));
3471 return be_transform_node(op);
3474 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3482 static int check_immediate_constraint(long val, char immediate_constraint_type)
3484 switch (immediate_constraint_type) {
3488 return val >= 0 && val <= 32;
3490 return val >= 0 && val <= 63;
3492 return val >= -128 && val <= 127;
3494 return val == 0xff || val == 0xffff;
3496 return val >= 0 && val <= 3;
3498 return val >= 0 && val <= 255;
3500 return val >= 0 && val <= 127;
3504 panic("Invalid immediate constraint found");
3508 static ir_node *try_create_Immediate(ir_node *node,
3509 char immediate_constraint_type)
3512 tarval *offset = NULL;
3513 int offset_sign = 0;
3515 ir_entity *symconst_ent = NULL;
3516 int symconst_sign = 0;
3518 ir_node *cnst = NULL;
3519 ir_node *symconst = NULL;
3522 mode = get_irn_mode(node);
3523 if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3527 if(is_Minus(node)) {
3529 node = get_Minus_op(node);
3532 if(is_Const(node)) {
3535 offset_sign = minus;
3536 } else if(is_SymConst(node)) {
3539 symconst_sign = minus;
3540 } else if(is_Add(node)) {
3541 ir_node *left = get_Add_left(node);
3542 ir_node *right = get_Add_right(node);
3543 if(is_Const(left) && is_SymConst(right)) {
3546 symconst_sign = minus;
3547 offset_sign = minus;
3548 } else if(is_SymConst(left) && is_Const(right)) {
3551 symconst_sign = minus;
3552 offset_sign = minus;
3554 } else if(is_Sub(node)) {
3555 ir_node *left = get_Sub_left(node);
3556 ir_node *right = get_Sub_right(node);
3557 if(is_Const(left) && is_SymConst(right)) {
3560 symconst_sign = !minus;
3561 offset_sign = minus;
3562 } else if(is_SymConst(left) && is_Const(right)) {
3565 symconst_sign = minus;
3566 offset_sign = !minus;
3573 offset = get_Const_tarval(cnst);
3574 if(tarval_is_long(offset)) {
3575 val = get_tarval_long(offset);
3577 ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3582 if(!check_immediate_constraint(val, immediate_constraint_type))
3585 if(symconst != NULL) {
3586 if(immediate_constraint_type != 0) {
3587 /* we need full 32bits for symconsts */
3591 /* unfortunately the assembler/linker doesn't support -symconst */
3595 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3597 symconst_ent = get_SymConst_entity(symconst);
3599 if(cnst == NULL && symconst == NULL)
3602 if(offset_sign && offset != NULL) {
3603 offset = tarval_neg(offset);
3606 new_node = create_Immediate(symconst_ent, symconst_sign, val);
3611 static ir_node *create_immediate_or_transform(ir_node *node,
3612 char immediate_constraint_type)
3614 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3615 if (new_node == NULL) {
3616 new_node = be_transform_node(node);
3621 static const arch_register_req_t no_register_req = {
3622 arch_register_req_type_none,
3623 NULL, /* regclass */
3624 NULL, /* limit bitset */
3626 0 /* different pos */
3630 * An assembler constraint.
3632 typedef struct constraint_t constraint_t;
3633 struct constraint_t {
3636 const arch_register_req_t **out_reqs;
3638 const arch_register_req_t *req;
3639 unsigned immediate_possible;
3640 char immediate_type;
3643 static void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
3645 int immediate_possible = 0;
3646 char immediate_type = 0;
3647 unsigned limited = 0;
3648 const arch_register_class_t *cls = NULL;
3649 ir_graph *irg = current_ir_graph;
3650 struct obstack *obst = get_irg_obstack(irg);
3651 arch_register_req_t *req;
3652 unsigned *limited_ptr = NULL;
3656 /* TODO: replace all the asserts with nice error messages */
3659 /* a memory constraint: no need to do anything in backend about it
3660 * (the dependencies are already respected by the memory edge of
3662 constraint->req = &no_register_req;
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_EAX;
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_EBX;
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_ECX;
3692 assert(cls == NULL ||
3693 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3694 cls = &ia32_reg_classes[CLASS_ia32_gp];
3695 limited |= 1 << REG_EDX;
3698 assert(cls == NULL ||
3699 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3700 cls = &ia32_reg_classes[CLASS_ia32_gp];
3701 limited |= 1 << REG_EDI;
3704 assert(cls == NULL ||
3705 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3706 cls = &ia32_reg_classes[CLASS_ia32_gp];
3707 limited |= 1 << REG_ESI;
3710 case 'q': /* q means lower part of the regs only, this makes no
3711 * difference to Q for us (we only assigne whole registers) */
3712 assert(cls == NULL ||
3713 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3714 cls = &ia32_reg_classes[CLASS_ia32_gp];
3715 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3719 assert(cls == NULL ||
3720 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3721 cls = &ia32_reg_classes[CLASS_ia32_gp];
3722 limited |= 1 << REG_EAX | 1 << REG_EDX;
3725 assert(cls == NULL ||
3726 (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3727 cls = &ia32_reg_classes[CLASS_ia32_gp];
3728 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3729 1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3736 assert(cls == NULL);
3737 cls = &ia32_reg_classes[CLASS_ia32_gp];
3743 /* TODO: mark values so the x87 simulator knows about t and u */
3744 assert(cls == NULL);
3745 cls = &ia32_reg_classes[CLASS_ia32_vfp];
3750 assert(cls == NULL);
3751 /* TODO: check that sse2 is supported */
3752 cls = &ia32_reg_classes[CLASS_ia32_xmm];
3762 assert(!immediate_possible);
3763 immediate_possible = 1;
3764 immediate_type = *c;
3768 assert(!immediate_possible);
3769 immediate_possible = 1;
3773 assert(!immediate_possible && cls == NULL);
3774 immediate_possible = 1;
3775 cls = &ia32_reg_classes[CLASS_ia32_gp];
3788 assert(constraint->is_in && "can only specify same constraint "
3791 sscanf(c, "%d%n", &same_as, &p);
3799 /* memory constraint no need to do anything in backend about it
3800 * (the dependencies are already respected by the memory edge of
3802 constraint->req = &no_register_req;
3805 case 'E': /* no float consts yet */
3806 case 'F': /* no float consts yet */
3807 case 's': /* makes no sense on x86 */
3808 case 'X': /* we can't support that in firm */
3811 case '<': /* no autodecrement on x86 */
3812 case '>': /* no autoincrement on x86 */
3813 case 'C': /* sse constant not supported yet */
3814 case 'G': /* 80387 constant not supported yet */
3815 case 'y': /* we don't support mmx registers yet */
3816 case 'Z': /* not available in 32 bit mode */
3817 case 'e': /* not available in 32 bit mode */
3818 panic("unsupported asm constraint '%c' found in (%+F)",
3819 *c, current_ir_graph);
3822 panic("unknown asm constraint '%c' found in (%+F)", *c,
3830 const arch_register_req_t *other_constr;
3832 assert(cls == NULL && "same as and register constraint not supported");
3833 assert(!immediate_possible && "same as and immediate constraint not "
3835 assert(same_as < constraint->n_outs && "wrong constraint number in "
3836 "same_as constraint");
3838 other_constr = constraint->out_reqs[same_as];
3840 req = obstack_alloc(obst, sizeof(req[0]));
3841 req->cls = other_constr->cls;
3842 req->type = arch_register_req_type_should_be_same;
3843 req->limited = NULL;
3844 req->other_same = 1U << pos;
3845 req->other_different = 0;
3847 /* switch constraints. This is because in firm we have same_as
3848 * constraints on the output constraints while in the gcc asm syntax
3849 * they are specified on the input constraints */
3850 constraint->req = other_constr;
3851 constraint->out_reqs[same_as] = req;
3852 constraint->immediate_possible = 0;
3856 if(immediate_possible && cls == NULL) {
3857 cls = &ia32_reg_classes[CLASS_ia32_gp];
3859 assert(!immediate_possible || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3860 assert(cls != NULL);
3862 if(immediate_possible) {
3863 assert(constraint->is_in
3864 && "immediate make no sense for output constraints");
3866 /* todo: check types (no float input on 'r' constrained in and such... */
3869 req = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3870 limited_ptr = (unsigned*) (req+1);
3872 req = obstack_alloc(obst, sizeof(req[0]));
3874 memset(req, 0, sizeof(req[0]));
3877 req->type = arch_register_req_type_limited;
3878 *limited_ptr = limited;
3879 req->limited = limited_ptr;
3881 req->type = arch_register_req_type_normal;
3885 constraint->req = req;
3886 constraint->immediate_possible = immediate_possible;
3887 constraint->immediate_type = immediate_type;
3890 static void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
3891 const char *clobber)
3893 ir_graph *irg = get_irn_irg(node);
3894 struct obstack *obst = get_irg_obstack(irg);
3895 const arch_register_t *reg = NULL;
3898 arch_register_req_t *req;
3899 const arch_register_class_t *cls;
3904 /* TODO: construct a hashmap instead of doing linear search for clobber
3906 for(c = 0; c < N_CLASSES; ++c) {
3907 cls = & ia32_reg_classes[c];
3908 for(r = 0; r < cls->n_regs; ++r) {
3909 const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3910 if(strcmp(temp_reg->name, clobber) == 0
3911 || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3920 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3924 assert(reg->index < 32);
3926 limited = obstack_alloc(obst, sizeof(limited[0]));
3927 *limited = 1 << reg->index;
3929 req = obstack_alloc(obst, sizeof(req[0]));
3930 memset(req, 0, sizeof(req[0]));
3931 req->type = arch_register_req_type_limited;
3933 req->limited = limited;
3935 constraint->req = req;
3936 constraint->immediate_possible = 0;
3937 constraint->immediate_type = 0;
3940 static int is_memory_op(const ir_asm_constraint *constraint)
3942 ident *id = constraint->constraint;
3943 const char *str = get_id_str(id);
3946 for(c = str; *c != '\0'; ++c) {
3955 * generates code for a ASM node
3957 static ir_node *gen_ASM(ir_node *node)
3960 ir_graph *irg = current_ir_graph;
3961 ir_node *block = get_nodes_block(node);
3962 ir_node *new_block = be_transform_node(block);
3963 dbg_info *dbgi = get_irn_dbg_info(node);
3967 int n_out_constraints;
3969 const arch_register_req_t **out_reg_reqs;
3970 const arch_register_req_t **in_reg_reqs;
3971 ia32_asm_reg_t *register_map;
3972 unsigned reg_map_size = 0;
3973 struct obstack *obst;
3974 const ir_asm_constraint *in_constraints;
3975 const ir_asm_constraint *out_constraints;
3977 constraint_t parsed_constraint;
3979 arity = get_irn_arity(node);
3980 in = alloca(arity * sizeof(in[0]));
3981 memset(in, 0, arity * sizeof(in[0]));
3983 n_out_constraints = get_ASM_n_output_constraints(node);
3984 n_clobbers = get_ASM_n_clobbers(node);
3985 out_arity = n_out_constraints + n_clobbers;
3986 /* hack to keep space for mem proj */
3990 in_constraints = get_ASM_input_constraints(node);
3991 out_constraints = get_ASM_output_constraints(node);
3992 clobbers = get_ASM_clobbers(node);
3994 /* construct output constraints */
3995 obst = get_irg_obstack(irg);
3996 out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
3997 parsed_constraint.out_reqs = out_reg_reqs;
3998 parsed_constraint.n_outs = n_out_constraints;
3999 parsed_constraint.is_in = 0;
4001 for(i = 0; i < out_arity; ++i) {
4004 if(i < n_out_constraints) {
4005 const ir_asm_constraint *constraint = &out_constraints[i];
4006 c = get_id_str(constraint->constraint);
4007 parse_asm_constraint(i, &parsed_constraint, c);
4009 if(constraint->pos > reg_map_size)
4010 reg_map_size = constraint->pos;
4012 out_reg_reqs[i] = parsed_constraint.req;
4013 } else if(i < out_arity - 1) {
4014 ident *glob_id = clobbers [i - n_out_constraints];
4015 assert(glob_id != NULL);
4016 c = get_id_str(glob_id);
4017 parse_clobber(node, i, &parsed_constraint, c);
4019 out_reg_reqs[i+1] = parsed_constraint.req;
4023 out_reg_reqs[n_out_constraints] = &no_register_req;
4025 /* construct input constraints */
4026 in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
4027 parsed_constraint.is_in = 1;
4028 for(i = 0; i < arity; ++i) {
4029 const ir_asm_constraint *constraint = &in_constraints[i];
4030 ident *constr_id = constraint->constraint;
4031 const char *c = get_id_str(constr_id);
4033 parse_asm_constraint(i, &parsed_constraint, c);
4034 in_reg_reqs[i] = parsed_constraint.req;
4036 if(constraint->pos > reg_map_size)
4037 reg_map_size = constraint->pos;
4039 if(parsed_constraint.immediate_possible) {
4040 ir_node *pred = get_irn_n(node, i);
4041 char imm_type = parsed_constraint.immediate_type;
4042 ir_node *immediate = try_create_Immediate(pred, imm_type);
4044 if(immediate != NULL) {
4051 register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
4052 memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
4054 for(i = 0; i < n_out_constraints; ++i) {
4055 const ir_asm_constraint *constraint = &out_constraints[i];
4056 unsigned pos = constraint->pos;
4058 assert(pos < reg_map_size);
4059 register_map[pos].use_input = 0;
4060 register_map[pos].valid = 1;
4061 register_map[pos].memory = is_memory_op(constraint);
4062 register_map[pos].inout_pos = i;
4063 register_map[pos].mode = constraint->mode;
4066 /* transform inputs */
4067 for(i = 0; i < arity; ++i) {
4068 const ir_asm_constraint *constraint = &in_constraints[i];
4069 unsigned pos = constraint->pos;
4070 ir_node *pred = get_irn_n(node, i);
4071 ir_node *transformed;
4073 assert(pos < reg_map_size);
4074 register_map[pos].use_input = 1;
4075 register_map[pos].valid = 1;
4076 register_map[pos].memory = is_memory_op(constraint);
4077 register_map[pos].inout_pos = i;
4078 register_map[pos].mode = constraint->mode;
4083 transformed = be_transform_node(pred);
4084 in[i] = transformed;
4087 new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
4088 get_ASM_text(node), register_map);
4090 set_ia32_out_req_all(new_node, out_reg_reqs);
4091 set_ia32_in_req_all(new_node, in_reg_reqs);
4093 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4099 * Transforms a FrameAddr into an ia32 Add.
4101 static ir_node *gen_be_FrameAddr(ir_node *node) {
4102 ir_node *block = be_transform_node(get_nodes_block(node));
4103 ir_node *op = be_get_FrameAddr_frame(node);
4104 ir_node *new_op = be_transform_node(op);
4105 ir_graph *irg = current_ir_graph;
4106 dbg_info *dbgi = get_irn_dbg_info(node);
4107 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4110 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
4111 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
4112 set_ia32_use_frame(new_node);
4114 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4120 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
4122 static ir_node *gen_be_Return(ir_node *node) {
4123 ir_graph *irg = current_ir_graph;
4124 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
4125 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
4126 ir_entity *ent = get_irg_entity(irg);
4127 ir_type *tp = get_entity_type(ent);
4132 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
4133 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
4136 int pn_ret_val, pn_ret_mem, arity, i;
4138 assert(ret_val != NULL);
4139 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4140 return be_duplicate_node(node);
4143 res_type = get_method_res_type(tp, 0);
4145 if (! is_Primitive_type(res_type)) {
4146 return be_duplicate_node(node);
4149 mode = get_type_mode(res_type);
4150 if (! mode_is_float(mode)) {
4151 return be_duplicate_node(node);
4154 assert(get_method_n_ress(tp) == 1);
4156 pn_ret_val = get_Proj_proj(ret_val);
4157 pn_ret_mem = get_Proj_proj(ret_mem);
4159 /* get the Barrier */
4160 barrier = get_Proj_pred(ret_val);
4162 /* get result input of the Barrier */
4163 ret_val = get_irn_n(barrier, pn_ret_val);
4164 new_ret_val = be_transform_node(ret_val);
4166 /* get memory input of the Barrier */
4167 ret_mem = get_irn_n(barrier, pn_ret_mem);
4168 new_ret_mem = be_transform_node(ret_mem);
4170 frame = get_irg_frame(irg);
4172 dbgi = get_irn_dbg_info(barrier);
4173 block = be_transform_node(get_nodes_block(barrier));
4175 noreg = ia32_new_NoReg_gp(env_cg);
4177 /* store xmm0 onto stack */
4178 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
4179 new_ret_mem, new_ret_val);
4180 set_ia32_ls_mode(sse_store, mode);
4181 set_ia32_op_type(sse_store, ia32_AddrModeD);
4182 set_ia32_use_frame(sse_store);
4184 /* load into x87 register */
4185 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
4186 set_ia32_op_type(fld, ia32_AddrModeS);
4187 set_ia32_use_frame(fld);
4189 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
4190 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
4192 /* create a new barrier */
4193 arity = get_irn_arity(barrier);
4194 in = alloca(arity * sizeof(in[0]));
4195 for (i = 0; i < arity; ++i) {
4198 if (i == pn_ret_val) {
4200 } else if (i == pn_ret_mem) {
4203 ir_node *in = get_irn_n(barrier, i);
4204 new_in = be_transform_node(in);
4209 new_barrier = new_ir_node(dbgi, irg, block,
4210 get_irn_op(barrier), get_irn_mode(barrier),
4212 copy_node_attr(barrier, new_barrier);
4213 be_duplicate_deps(barrier, new_barrier);
4214 be_set_transformed_node(barrier, new_barrier);
4215 mark_irn_visited(barrier);
4217 /* transform normally */
4218 return be_duplicate_node(node);
4222 * Transform a be_AddSP into an ia32_SubSP.
4224 static ir_node *gen_be_AddSP(ir_node *node)
4226 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4227 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4229 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
4233 * Transform a be_SubSP into an ia32_AddSP
4235 static ir_node *gen_be_SubSP(ir_node *node)
4237 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4238 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4240 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
4244 * This function just sets the register for the Unknown node
4245 * as this is not done during register allocation because Unknown
4246 * is an "ignore" node.
4248 static ir_node *gen_Unknown(ir_node *node) {
4249 ir_mode *mode = get_irn_mode(node);
4251 if (mode_is_float(mode)) {
4252 if (ia32_cg_config.use_sse2) {
4253 return ia32_new_Unknown_xmm(env_cg);
4255 /* Unknown nodes are buggy in x87 simulator, use zero for now... */
4256 ir_graph *irg = current_ir_graph;
4257 dbg_info *dbgi = get_irn_dbg_info(node);
4258 ir_node *block = get_irg_start_block(irg);
4259 ir_node *ret = new_rd_ia32_vfldz(dbgi, irg, block);
4261 /* Const Nodes before the initial IncSP are a bad idea, because
4262 * they could be spilled and we have no SP ready at that point yet.
4263 * So add a dependency to the initial frame pointer calculation to
4264 * avoid that situation.
4266 add_irn_dep(ret, get_irg_frame(irg));
4269 } else if (mode_needs_gp_reg(mode)) {
4270 return ia32_new_Unknown_gp(env_cg);
4272 panic("unsupported Unknown-Mode");
4278 * Change some phi modes
4280 static ir_node *gen_Phi(ir_node *node) {
4281 ir_node *block = be_transform_node(get_nodes_block(node));
4282 ir_graph *irg = current_ir_graph;
4283 dbg_info *dbgi = get_irn_dbg_info(node);
4284 ir_mode *mode = get_irn_mode(node);
4287 if(mode_needs_gp_reg(mode)) {
4288 /* we shouldn't have any 64bit stuff around anymore */
4289 assert(get_mode_size_bits(mode) <= 32);
4290 /* all integer operations are on 32bit registers now */
4292 } else if(mode_is_float(mode)) {
4293 if (ia32_cg_config.use_sse2) {
4300 /* phi nodes allow loops, so we use the old arguments for now
4301 * and fix this later */
4302 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4303 get_irn_in(node) + 1);
4304 copy_node_attr(node, phi);
4305 be_duplicate_deps(node, phi);
4307 be_set_transformed_node(node, phi);
4308 be_enqueue_preds(node);
4316 static ir_node *gen_IJmp(ir_node *node)
4318 ir_node *block = get_nodes_block(node);
4319 ir_node *new_block = be_transform_node(block);
4320 ir_graph *irg = current_ir_graph;
4321 dbg_info *dbgi = get_irn_dbg_info(node);
4322 ir_node *op = get_IJmp_target(node);
4324 ia32_address_mode_t am;
4325 ia32_address_t *addr = &am.addr;
4327 assert(get_irn_mode(op) == mode_P);
4329 match_arguments(&am, block, NULL, op, NULL,
4330 match_am | match_8bit_am | match_16bit_am |
4331 match_immediate | match_8bit | match_16bit);
4333 new_node = new_rd_ia32_IJmp(dbgi, irg, new_block, addr->base, addr->index,
4334 addr->mem, am.new_op2);
4335 set_am_attributes(new_node, &am);
4336 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4338 new_node = fix_mem_proj(new_node, &am);
4343 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4346 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4347 ir_node *val, ir_node *mem);
4350 * Transforms a lowered Load into a "real" one.
4352 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4354 ir_node *block = be_transform_node(get_nodes_block(node));
4355 ir_node *ptr = get_irn_n(node, 0);
4356 ir_node *new_ptr = be_transform_node(ptr);
4357 ir_node *mem = get_irn_n(node, 1);
4358 ir_node *new_mem = be_transform_node(mem);
4359 ir_graph *irg = current_ir_graph;
4360 dbg_info *dbgi = get_irn_dbg_info(node);
4361 ir_mode *mode = get_ia32_ls_mode(node);
4362 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4365 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4367 set_ia32_op_type(new_op, ia32_AddrModeS);
4368 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4369 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4370 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4371 if (is_ia32_am_sc_sign(node))
4372 set_ia32_am_sc_sign(new_op);
4373 set_ia32_ls_mode(new_op, mode);
4374 if (is_ia32_use_frame(node)) {
4375 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4376 set_ia32_use_frame(new_op);
4379 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4385 * Transforms a lowered Store into a "real" one.
4387 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4389 ir_node *block = be_transform_node(get_nodes_block(node));
4390 ir_node *ptr = get_irn_n(node, 0);
4391 ir_node *new_ptr = be_transform_node(ptr);
4392 ir_node *val = get_irn_n(node, 1);
4393 ir_node *new_val = be_transform_node(val);
4394 ir_node *mem = get_irn_n(node, 2);
4395 ir_node *new_mem = be_transform_node(mem);
4396 ir_graph *irg = current_ir_graph;
4397 dbg_info *dbgi = get_irn_dbg_info(node);
4398 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4399 ir_mode *mode = get_ia32_ls_mode(node);
4403 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4405 am_offs = get_ia32_am_offs_int(node);
4406 add_ia32_am_offs_int(new_op, am_offs);
4408 set_ia32_op_type(new_op, ia32_AddrModeD);
4409 set_ia32_ls_mode(new_op, mode);
4410 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4411 set_ia32_use_frame(new_op);
4413 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4418 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4420 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4421 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4423 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4424 match_immediate | match_mode_neutral);
4427 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4429 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4430 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4431 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4435 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4437 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4438 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4439 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4443 static ir_node *gen_ia32_l_Add(ir_node *node) {
4444 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4445 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4446 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4447 match_commutative | match_am | match_immediate |
4448 match_mode_neutral);
4450 if(is_Proj(lowered)) {
4451 lowered = get_Proj_pred(lowered);
4453 assert(is_ia32_Add(lowered));
4454 set_irn_mode(lowered, mode_T);
4460 static ir_node *gen_ia32_l_Adc(ir_node *node)
4462 return gen_binop_flags(node, new_rd_ia32_Adc,
4463 match_commutative | match_am | match_immediate |
4464 match_mode_neutral);
4468 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4470 * @param node The node to transform
4471 * @return the created ia32 vfild node
4473 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4474 return gen_lowered_Load(node, new_rd_ia32_vfild);
4478 * Transforms an ia32_l_Load into a "real" ia32_Load node
4480 * @param node The node to transform
4481 * @return the created ia32 Load node
4483 static ir_node *gen_ia32_l_Load(ir_node *node) {
4484 return gen_lowered_Load(node, new_rd_ia32_Load);
4488 * Transforms an ia32_l_Store into a "real" ia32_Store node
4490 * @param node The node to transform
4491 * @return the created ia32 Store node
4493 static ir_node *gen_ia32_l_Store(ir_node *node) {
4494 return gen_lowered_Store(node, new_rd_ia32_Store);
4498 * Transforms a l_vfist into a "real" vfist node.
4500 * @param node The node to transform
4501 * @return the created ia32 vfist node
4503 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4504 ir_node *block = be_transform_node(get_nodes_block(node));
4505 ir_node *ptr = get_irn_n(node, 0);
4506 ir_node *new_ptr = be_transform_node(ptr);
4507 ir_node *val = get_irn_n(node, 1);
4508 ir_node *new_val = be_transform_node(val);
4509 ir_node *mem = get_irn_n(node, 2);
4510 ir_node *new_mem = be_transform_node(mem);
4511 ir_graph *irg = current_ir_graph;
4512 dbg_info *dbgi = get_irn_dbg_info(node);
4513 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4514 ir_mode *mode = get_ia32_ls_mode(node);
4515 ir_node *memres, *fist;
4518 memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
4519 am_offs = get_ia32_am_offs_int(node);
4520 add_ia32_am_offs_int(fist, am_offs);
4522 set_ia32_op_type(fist, ia32_AddrModeD);
4523 set_ia32_ls_mode(fist, mode);
4524 set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
4525 set_ia32_use_frame(fist);
4527 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4533 * Transforms a l_MulS into a "real" MulS node.
4535 * @return the created ia32 Mul node
4537 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4538 ir_node *left = get_binop_left(node);
4539 ir_node *right = get_binop_right(node);
4541 return gen_binop(node, left, right, new_rd_ia32_Mul,
4542 match_commutative | match_am | match_mode_neutral);
4546 * Transforms a l_IMulS into a "real" IMul1OPS node.
4548 * @return the created ia32 IMul1OP node
4550 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4551 ir_node *left = get_binop_left(node);
4552 ir_node *right = get_binop_right(node);
4554 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4555 match_commutative | match_am | match_mode_neutral);
4558 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4559 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4560 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4561 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4562 match_am | match_immediate | match_mode_neutral);
4564 if(is_Proj(lowered)) {
4565 lowered = get_Proj_pred(lowered);
4567 assert(is_ia32_Sub(lowered));
4568 set_irn_mode(lowered, mode_T);
4574 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4575 return gen_binop_flags(node, new_rd_ia32_Sbb,
4576 match_am | match_immediate | match_mode_neutral);
4580 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4581 * op1 - target to be shifted
4582 * op2 - contains bits to be shifted into target
4584 * Only op3 can be an immediate.
4586 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4587 ir_node *low, ir_node *count)
4589 ir_node *block = get_nodes_block(node);
4590 ir_node *new_block = be_transform_node(block);
4591 ir_graph *irg = current_ir_graph;
4592 dbg_info *dbgi = get_irn_dbg_info(node);
4593 ir_node *new_high = be_transform_node(high);
4594 ir_node *new_low = be_transform_node(low);
4598 /* the shift amount can be any mode that is bigger than 5 bits, since all
4599 * other bits are ignored anyway */
4600 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4601 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4602 count = get_Conv_op(count);
4604 new_count = create_immediate_or_transform(count, 0);
4606 if (is_ia32_l_ShlD(node)) {
4607 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4610 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4613 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4618 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4620 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4621 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4622 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4623 return gen_lowered_64bit_shifts(node, high, low, count);
4626 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4628 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4629 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4630 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4631 return gen_lowered_64bit_shifts(node, high, low, count);
4634 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4635 ir_node *src_block = get_nodes_block(node);
4636 ir_node *block = be_transform_node(src_block);
4637 ir_graph *irg = current_ir_graph;
4638 dbg_info *dbgi = get_irn_dbg_info(node);
4639 ir_node *frame = get_irg_frame(irg);
4640 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4641 ir_node *nomem = new_NoMem();
4642 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4643 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4644 ir_node *new_val_low = be_transform_node(val_low);
4645 ir_node *new_val_high = be_transform_node(val_high);
4650 ir_node *store_high;
4652 if(!mode_is_signed(get_irn_mode(val_high))) {
4653 panic("unsigned long long -> float not supported yet (%+F)", node);
4657 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4659 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4661 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4662 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4664 set_ia32_use_frame(store_low);
4665 set_ia32_use_frame(store_high);
4666 set_ia32_op_type(store_low, ia32_AddrModeD);
4667 set_ia32_op_type(store_high, ia32_AddrModeD);
4668 set_ia32_ls_mode(store_low, mode_Iu);
4669 set_ia32_ls_mode(store_high, mode_Is);
4670 add_ia32_am_offs_int(store_high, 4);
4674 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4677 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4679 set_ia32_use_frame(fild);
4680 set_ia32_op_type(fild, ia32_AddrModeS);
4681 set_ia32_ls_mode(fild, mode_Ls);
4683 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4685 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4688 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4689 ir_node *src_block = get_nodes_block(node);
4690 ir_node *block = be_transform_node(src_block);
4691 ir_graph *irg = current_ir_graph;
4692 dbg_info *dbgi = get_irn_dbg_info(node);
4693 ir_node *frame = get_irg_frame(irg);
4694 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4695 ir_node *nomem = new_NoMem();
4696 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4697 ir_node *new_val = be_transform_node(val);
4698 ir_node *fist, *mem;
4700 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4701 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4702 set_ia32_use_frame(fist);
4703 set_ia32_op_type(fist, ia32_AddrModeD);
4704 set_ia32_ls_mode(fist, mode_Ls);
4710 * the BAD transformer.
4712 static ir_node *bad_transform(ir_node *node) {
4713 panic("No transform function for %+F available.\n", node);
4717 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4718 ir_graph *irg = current_ir_graph;
4719 ir_node *block = be_transform_node(get_nodes_block(node));
4720 ir_node *pred = get_Proj_pred(node);
4721 ir_node *new_pred = be_transform_node(pred);
4722 ir_node *frame = get_irg_frame(irg);
4723 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4724 dbg_info *dbgi = get_irn_dbg_info(node);
4725 long pn = get_Proj_proj(node);
4730 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4731 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4732 set_ia32_use_frame(load);
4733 set_ia32_op_type(load, ia32_AddrModeS);
4734 set_ia32_ls_mode(load, mode_Iu);
4735 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4736 * 32 bit from it with this particular load */
4737 attr = get_ia32_attr(load);
4738 attr->data.need_64bit_stackent = 1;
4740 if (pn == pn_ia32_l_FloattoLL_res_high) {
4741 add_ia32_am_offs_int(load, 4);
4743 assert(pn == pn_ia32_l_FloattoLL_res_low);
4746 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4752 * Transform the Projs of an AddSP.
4754 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4755 ir_node *block = be_transform_node(get_nodes_block(node));
4756 ir_node *pred = get_Proj_pred(node);
4757 ir_node *new_pred = be_transform_node(pred);
4758 ir_graph *irg = current_ir_graph;
4759 dbg_info *dbgi = get_irn_dbg_info(node);
4760 long proj = get_Proj_proj(node);
4762 if (proj == pn_be_AddSP_sp) {
4763 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4764 pn_ia32_SubSP_stack);
4765 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4767 } else if(proj == pn_be_AddSP_res) {
4768 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4769 pn_ia32_SubSP_addr);
4770 } else if (proj == pn_be_AddSP_M) {
4771 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4775 return new_rd_Unknown(irg, get_irn_mode(node));
4779 * Transform the Projs of a SubSP.
4781 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4782 ir_node *block = be_transform_node(get_nodes_block(node));
4783 ir_node *pred = get_Proj_pred(node);
4784 ir_node *new_pred = be_transform_node(pred);
4785 ir_graph *irg = current_ir_graph;
4786 dbg_info *dbgi = get_irn_dbg_info(node);
4787 long proj = get_Proj_proj(node);
4789 if (proj == pn_be_SubSP_sp) {
4790 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4791 pn_ia32_AddSP_stack);
4792 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4794 } else if (proj == pn_be_SubSP_M) {
4795 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4799 return new_rd_Unknown(irg, get_irn_mode(node));
4803 * Transform and renumber the Projs from a Load.
4805 static ir_node *gen_Proj_Load(ir_node *node) {
4807 ir_node *block = be_transform_node(get_nodes_block(node));
4808 ir_node *pred = get_Proj_pred(node);
4809 ir_graph *irg = current_ir_graph;
4810 dbg_info *dbgi = get_irn_dbg_info(node);
4811 long proj = get_Proj_proj(node);
4813 /* loads might be part of source address mode matches, so we don't
4814 * transform the ProjMs yet (with the exception of loads whose result is
4817 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4820 /* this is needed, because sometimes we have loops that are only
4821 reachable through the ProjM */
4822 be_enqueue_preds(node);
4823 /* do it in 2 steps, to silence firm verifier */
4824 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4825 set_Proj_proj(res, pn_ia32_mem);
4829 /* renumber the proj */
4830 new_pred = be_transform_node(pred);
4831 if (is_ia32_Load(new_pred)) {
4834 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4836 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4837 case pn_Load_X_regular:
4838 return new_rd_Jmp(dbgi, irg, block);
4839 case pn_Load_X_except:
4840 /* This Load might raise an exception. Mark it. */
4841 set_ia32_exc_label(new_pred, 1);
4842 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4846 } else if (is_ia32_Conv_I2I(new_pred) ||
4847 is_ia32_Conv_I2I8Bit(new_pred)) {
4848 set_irn_mode(new_pred, mode_T);
4849 if (proj == pn_Load_res) {
4850 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4851 } else if (proj == pn_Load_M) {
4852 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4854 } else if (is_ia32_xLoad(new_pred)) {
4857 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4859 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_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);
4869 } else if (is_ia32_vfld(new_pred)) {
4872 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4874 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4875 case pn_Load_X_regular:
4876 return new_rd_Jmp(dbgi, irg, block);
4877 case pn_Load_X_except:
4878 /* This Load might raise an exception. Mark it. */
4879 set_ia32_exc_label(new_pred, 1);
4880 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4885 /* can happen for ProJMs when source address mode happened for the
4888 /* however it should not be the result proj, as that would mean the
4889 load had multiple users and should not have been used for
4891 if (proj != pn_Load_M) {
4892 panic("internal error: transformed node not a Load");
4894 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4898 return new_rd_Unknown(irg, get_irn_mode(node));
4902 * Transform and renumber the Projs from a DivMod like instruction.
4904 static ir_node *gen_Proj_DivMod(ir_node *node) {
4905 ir_node *block = be_transform_node(get_nodes_block(node));
4906 ir_node *pred = get_Proj_pred(node);
4907 ir_node *new_pred = be_transform_node(pred);
4908 ir_graph *irg = current_ir_graph;
4909 dbg_info *dbgi = get_irn_dbg_info(node);
4910 ir_mode *mode = get_irn_mode(node);
4911 long proj = get_Proj_proj(node);
4913 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4915 switch (get_irn_opcode(pred)) {
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_div_res);
4922 case pn_Div_X_regular:
4923 return new_rd_Jmp(dbgi, irg, block);
4924 case pn_Div_X_except:
4925 set_ia32_exc_label(new_pred, 1);
4926 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4934 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4936 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4937 case pn_Mod_X_except:
4938 set_ia32_exc_label(new_pred, 1);
4939 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4947 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4948 case pn_DivMod_res_div:
4949 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4950 case pn_DivMod_res_mod:
4951 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4952 case pn_DivMod_X_regular:
4953 return new_rd_Jmp(dbgi, irg, block);
4954 case pn_DivMod_X_except:
4955 set_ia32_exc_label(new_pred, 1);
4956 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4966 return new_rd_Unknown(irg, mode);
4970 * Transform and renumber the Projs from a CopyB.
4972 static ir_node *gen_Proj_CopyB(ir_node *node) {
4973 ir_node *block = be_transform_node(get_nodes_block(node));
4974 ir_node *pred = get_Proj_pred(node);
4975 ir_node *new_pred = be_transform_node(pred);
4976 ir_graph *irg = current_ir_graph;
4977 dbg_info *dbgi = get_irn_dbg_info(node);
4978 ir_mode *mode = get_irn_mode(node);
4979 long proj = get_Proj_proj(node);
4982 case pn_CopyB_M_regular:
4983 if (is_ia32_CopyB_i(new_pred)) {
4984 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4985 } else if (is_ia32_CopyB(new_pred)) {
4986 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4994 return new_rd_Unknown(irg, mode);
4998 * Transform and renumber the Projs from a Quot.
5000 static ir_node *gen_Proj_Quot(ir_node *node) {
5001 ir_node *block = be_transform_node(get_nodes_block(node));
5002 ir_node *pred = get_Proj_pred(node);
5003 ir_node *new_pred = be_transform_node(pred);
5004 ir_graph *irg = current_ir_graph;
5005 dbg_info *dbgi = get_irn_dbg_info(node);
5006 ir_mode *mode = get_irn_mode(node);
5007 long proj = get_Proj_proj(node);
5011 if (is_ia32_xDiv(new_pred)) {
5012 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
5013 } else if (is_ia32_vfdiv(new_pred)) {
5014 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
5018 if (is_ia32_xDiv(new_pred)) {
5019 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
5020 } else if (is_ia32_vfdiv(new_pred)) {
5021 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
5024 case pn_Quot_X_regular:
5025 case pn_Quot_X_except:
5031 return new_rd_Unknown(irg, mode);
5035 * Transform the Thread Local Storage Proj.
5037 static ir_node *gen_Proj_tls(ir_node *node) {
5038 ir_node *block = be_transform_node(get_nodes_block(node));
5039 ir_graph *irg = current_ir_graph;
5040 dbg_info *dbgi = NULL;
5041 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
5046 static ir_node *gen_be_Call(ir_node *node) {
5047 ir_node *res = be_duplicate_node(node);
5048 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5053 static ir_node *gen_be_IncSP(ir_node *node) {
5054 ir_node *res = be_duplicate_node(node);
5055 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5061 * Transform the Projs from a be_Call.
5063 static ir_node *gen_Proj_be_Call(ir_node *node) {
5064 ir_node *block = be_transform_node(get_nodes_block(node));
5065 ir_node *call = get_Proj_pred(node);
5066 ir_node *new_call = be_transform_node(call);
5067 ir_graph *irg = current_ir_graph;
5068 dbg_info *dbgi = get_irn_dbg_info(node);
5069 ir_type *method_type = be_Call_get_type(call);
5070 int n_res = get_method_n_ress(method_type);
5071 long proj = get_Proj_proj(node);
5072 ir_mode *mode = get_irn_mode(node);
5074 const arch_register_class_t *cls;
5076 /* The following is kinda tricky: If we're using SSE, then we have to
5077 * move the result value of the call in floating point registers to an
5078 * xmm register, we therefore construct a GetST0 -> xLoad sequence
5079 * after the call, we have to make sure to correctly make the
5080 * MemProj and the result Proj use these 2 nodes
5082 if (proj == pn_be_Call_M_regular) {
5083 // get new node for result, are we doing the sse load/store hack?
5084 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5085 ir_node *call_res_new;
5086 ir_node *call_res_pred = NULL;
5088 if (call_res != NULL) {
5089 call_res_new = be_transform_node(call_res);
5090 call_res_pred = get_Proj_pred(call_res_new);
5093 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
5094 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5095 pn_be_Call_M_regular);
5097 assert(is_ia32_xLoad(call_res_pred));
5098 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5102 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5103 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5105 ir_node *frame = get_irg_frame(irg);
5106 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
5108 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5111 /* in case there is no memory output: create one to serialize the copy
5113 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5114 pn_be_Call_M_regular);
5115 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5116 pn_be_Call_first_res);
5118 /* store st(0) onto stack */
5119 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
5121 set_ia32_op_type(fstp, ia32_AddrModeD);
5122 set_ia32_use_frame(fstp);
5124 /* load into SSE register */
5125 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5127 set_ia32_op_type(sse_load, ia32_AddrModeS);
5128 set_ia32_use_frame(sse_load);
5130 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5136 /* transform call modes */
5137 if (mode_is_data(mode)) {
5138 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5142 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5146 * Transform the Projs from a Cmp.
5148 static ir_node *gen_Proj_Cmp(ir_node *node)
5150 /* this probably means not all mode_b nodes were lowered... */
5151 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5156 * Transform and potentially renumber Proj nodes.
5158 static ir_node *gen_Proj(ir_node *node) {
5159 ir_node *pred = get_Proj_pred(node);
5160 if (is_Store(pred)) {
5161 long proj = get_Proj_proj(node);
5162 if (proj == pn_Store_M) {
5163 return be_transform_node(pred);
5166 return new_r_Bad(current_ir_graph);
5168 } else if (is_Load(pred)) {
5169 return gen_Proj_Load(node);
5170 } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
5171 return gen_Proj_DivMod(node);
5172 } else if (is_CopyB(pred)) {
5173 return gen_Proj_CopyB(node);
5174 } else if (is_Quot(pred)) {
5175 return gen_Proj_Quot(node);
5176 } else if (be_is_SubSP(pred)) {
5177 return gen_Proj_be_SubSP(node);
5178 } else if (be_is_AddSP(pred)) {
5179 return gen_Proj_be_AddSP(node);
5180 } else if (be_is_Call(pred)) {
5181 return gen_Proj_be_Call(node);
5182 } else if (is_Cmp(pred)) {
5183 return gen_Proj_Cmp(node);
5184 } else if (get_irn_op(pred) == op_Start) {
5185 long proj = get_Proj_proj(node);
5186 if (proj == pn_Start_X_initial_exec) {
5187 ir_node *block = get_nodes_block(pred);
5188 dbg_info *dbgi = get_irn_dbg_info(node);
5191 /* we exchange the ProjX with a jump */
5192 block = be_transform_node(block);
5193 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
5196 if (node == be_get_old_anchor(anchor_tls)) {
5197 return gen_Proj_tls(node);
5199 } else if (is_ia32_l_FloattoLL(pred)) {
5200 return gen_Proj_l_FloattoLL(node);
5202 } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5206 ir_mode *mode = get_irn_mode(node);
5207 if (mode_needs_gp_reg(mode)) {
5208 ir_node *new_pred = be_transform_node(pred);
5209 ir_node *block = be_transform_node(get_nodes_block(node));
5210 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5211 mode_Iu, get_Proj_proj(node));
5212 #ifdef DEBUG_libfirm
5213 new_proj->node_nr = node->node_nr;
5219 return be_duplicate_node(node);
5223 * Enters all transform functions into the generic pointer
5225 static void register_transformers(void)
5229 /* first clear the generic function pointer for all ops */
5230 clear_irp_opcodes_generic_func();
5232 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5233 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5271 /* transform ops from intrinsic lowering */
5287 GEN(ia32_l_LLtoFloat);
5288 GEN(ia32_l_FloattoLL);
5294 /* we should never see these nodes */
5309 /* handle generic backend nodes */
5318 op_Mulh = get_op_Mulh();
5327 * Pre-transform all unknown and noreg nodes.
5329 static void ia32_pretransform_node(void *arch_cg) {
5330 ia32_code_gen_t *cg = arch_cg;
5332 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5333 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5334 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5335 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5336 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5337 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5342 * Walker, checks if all ia32 nodes producing more than one result have
5343 * its Projs, other wise creates new projs and keep them using a be_Keep node.
5345 static void add_missing_keep_walker(ir_node *node, void *data)
5348 unsigned found_projs = 0;
5349 const ir_edge_t *edge;
5350 ir_mode *mode = get_irn_mode(node);
5355 if(!is_ia32_irn(node))
5358 n_outs = get_ia32_n_res(node);
5361 if(is_ia32_SwitchJmp(node))
5364 assert(n_outs < (int) sizeof(unsigned) * 8);
5365 foreach_out_edge(node, edge) {
5366 ir_node *proj = get_edge_src_irn(edge);
5367 int pn = get_Proj_proj(proj);
5369 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
5370 found_projs |= 1 << pn;
5374 /* are keeps missing? */
5376 for(i = 0; i < n_outs; ++i) {
5379 const arch_register_req_t *req;
5380 const arch_register_class_t *class;
5382 if(found_projs & (1 << i)) {
5386 req = get_ia32_out_req(node, i);
5391 if(class == &ia32_reg_classes[CLASS_ia32_flags]) {
5395 block = get_nodes_block(node);
5396 in[0] = new_r_Proj(current_ir_graph, block, node,
5397 arch_register_class_mode(class), i);
5398 if(last_keep != NULL) {
5399 be_Keep_add_node(last_keep, class, in[0]);
5401 last_keep = be_new_Keep(class, current_ir_graph, block, 1, in);
5402 if(sched_is_scheduled(node)) {
5403 sched_add_after(node, last_keep);
5410 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5413 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5415 ir_graph *irg = be_get_birg_irg(cg->birg);
5416 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5419 /* do the transformation */
5420 void ia32_transform_graph(ia32_code_gen_t *cg) {
5422 ir_graph *irg = cg->irg;
5424 register_transformers();
5426 initial_fpcw = NULL;
5428 BE_TIMER_PUSH(t_heights);
5429 heights = heights_new(irg);
5430 BE_TIMER_POP(t_heights);
5431 ia32_calculate_non_address_mode_nodes(cg->birg);
5433 /* the transform phase is not safe for CSE (yet) because several nodes get
5434 * attributes set after their creation */
5435 cse_last = get_opt_cse();
5438 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5440 set_opt_cse(cse_last);
5442 ia32_free_non_address_mode_nodes();
5443 heights_free(heights);
5447 void ia32_init_transform(void)
5449 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");