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 /** Return non-zero is a node represents the 0 constant. */
267 static int is_Const_0(ir_node *node) {
268 return is_Const(node) && is_Const_null(node);
271 /** Return non-zero is a node represents the 1 constant. */
272 static int is_Const_1(ir_node *node) {
273 return is_Const(node) && is_Const_one(node);
276 /** Return non-zero is a node represents the -1 constant. */
277 static int is_Const_Minus_1(ir_node *node) {
278 return is_Const(node) && is_Const_all_one(node);
282 * returns true if constant can be created with a simple float command
284 static int is_simple_x87_Const(ir_node *node)
286 tarval *tv = get_Const_tarval(node);
287 if (tarval_is_null(tv) || tarval_is_one(tv))
290 /* TODO: match all the other float constants */
295 * returns true if constant can be created with a simple float command
297 static int is_simple_sse_Const(ir_node *node)
299 tarval *tv = get_Const_tarval(node);
300 ir_mode *mode = get_tarval_mode(tv);
305 if (tarval_is_null(tv) || tarval_is_one(tv))
308 if (mode == mode_D) {
309 unsigned val = get_tarval_sub_bits(tv, 0) |
310 (get_tarval_sub_bits(tv, 1) << 8) |
311 (get_tarval_sub_bits(tv, 2) << 16) |
312 (get_tarval_sub_bits(tv, 3) << 24);
314 /* lower 32bit are zero, really a 32bit constant */
318 /* TODO: match all the other float constants */
323 * Transforms a Const.
325 static ir_node *gen_Const(ir_node *node) {
326 ir_graph *irg = current_ir_graph;
327 ir_node *old_block = get_nodes_block(node);
328 ir_node *block = be_transform_node(old_block);
329 dbg_info *dbgi = get_irn_dbg_info(node);
330 ir_mode *mode = get_irn_mode(node);
332 assert(is_Const(node));
334 if (mode_is_float(mode)) {
336 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
337 ir_node *nomem = new_NoMem();
341 if (ia32_cg_config.use_sse2) {
342 tarval *tv = get_Const_tarval(node);
343 if (tarval_is_null(tv)) {
344 load = new_rd_ia32_xZero(dbgi, irg, block);
345 set_ia32_ls_mode(load, mode);
347 } else if (tarval_is_one(tv)) {
348 int cnst = mode == mode_F ? 26 : 55;
349 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
350 ir_node *imm2 = create_Immediate(NULL, 0, 2);
351 ir_node *pslld, *psrld;
353 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
354 set_ia32_ls_mode(load, mode);
355 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
356 set_ia32_ls_mode(pslld, mode);
357 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
358 set_ia32_ls_mode(psrld, mode);
360 } else if (mode == mode_F) {
361 /* we can place any 32bit constant by using a movd gp, sse */
362 unsigned val = get_tarval_sub_bits(tv, 0) |
363 (get_tarval_sub_bits(tv, 1) << 8) |
364 (get_tarval_sub_bits(tv, 2) << 16) |
365 (get_tarval_sub_bits(tv, 3) << 24);
366 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
367 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
368 set_ia32_ls_mode(load, mode);
371 if (mode == mode_D) {
372 unsigned val = get_tarval_sub_bits(tv, 0) |
373 (get_tarval_sub_bits(tv, 1) << 8) |
374 (get_tarval_sub_bits(tv, 2) << 16) |
375 (get_tarval_sub_bits(tv, 3) << 24);
377 ir_node *imm32 = create_Immediate(NULL, 0, 32);
378 ir_node *cnst, *psllq;
380 /* fine, lower 32bit are zero, produce 32bit value */
381 val = get_tarval_sub_bits(tv, 4) |
382 (get_tarval_sub_bits(tv, 5) << 8) |
383 (get_tarval_sub_bits(tv, 6) << 16) |
384 (get_tarval_sub_bits(tv, 7) << 24);
385 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
386 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
387 set_ia32_ls_mode(load, mode);
388 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
389 set_ia32_ls_mode(psllq, mode);
394 floatent = create_float_const_entity(node);
396 load = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
398 set_ia32_op_type(load, ia32_AddrModeS);
399 set_ia32_am_sc(load, floatent);
400 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
401 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
404 if (is_Const_null(node)) {
405 load = new_rd_ia32_vfldz(dbgi, irg, block);
407 set_ia32_ls_mode(load, mode);
408 } else if (is_Const_one(node)) {
409 load = new_rd_ia32_vfld1(dbgi, irg, block);
411 set_ia32_ls_mode(load, mode);
413 floatent = create_float_const_entity(node);
415 load = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
416 set_ia32_op_type(load, ia32_AddrModeS);
417 set_ia32_am_sc(load, floatent);
418 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
419 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
420 /* take the mode from the entity */
421 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
425 /* Const Nodes before the initial IncSP are a bad idea, because
426 * they could be spilled and we have no SP ready at that point yet.
427 * So add a dependency to the initial frame pointer calculation to
428 * avoid that situation.
430 if (get_irg_start_block(irg) == block) {
431 add_irn_dep(load, get_irg_frame(irg));
434 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
436 } else { /* non-float mode */
438 tarval *tv = get_Const_tarval(node);
441 tv = tarval_convert_to(tv, mode_Iu);
443 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
445 panic("couldn't convert constant tarval (%+F)", node);
447 val = get_tarval_long(tv);
449 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
450 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
453 if (get_irg_start_block(irg) == block) {
454 add_irn_dep(cnst, get_irg_frame(irg));
462 * Transforms a SymConst.
464 static ir_node *gen_SymConst(ir_node *node) {
465 ir_graph *irg = current_ir_graph;
466 ir_node *old_block = get_nodes_block(node);
467 ir_node *block = be_transform_node(old_block);
468 dbg_info *dbgi = get_irn_dbg_info(node);
469 ir_mode *mode = get_irn_mode(node);
472 if (mode_is_float(mode)) {
473 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
474 ir_node *nomem = new_NoMem();
476 if (ia32_cg_config.use_sse2)
477 cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
479 cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
480 set_ia32_am_sc(cnst, get_SymConst_entity(node));
481 set_ia32_use_frame(cnst);
485 if(get_SymConst_kind(node) != symconst_addr_ent) {
486 panic("backend only support symconst_addr_ent (at %+F)", node);
488 entity = get_SymConst_entity(node);
489 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
492 /* Const Nodes before the initial IncSP are a bad idea, because
493 * they could be spilled and we have no SP ready at that point yet
495 if (get_irg_start_block(irg) == block) {
496 add_irn_dep(cnst, get_irg_frame(irg));
499 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
504 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
505 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
506 static const struct {
508 const char *ent_name;
509 const char *cnst_str;
512 } names [ia32_known_const_max] = {
513 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
514 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
515 { TP_SFP_ABS, ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
516 { TP_DFP_ABS, ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
517 { TP_INT_MAX, ENT_INT_MAX, DFP_INTMAX, 2, 4 } /* ia32_INTMAX */
519 static ir_entity *ent_cache[ia32_known_const_max];
521 const char *tp_name, *ent_name, *cnst_str;
529 ent_name = names[kct].ent_name;
530 if (! ent_cache[kct]) {
531 tp_name = names[kct].tp_name;
532 cnst_str = names[kct].cnst_str;
534 switch (names[kct].mode) {
535 case 0: mode = mode_Iu; break;
536 case 1: mode = mode_Lu; break;
537 default: mode = mode_F; break;
539 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
540 tp = new_type_primitive(new_id_from_str(tp_name), mode);
541 /* set the specified alignment */
542 set_type_alignment_bytes(tp, names[kct].align);
544 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
546 set_entity_ld_ident(ent, get_entity_ident(ent));
547 set_entity_visibility(ent, visibility_local);
548 set_entity_variability(ent, variability_constant);
549 set_entity_allocation(ent, allocation_static);
551 /* we create a new entity here: It's initialization must resist on the
553 rem = current_ir_graph;
554 current_ir_graph = get_const_code_irg();
555 cnst = new_Const(mode, tv);
556 current_ir_graph = rem;
558 set_atomic_ent_value(ent, cnst);
560 /* cache the entry */
561 ent_cache[kct] = ent;
564 return ent_cache[kct];
569 * Prints the old node name on cg obst and returns a pointer to it.
571 const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
572 ia32_isa_t *isa = (ia32_isa_t*) cg->arch_env;
574 lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
575 obstack_1grow(isa->name_obst, 0);
576 return obstack_finish(isa->name_obst);
581 * return true if the node is a Proj(Load) and could be used in source address
582 * mode for another node. Will return only true if the @p other node is not
583 * dependent on the memory of the Load (for binary operations use the other
584 * input here, for unary operations use NULL).
586 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
587 ir_node *other, ir_node *other2, match_flags_t flags)
592 /* float constants are always available */
593 if (is_Const(node)) {
594 ir_mode *mode = get_irn_mode(node);
595 if (mode_is_float(mode)) {
596 if (ia32_cg_config.use_sse2) {
597 if (is_simple_sse_Const(node))
600 if (is_simple_x87_Const(node))
603 if (get_irn_n_edges(node) > 1)
611 load = get_Proj_pred(node);
612 pn = get_Proj_proj(node);
613 if (!is_Load(load) || pn != pn_Load_res)
615 if (get_nodes_block(load) != block)
617 /* we only use address mode if we're the only user of the load */
618 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
620 /* in some edge cases with address mode we might reach the load normally
621 * and through some AM sequence, if it is already materialized then we
622 * can't create an AM node from it */
623 if (be_is_transformed(node))
626 /* don't do AM if other node inputs depend on the load (via mem-proj) */
627 if (other != NULL && get_nodes_block(other) == block &&
628 heights_reachable_in_block(heights, other, load))
630 if (other2 != NULL && get_nodes_block(other2) == block &&
631 heights_reachable_in_block(heights, other2, load))
637 typedef struct ia32_address_mode_t ia32_address_mode_t;
638 struct ia32_address_mode_t {
642 ia32_op_type_t op_type;
646 unsigned commutative : 1;
647 unsigned ins_permuted : 1;
650 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
654 /* construct load address */
655 memset(addr, 0, sizeof(addr[0]));
656 ia32_create_address_mode(addr, ptr, /*force=*/0);
658 noreg_gp = ia32_new_NoReg_gp(env_cg);
659 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
660 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
661 addr->mem = be_transform_node(mem);
664 static void build_address(ia32_address_mode_t *am, ir_node *node)
666 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
667 ia32_address_t *addr = &am->addr;
673 if (is_Const(node)) {
674 ir_entity *entity = create_float_const_entity(node);
675 addr->base = noreg_gp;
676 addr->index = noreg_gp;
677 addr->mem = new_NoMem();
678 addr->symconst_ent = entity;
680 am->ls_mode = get_type_mode(get_entity_type(entity));
681 am->pinned = op_pin_state_floats;
685 load = get_Proj_pred(node);
686 ptr = get_Load_ptr(load);
687 mem = get_Load_mem(load);
688 new_mem = be_transform_node(mem);
689 am->pinned = get_irn_pinned(load);
690 am->ls_mode = get_Load_mode(load);
691 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
693 /* construct load address */
694 ia32_create_address_mode(addr, ptr, /*force=*/0);
696 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
697 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
701 static void set_address(ir_node *node, const ia32_address_t *addr)
703 set_ia32_am_scale(node, addr->scale);
704 set_ia32_am_sc(node, addr->symconst_ent);
705 set_ia32_am_offs_int(node, addr->offset);
706 if(addr->symconst_sign)
707 set_ia32_am_sc_sign(node);
709 set_ia32_use_frame(node);
710 set_ia32_frame_ent(node, addr->frame_entity);
714 * Apply attributes of a given address mode to a node.
716 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
718 set_address(node, &am->addr);
720 set_ia32_op_type(node, am->op_type);
721 set_ia32_ls_mode(node, am->ls_mode);
722 if (am->pinned == op_pin_state_pinned) {
723 set_irn_pinned(node, am->pinned);
726 set_ia32_commutative(node);
730 * Check, if a given node is a Down-Conv, ie. a integer Conv
731 * from a mode with a mode with more bits to a mode with lesser bits.
732 * Moreover, we return only true if the node has not more than 1 user.
734 * @param node the node
735 * @return non-zero if node is a Down-Conv
737 static int is_downconv(const ir_node *node)
745 /* we only want to skip the conv when we're the only user
746 * (not optimal but for now...)
748 if(get_irn_n_edges(node) > 1)
751 src_mode = get_irn_mode(get_Conv_op(node));
752 dest_mode = get_irn_mode(node);
753 return mode_needs_gp_reg(src_mode)
754 && mode_needs_gp_reg(dest_mode)
755 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
758 /* Skip all Down-Conv's on a given node and return the resulting node. */
759 ir_node *ia32_skip_downconv(ir_node *node) {
760 while (is_downconv(node))
761 node = get_Conv_op(node);
766 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
768 ir_mode *mode = get_irn_mode(node);
773 if(mode_is_signed(mode)) {
778 block = get_nodes_block(node);
779 dbgi = get_irn_dbg_info(node);
781 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
785 * matches operands of a node into ia32 addressing/operand modes. This covers
786 * usage of source address mode, immediates, operations with non 32-bit modes,
788 * The resulting data is filled into the @p am struct. block is the block
789 * of the node whose arguments are matched. op1, op2 are the first and second
790 * input that are matched (op1 may be NULL). other_op is another unrelated
791 * input that is not matched! but which is needed sometimes to check if AM
792 * for op1/op2 is legal.
793 * @p flags describes the supported modes of the operation in detail.
795 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
796 ir_node *op1, ir_node *op2, ir_node *other_op,
799 ia32_address_t *addr = &am->addr;
800 ir_mode *mode = get_irn_mode(op2);
801 int mode_bits = get_mode_size_bits(mode);
802 ir_node *noreg_gp, *new_op1, *new_op2;
804 unsigned commutative;
805 int use_am_and_immediates;
808 memset(am, 0, sizeof(am[0]));
810 commutative = (flags & match_commutative) != 0;
811 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
812 use_am = (flags & match_am) != 0;
813 use_immediate = (flags & match_immediate) != 0;
814 assert(!use_am_and_immediates || use_immediate);
817 assert(!commutative || op1 != NULL);
818 assert(use_am || !(flags & match_8bit_am));
819 assert(use_am || !(flags & match_16bit_am));
821 if (mode_bits == 8) {
822 if (!(flags & match_8bit_am))
824 /* we don't automatically add upconvs yet */
825 assert((flags & match_mode_neutral) || (flags & match_8bit));
826 } else if (mode_bits == 16) {
827 if (!(flags & match_16bit_am))
829 /* we don't automatically add upconvs yet */
830 assert((flags & match_mode_neutral) || (flags & match_16bit));
833 /* we can simply skip downconvs for mode neutral nodes: the upper bits
834 * can be random for these operations */
835 if (flags & match_mode_neutral) {
836 op2 = ia32_skip_downconv(op2);
838 op1 = ia32_skip_downconv(op1);
842 /* match immediates. firm nodes are normalized: constants are always on the
845 if (!(flags & match_try_am) && use_immediate) {
846 new_op2 = try_create_Immediate(op2, 0);
849 noreg_gp = ia32_new_NoReg_gp(env_cg);
850 if (new_op2 == NULL &&
851 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
852 build_address(am, op2);
853 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
854 if (mode_is_float(mode)) {
855 new_op2 = ia32_new_NoReg_vfp(env_cg);
859 am->op_type = ia32_AddrModeS;
860 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
862 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
864 build_address(am, op1);
866 if (mode_is_float(mode)) {
867 noreg = ia32_new_NoReg_vfp(env_cg);
872 if (new_op2 != NULL) {
875 new_op1 = be_transform_node(op2);
877 am->ins_permuted = 1;
879 am->op_type = ia32_AddrModeS;
881 if (flags & match_try_am) {
884 am->op_type = ia32_Normal;
888 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
890 new_op2 = be_transform_node(op2);
891 am->op_type = ia32_Normal;
892 am->ls_mode = get_irn_mode(op2);
893 if (flags & match_mode_neutral)
894 am->ls_mode = mode_Iu;
896 if (addr->base == NULL)
897 addr->base = noreg_gp;
898 if (addr->index == NULL)
899 addr->index = noreg_gp;
900 if (addr->mem == NULL)
901 addr->mem = new_NoMem();
903 am->new_op1 = new_op1;
904 am->new_op2 = new_op2;
905 am->commutative = commutative;
908 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
913 if (am->mem_proj == NULL)
916 /* we have to create a mode_T so the old MemProj can attach to us */
917 mode = get_irn_mode(node);
918 load = get_Proj_pred(am->mem_proj);
920 mark_irn_visited(load);
921 be_set_transformed_node(load, node);
923 if (mode != mode_T) {
924 set_irn_mode(node, mode_T);
925 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
932 * Construct a standard binary operation, set AM and immediate if required.
934 * @param node The original node for which the binop is created
935 * @param op1 The first operand
936 * @param op2 The second operand
937 * @param func The node constructor function
938 * @return The constructed ia32 node.
940 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
941 construct_binop_func *func, match_flags_t flags)
944 ir_node *block, *new_block, *new_node;
945 ia32_address_mode_t am;
946 ia32_address_t *addr = &am.addr;
948 block = get_nodes_block(node);
949 match_arguments(&am, block, op1, op2, NULL, flags);
951 dbgi = get_irn_dbg_info(node);
952 new_block = be_transform_node(block);
953 new_node = func(dbgi, current_ir_graph, new_block,
954 addr->base, addr->index, addr->mem,
955 am.new_op1, am.new_op2);
956 set_am_attributes(new_node, &am);
957 /* we can't use source address mode anymore when using immediates */
958 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
959 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
960 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
962 new_node = fix_mem_proj(new_node, &am);
969 n_ia32_l_binop_right,
970 n_ia32_l_binop_eflags
972 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
973 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
974 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
975 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
976 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
977 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
980 * Construct a binary operation which also consumes the eflags.
982 * @param node The node to transform
983 * @param func The node constructor function
984 * @param flags The match flags
985 * @return The constructor ia32 node
987 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
990 ir_node *src_block = get_nodes_block(node);
991 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
992 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
994 ir_node *block, *new_node, *eflags, *new_eflags;
995 ia32_address_mode_t am;
996 ia32_address_t *addr = &am.addr;
998 match_arguments(&am, src_block, op1, op2, NULL, flags);
1000 dbgi = get_irn_dbg_info(node);
1001 block = be_transform_node(src_block);
1002 eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1003 new_eflags = be_transform_node(eflags);
1004 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
1005 addr->mem, am.new_op1, am.new_op2, new_eflags);
1006 set_am_attributes(new_node, &am);
1007 /* we can't use source address mode anymore when using immediates */
1008 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1009 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1010 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1012 new_node = fix_mem_proj(new_node, &am);
1017 static ir_node *get_fpcw(void)
1020 if (initial_fpcw != NULL)
1021 return initial_fpcw;
1023 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
1024 &ia32_fp_cw_regs[REG_FPCW]);
1025 initial_fpcw = be_transform_node(fpcw);
1027 return initial_fpcw;
1031 * Construct a standard binary operation, set AM and immediate if required.
1033 * @param op1 The first operand
1034 * @param op2 The second operand
1035 * @param func The node constructor function
1036 * @return The constructed ia32 node.
1038 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1039 construct_binop_float_func *func,
1040 match_flags_t flags)
1042 ir_mode *mode = get_irn_mode(node);
1044 ir_node *block, *new_block, *new_node;
1045 ia32_address_mode_t am;
1046 ia32_address_t *addr = &am.addr;
1048 /* cannot use address mode with long double on x87 */
1049 if (get_mode_size_bits(mode) > 64)
1052 block = get_nodes_block(node);
1053 match_arguments(&am, block, op1, op2, NULL, flags);
1055 dbgi = get_irn_dbg_info(node);
1056 new_block = be_transform_node(block);
1057 new_node = func(dbgi, current_ir_graph, new_block,
1058 addr->base, addr->index, addr->mem,
1059 am.new_op1, am.new_op2, get_fpcw());
1060 set_am_attributes(new_node, &am);
1062 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1064 new_node = fix_mem_proj(new_node, &am);
1070 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1072 * @param op1 The first operand
1073 * @param op2 The second operand
1074 * @param func The node constructor function
1075 * @return The constructed ia32 node.
1077 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1078 construct_shift_func *func,
1079 match_flags_t flags)
1082 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1084 assert(! mode_is_float(get_irn_mode(node)));
1085 assert(flags & match_immediate);
1086 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1088 if (flags & match_mode_neutral) {
1089 op1 = ia32_skip_downconv(op1);
1090 new_op1 = be_transform_node(op1);
1091 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1092 new_op1 = create_upconv(op1, node);
1094 new_op1 = be_transform_node(op1);
1097 /* the shift amount can be any mode that is bigger than 5 bits, since all
1098 * other bits are ignored anyway */
1099 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1100 op2 = get_Conv_op(op2);
1101 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1103 new_op2 = create_immediate_or_transform(op2, 0);
1105 dbgi = get_irn_dbg_info(node);
1106 block = get_nodes_block(node);
1107 new_block = be_transform_node(block);
1108 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1109 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1111 /* lowered shift instruction may have a dependency operand, handle it here */
1112 if (get_irn_arity(node) == 3) {
1113 /* we have a dependency */
1114 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1115 add_irn_dep(new_node, new_dep);
1123 * Construct a standard unary operation, set AM and immediate if required.
1125 * @param op The operand
1126 * @param func The node constructor function
1127 * @return The constructed ia32 node.
1129 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1130 match_flags_t flags)
1133 ir_node *block, *new_block, *new_op, *new_node;
1135 assert(flags == 0 || flags == match_mode_neutral);
1136 if (flags & match_mode_neutral) {
1137 op = ia32_skip_downconv(op);
1140 new_op = be_transform_node(op);
1141 dbgi = get_irn_dbg_info(node);
1142 block = get_nodes_block(node);
1143 new_block = be_transform_node(block);
1144 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1146 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1151 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1152 ia32_address_t *addr)
1154 ir_node *base, *index, *res;
1158 base = ia32_new_NoReg_gp(env_cg);
1160 base = be_transform_node(base);
1163 index = addr->index;
1164 if (index == NULL) {
1165 index = ia32_new_NoReg_gp(env_cg);
1167 index = be_transform_node(index);
1170 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1171 set_address(res, addr);
1177 * Returns non-zero if a given address mode has a symbolic or
1178 * numerical offset != 0.
1180 static int am_has_immediates(const ia32_address_t *addr)
1182 return addr->offset != 0 || addr->symconst_ent != NULL
1183 || addr->frame_entity || addr->use_frame;
1187 * Creates an ia32 Add.
1189 * @return the created ia32 Add node
1191 static ir_node *gen_Add(ir_node *node) {
1192 ir_mode *mode = get_irn_mode(node);
1193 ir_node *op1 = get_Add_left(node);
1194 ir_node *op2 = get_Add_right(node);
1196 ir_node *block, *new_block, *new_node, *add_immediate_op;
1197 ia32_address_t addr;
1198 ia32_address_mode_t am;
1200 if (mode_is_float(mode)) {
1201 if (ia32_cg_config.use_sse2)
1202 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1203 match_commutative | match_am);
1205 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1206 match_commutative | match_am);
1209 ia32_mark_non_am(node);
1211 op2 = ia32_skip_downconv(op2);
1212 op1 = ia32_skip_downconv(op1);
1216 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1217 * 1. Add with immediate -> Lea
1218 * 2. Add with possible source address mode -> Add
1219 * 3. Otherwise -> Lea
1221 memset(&addr, 0, sizeof(addr));
1222 ia32_create_address_mode(&addr, node, /*force=*/1);
1223 add_immediate_op = NULL;
1225 dbgi = get_irn_dbg_info(node);
1226 block = get_nodes_block(node);
1227 new_block = be_transform_node(block);
1230 if(addr.base == NULL && addr.index == NULL) {
1231 ir_graph *irg = current_ir_graph;
1232 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1233 addr.symconst_sign, addr.offset);
1234 add_irn_dep(new_node, get_irg_frame(irg));
1235 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1238 /* add with immediate? */
1239 if(addr.index == NULL) {
1240 add_immediate_op = addr.base;
1241 } else if(addr.base == NULL && addr.scale == 0) {
1242 add_immediate_op = addr.index;
1245 if(add_immediate_op != NULL) {
1246 if(!am_has_immediates(&addr)) {
1247 #ifdef DEBUG_libfirm
1248 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1251 return be_transform_node(add_immediate_op);
1254 new_node = create_lea_from_address(dbgi, new_block, &addr);
1255 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1259 /* test if we can use source address mode */
1260 match_arguments(&am, block, op1, op2, NULL, match_commutative
1261 | match_mode_neutral | match_am | match_immediate | match_try_am);
1263 /* construct an Add with source address mode */
1264 if (am.op_type == ia32_AddrModeS) {
1265 ir_graph *irg = current_ir_graph;
1266 ia32_address_t *am_addr = &am.addr;
1267 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1268 am_addr->index, am_addr->mem, am.new_op1,
1270 set_am_attributes(new_node, &am);
1271 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1273 new_node = fix_mem_proj(new_node, &am);
1278 /* otherwise construct a lea */
1279 new_node = create_lea_from_address(dbgi, new_block, &addr);
1280 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1285 * Creates an ia32 Mul.
1287 * @return the created ia32 Mul node
1289 static ir_node *gen_Mul(ir_node *node) {
1290 ir_node *op1 = get_Mul_left(node);
1291 ir_node *op2 = get_Mul_right(node);
1292 ir_mode *mode = get_irn_mode(node);
1294 if (mode_is_float(mode)) {
1295 if (ia32_cg_config.use_sse2)
1296 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1297 match_commutative | match_am);
1299 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1300 match_commutative | match_am);
1302 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1303 match_commutative | match_am | match_mode_neutral |
1304 match_immediate | match_am_and_immediates);
1308 * Creates an ia32 Mulh.
1309 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1310 * this result while Mul returns the lower 32 bit.
1312 * @return the created ia32 Mulh node
1314 static ir_node *gen_Mulh(ir_node *node)
1316 ir_node *block = get_nodes_block(node);
1317 ir_node *new_block = be_transform_node(block);
1318 ir_graph *irg = current_ir_graph;
1319 dbg_info *dbgi = get_irn_dbg_info(node);
1320 ir_mode *mode = get_irn_mode(node);
1321 ir_node *op1 = get_Mulh_left(node);
1322 ir_node *op2 = get_Mulh_right(node);
1323 ir_node *proj_res_high;
1325 ia32_address_mode_t am;
1326 ia32_address_t *addr = &am.addr;
1328 assert(!mode_is_float(mode) && "Mulh with float not supported");
1329 assert(get_mode_size_bits(mode) == 32);
1331 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1333 if (mode_is_signed(mode)) {
1334 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1335 addr->index, addr->mem, am.new_op1,
1338 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1339 addr->index, addr->mem, am.new_op1,
1343 set_am_attributes(new_node, &am);
1344 /* we can't use source address mode anymore when using immediates */
1345 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1346 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1347 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1349 assert(get_irn_mode(new_node) == mode_T);
1351 fix_mem_proj(new_node, &am);
1353 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1354 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1355 mode_Iu, pn_ia32_IMul1OP_res_high);
1357 return proj_res_high;
1363 * Creates an ia32 And.
1365 * @return The created ia32 And node
1367 static ir_node *gen_And(ir_node *node) {
1368 ir_node *op1 = get_And_left(node);
1369 ir_node *op2 = get_And_right(node);
1370 assert(! mode_is_float(get_irn_mode(node)));
1372 /* is it a zero extension? */
1373 if (is_Const(op2)) {
1374 tarval *tv = get_Const_tarval(op2);
1375 long v = get_tarval_long(tv);
1377 if (v == 0xFF || v == 0xFFFF) {
1378 dbg_info *dbgi = get_irn_dbg_info(node);
1379 ir_node *block = get_nodes_block(node);
1386 assert(v == 0xFFFF);
1389 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1394 return gen_binop(node, op1, op2, new_rd_ia32_And,
1395 match_commutative | match_mode_neutral | match_am
1402 * Creates an ia32 Or.
1404 * @return The created ia32 Or node
1406 static ir_node *gen_Or(ir_node *node) {
1407 ir_node *op1 = get_Or_left(node);
1408 ir_node *op2 = get_Or_right(node);
1410 assert (! mode_is_float(get_irn_mode(node)));
1411 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1412 | match_mode_neutral | match_am | match_immediate);
1418 * Creates an ia32 Eor.
1420 * @return The created ia32 Eor node
1422 static ir_node *gen_Eor(ir_node *node) {
1423 ir_node *op1 = get_Eor_left(node);
1424 ir_node *op2 = get_Eor_right(node);
1426 assert(! mode_is_float(get_irn_mode(node)));
1427 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1428 | match_mode_neutral | match_am | match_immediate);
1433 * Creates an ia32 Sub.
1435 * @return The created ia32 Sub node
1437 static ir_node *gen_Sub(ir_node *node) {
1438 ir_node *op1 = get_Sub_left(node);
1439 ir_node *op2 = get_Sub_right(node);
1440 ir_mode *mode = get_irn_mode(node);
1442 if (mode_is_float(mode)) {
1443 if (ia32_cg_config.use_sse2)
1444 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1446 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1450 if (is_Const(op2)) {
1451 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1455 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1456 | match_am | match_immediate);
1460 * Generates an ia32 DivMod with additional infrastructure for the
1461 * register allocator if needed.
1463 static ir_node *create_Div(ir_node *node)
1465 ir_graph *irg = current_ir_graph;
1466 dbg_info *dbgi = get_irn_dbg_info(node);
1467 ir_node *block = get_nodes_block(node);
1468 ir_node *new_block = be_transform_node(block);
1475 ir_node *sign_extension;
1476 ia32_address_mode_t am;
1477 ia32_address_t *addr = &am.addr;
1479 /* the upper bits have random contents for smaller modes */
1480 switch (get_irn_opcode(node)) {
1482 op1 = get_Div_left(node);
1483 op2 = get_Div_right(node);
1484 mem = get_Div_mem(node);
1485 mode = get_Div_resmode(node);
1488 op1 = get_Mod_left(node);
1489 op2 = get_Mod_right(node);
1490 mem = get_Mod_mem(node);
1491 mode = get_Mod_resmode(node);
1494 op1 = get_DivMod_left(node);
1495 op2 = get_DivMod_right(node);
1496 mem = get_DivMod_mem(node);
1497 mode = get_DivMod_resmode(node);
1500 panic("invalid divmod node %+F", node);
1503 match_arguments(&am, block, op1, op2, NULL, match_am);
1505 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1506 is the memory of the consumed address. We can have only the second op as address
1507 in Div nodes, so check only op2. */
1508 if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1509 new_mem = be_transform_node(mem);
1510 if(!is_NoMem(addr->mem)) {
1514 new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1517 new_mem = addr->mem;
1520 if (mode_is_signed(mode)) {
1521 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1522 add_irn_dep(produceval, get_irg_frame(irg));
1523 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1526 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1527 addr->index, new_mem, am.new_op2,
1528 am.new_op1, sign_extension);
1530 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1531 add_irn_dep(sign_extension, get_irg_frame(irg));
1533 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1534 addr->index, new_mem, am.new_op2,
1535 am.new_op1, sign_extension);
1538 set_irn_pinned(new_node, get_irn_pinned(node));
1540 set_am_attributes(new_node, &am);
1541 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1543 new_node = fix_mem_proj(new_node, &am);
1549 static ir_node *gen_Mod(ir_node *node) {
1550 return create_Div(node);
1553 static ir_node *gen_Div(ir_node *node) {
1554 return create_Div(node);
1557 static ir_node *gen_DivMod(ir_node *node) {
1558 return create_Div(node);
1564 * Creates an ia32 floating Div.
1566 * @return The created ia32 xDiv node
1568 static ir_node *gen_Quot(ir_node *node)
1570 ir_node *op1 = get_Quot_left(node);
1571 ir_node *op2 = get_Quot_right(node);
1573 if (ia32_cg_config.use_sse2) {
1574 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1576 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1582 * Creates an ia32 Shl.
1584 * @return The created ia32 Shl node
1586 static ir_node *gen_Shl(ir_node *node) {
1587 ir_node *left = get_Shl_left(node);
1588 ir_node *right = get_Shl_right(node);
1590 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1591 match_mode_neutral | match_immediate);
1595 * Creates an ia32 Shr.
1597 * @return The created ia32 Shr node
1599 static ir_node *gen_Shr(ir_node *node) {
1600 ir_node *left = get_Shr_left(node);
1601 ir_node *right = get_Shr_right(node);
1603 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1609 * Creates an ia32 Sar.
1611 * @return The created ia32 Shrs node
1613 static ir_node *gen_Shrs(ir_node *node) {
1614 ir_node *left = get_Shrs_left(node);
1615 ir_node *right = get_Shrs_right(node);
1616 ir_mode *mode = get_irn_mode(node);
1618 if(is_Const(right) && mode == mode_Is) {
1619 tarval *tv = get_Const_tarval(right);
1620 long val = get_tarval_long(tv);
1622 /* this is a sign extension */
1623 ir_graph *irg = current_ir_graph;
1624 dbg_info *dbgi = get_irn_dbg_info(node);
1625 ir_node *block = be_transform_node(get_nodes_block(node));
1627 ir_node *new_op = be_transform_node(op);
1628 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1629 add_irn_dep(pval, get_irg_frame(irg));
1631 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1635 /* 8 or 16 bit sign extension? */
1636 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1637 ir_node *shl_left = get_Shl_left(left);
1638 ir_node *shl_right = get_Shl_right(left);
1639 if(is_Const(shl_right)) {
1640 tarval *tv1 = get_Const_tarval(right);
1641 tarval *tv2 = get_Const_tarval(shl_right);
1642 if(tv1 == tv2 && tarval_is_long(tv1)) {
1643 long val = get_tarval_long(tv1);
1644 if(val == 16 || val == 24) {
1645 dbg_info *dbgi = get_irn_dbg_info(node);
1646 ir_node *block = get_nodes_block(node);
1656 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1665 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1671 * Creates an ia32 Rol.
1673 * @param op1 The first operator
1674 * @param op2 The second operator
1675 * @return The created ia32 RotL node
1677 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1678 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1684 * Creates an ia32 Ror.
1685 * NOTE: There is no RotR with immediate because this would always be a RotL
1686 * "imm-mode_size_bits" which can be pre-calculated.
1688 * @param op1 The first operator
1689 * @param op2 The second operator
1690 * @return The created ia32 RotR node
1692 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1693 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1699 * Creates an ia32 RotR or RotL (depending on the found pattern).
1701 * @return The created ia32 RotL or RotR node
1703 static ir_node *gen_Rotl(ir_node *node) {
1704 ir_node *rotate = NULL;
1705 ir_node *op1 = get_Rotl_left(node);
1706 ir_node *op2 = get_Rotl_right(node);
1708 /* Firm has only RotL, so we are looking for a right (op2)
1709 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1710 that means we can create a RotR instead of an Add and a RotL */
1714 ir_node *left = get_Add_left(add);
1715 ir_node *right = get_Add_right(add);
1716 if (is_Const(right)) {
1717 tarval *tv = get_Const_tarval(right);
1718 ir_mode *mode = get_irn_mode(node);
1719 long bits = get_mode_size_bits(mode);
1721 if (is_Minus(left) &&
1722 tarval_is_long(tv) &&
1723 get_tarval_long(tv) == bits &&
1726 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1727 rotate = gen_Ror(node, op1, get_Minus_op(left));
1732 if (rotate == NULL) {
1733 rotate = gen_Rol(node, op1, op2);
1742 * Transforms a Minus node.
1744 * @return The created ia32 Minus node
1746 static ir_node *gen_Minus(ir_node *node)
1748 ir_node *op = get_Minus_op(node);
1749 ir_node *block = be_transform_node(get_nodes_block(node));
1750 ir_graph *irg = current_ir_graph;
1751 dbg_info *dbgi = get_irn_dbg_info(node);
1752 ir_mode *mode = get_irn_mode(node);
1757 if (mode_is_float(mode)) {
1758 ir_node *new_op = be_transform_node(op);
1759 if (ia32_cg_config.use_sse2) {
1760 /* TODO: non-optimal... if we have many xXors, then we should
1761 * rather create a load for the const and use that instead of
1762 * several AM nodes... */
1763 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1764 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1765 ir_node *nomem = new_rd_NoMem(irg);
1767 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1768 nomem, new_op, noreg_xmm);
1770 size = get_mode_size_bits(mode);
1771 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1773 set_ia32_am_sc(new_node, ent);
1774 set_ia32_op_type(new_node, ia32_AddrModeS);
1775 set_ia32_ls_mode(new_node, mode);
1777 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1780 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1783 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1789 * Transforms a Not node.
1791 * @return The created ia32 Not node
1793 static ir_node *gen_Not(ir_node *node) {
1794 ir_node *op = get_Not_op(node);
1796 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1797 assert (! mode_is_float(get_irn_mode(node)));
1799 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1805 * Transforms an Abs node.
1807 * @return The created ia32 Abs node
1809 static ir_node *gen_Abs(ir_node *node)
1811 ir_node *block = get_nodes_block(node);
1812 ir_node *new_block = be_transform_node(block);
1813 ir_node *op = get_Abs_op(node);
1814 ir_graph *irg = current_ir_graph;
1815 dbg_info *dbgi = get_irn_dbg_info(node);
1816 ir_mode *mode = get_irn_mode(node);
1817 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1818 ir_node *nomem = new_NoMem();
1824 if (mode_is_float(mode)) {
1825 new_op = be_transform_node(op);
1827 if (ia32_cg_config.use_sse2) {
1828 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1829 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1830 nomem, new_op, noreg_fp);
1832 size = get_mode_size_bits(mode);
1833 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1835 set_ia32_am_sc(new_node, ent);
1837 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1839 set_ia32_op_type(new_node, ia32_AddrModeS);
1840 set_ia32_ls_mode(new_node, mode);
1842 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1843 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1846 ir_node *xor, *pval, *sign_extension;
1848 if (get_mode_size_bits(mode) == 32) {
1849 new_op = be_transform_node(op);
1851 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1854 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1855 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1858 add_irn_dep(pval, get_irg_frame(irg));
1859 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1861 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1862 nomem, new_op, sign_extension);
1863 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1865 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1866 nomem, xor, sign_extension);
1867 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1874 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1876 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1877 dbg_info *dbgi = get_irn_dbg_info(cmp);
1878 ir_node *block = get_nodes_block(cmp);
1879 ir_node *new_block = be_transform_node(block);
1880 ir_node *op1 = be_transform_node(x);
1881 ir_node *op2 = be_transform_node(n);
1883 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1887 * Transform a node returning a "flag" result.
1889 * @param node the node to transform
1890 * @param pnc_out the compare mode to use
1892 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1901 /* we have a Cmp as input */
1902 if (is_Proj(node)) {
1903 ir_node *pred = get_Proj_pred(node);
1905 pn_Cmp pnc = get_Proj_proj(node);
1906 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1907 ir_node *l = get_Cmp_left(pred);
1908 ir_node *r = get_Cmp_right(pred);
1910 ir_node *la = get_And_left(l);
1911 ir_node *ra = get_And_right(l);
1913 ir_node *c = get_Shl_left(la);
1914 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1915 /* (1 << n) & ra) */
1916 ir_node *n = get_Shl_right(la);
1917 flags = gen_bt(pred, ra, n);
1918 /* we must generate a Jc/Jnc jump */
1919 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1922 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1927 ir_node *c = get_Shl_left(ra);
1928 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1929 /* la & (1 << n)) */
1930 ir_node *n = get_Shl_right(ra);
1931 flags = gen_bt(pred, la, n);
1932 /* we must generate a Jc/Jnc jump */
1933 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1936 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1942 flags = be_transform_node(pred);
1948 /* a mode_b value, we have to compare it against 0 */
1949 dbgi = get_irn_dbg_info(node);
1950 new_block = be_transform_node(get_nodes_block(node));
1951 new_op = be_transform_node(node);
1952 noreg = ia32_new_NoReg_gp(env_cg);
1953 nomem = new_NoMem();
1954 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1955 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1956 *pnc_out = pn_Cmp_Lg;
1961 * Transforms a Load.
1963 * @return the created ia32 Load node
1965 static ir_node *gen_Load(ir_node *node) {
1966 ir_node *old_block = get_nodes_block(node);
1967 ir_node *block = be_transform_node(old_block);
1968 ir_node *ptr = get_Load_ptr(node);
1969 ir_node *mem = get_Load_mem(node);
1970 ir_node *new_mem = be_transform_node(mem);
1973 ir_graph *irg = current_ir_graph;
1974 dbg_info *dbgi = get_irn_dbg_info(node);
1975 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1976 ir_mode *mode = get_Load_mode(node);
1979 ia32_address_t addr;
1981 /* construct load address */
1982 memset(&addr, 0, sizeof(addr));
1983 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1990 base = be_transform_node(base);
1996 index = be_transform_node(index);
1999 if (mode_is_float(mode)) {
2000 if (ia32_cg_config.use_sse2) {
2001 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
2003 res_mode = mode_xmm;
2005 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
2007 res_mode = mode_vfp;
2010 assert(mode != mode_b);
2012 /* create a conv node with address mode for smaller modes */
2013 if(get_mode_size_bits(mode) < 32) {
2014 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
2015 new_mem, noreg, mode);
2017 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
2022 set_irn_pinned(new_node, get_irn_pinned(node));
2023 set_ia32_op_type(new_node, ia32_AddrModeS);
2024 set_ia32_ls_mode(new_node, mode);
2025 set_address(new_node, &addr);
2027 if(get_irn_pinned(node) == op_pin_state_floats) {
2028 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
2031 /* make sure we are scheduled behind the initial IncSP/Barrier
2032 * to avoid spills being placed before it
2034 if (block == get_irg_start_block(irg)) {
2035 add_irn_dep(new_node, get_irg_frame(irg));
2038 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2043 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2044 ir_node *ptr, ir_node *other)
2051 /* we only use address mode if we're the only user of the load */
2052 if(get_irn_n_edges(node) > 1)
2055 load = get_Proj_pred(node);
2058 if(get_nodes_block(load) != block)
2061 /* Store should be attached to the load */
2062 if(!is_Proj(mem) || get_Proj_pred(mem) != load)
2064 /* store should have the same pointer as the load */
2065 if(get_Load_ptr(load) != ptr)
2068 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2069 if(other != NULL && get_nodes_block(other) == block
2070 && heights_reachable_in_block(heights, other, load))
2076 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2077 ir_node *mem, ir_node *ptr, ir_mode *mode,
2078 construct_binop_dest_func *func,
2079 construct_binop_dest_func *func8bit,
2080 match_flags_t flags)
2082 ir_node *src_block = get_nodes_block(node);
2084 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2085 ir_graph *irg = current_ir_graph;
2090 ia32_address_mode_t am;
2091 ia32_address_t *addr = &am.addr;
2092 memset(&am, 0, sizeof(am));
2094 assert(flags & match_dest_am);
2095 assert(flags & match_immediate); /* there is no destam node without... */
2096 commutative = (flags & match_commutative) != 0;
2098 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2099 build_address(&am, op1);
2100 new_op = create_immediate_or_transform(op2, 0);
2101 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2102 build_address(&am, op2);
2103 new_op = create_immediate_or_transform(op1, 0);
2108 if(addr->base == NULL)
2109 addr->base = noreg_gp;
2110 if(addr->index == NULL)
2111 addr->index = noreg_gp;
2112 if(addr->mem == NULL)
2113 addr->mem = new_NoMem();
2115 dbgi = get_irn_dbg_info(node);
2116 block = be_transform_node(src_block);
2117 if(get_mode_size_bits(mode) == 8) {
2118 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2121 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
2124 set_address(new_node, addr);
2125 set_ia32_op_type(new_node, ia32_AddrModeD);
2126 set_ia32_ls_mode(new_node, mode);
2127 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2132 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2133 ir_node *ptr, ir_mode *mode,
2134 construct_unop_dest_func *func)
2136 ir_graph *irg = current_ir_graph;
2137 ir_node *src_block = get_nodes_block(node);
2141 ia32_address_mode_t am;
2142 ia32_address_t *addr = &am.addr;
2143 memset(&am, 0, sizeof(am));
2145 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2148 build_address(&am, op);
2150 dbgi = get_irn_dbg_info(node);
2151 block = be_transform_node(src_block);
2152 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2153 set_address(new_node, addr);
2154 set_ia32_op_type(new_node, ia32_AddrModeD);
2155 set_ia32_ls_mode(new_node, mode);
2156 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2161 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2162 ir_mode *mode = get_irn_mode(node);
2163 ir_node *psi_true = get_Psi_val(node, 0);
2164 ir_node *psi_default = get_Psi_default(node);
2175 ia32_address_t addr;
2177 if(get_mode_size_bits(mode) != 8)
2180 if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2182 } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2188 build_address_ptr(&addr, ptr, mem);
2190 irg = current_ir_graph;
2191 dbgi = get_irn_dbg_info(node);
2192 block = get_nodes_block(node);
2193 new_block = be_transform_node(block);
2194 cond = get_Psi_cond(node, 0);
2195 flags = get_flags_node(cond, &pnc);
2196 new_mem = be_transform_node(mem);
2197 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2198 addr.index, addr.mem, flags, pnc, negated);
2199 set_address(new_node, &addr);
2200 set_ia32_op_type(new_node, ia32_AddrModeD);
2201 set_ia32_ls_mode(new_node, mode);
2202 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2207 static ir_node *try_create_dest_am(ir_node *node) {
2208 ir_node *val = get_Store_value(node);
2209 ir_node *mem = get_Store_mem(node);
2210 ir_node *ptr = get_Store_ptr(node);
2211 ir_mode *mode = get_irn_mode(val);
2212 unsigned bits = get_mode_size_bits(mode);
2217 /* handle only GP modes for now... */
2218 if(!mode_needs_gp_reg(mode))
2222 /* store must be the only user of the val node */
2223 if(get_irn_n_edges(val) > 1)
2225 /* skip pointless convs */
2227 ir_node *conv_op = get_Conv_op(val);
2228 ir_mode *pred_mode = get_irn_mode(conv_op);
2229 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2237 /* value must be in the same block */
2238 if(get_nodes_block(node) != get_nodes_block(val))
2241 switch (get_irn_opcode(val)) {
2243 op1 = get_Add_left(val);
2244 op2 = get_Add_right(val);
2245 if(is_Const_1(op2)) {
2246 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2247 new_rd_ia32_IncMem);
2249 } else if(is_Const_Minus_1(op2)) {
2250 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2251 new_rd_ia32_DecMem);
2254 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2255 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2256 match_dest_am | match_commutative |
2260 op1 = get_Sub_left(val);
2261 op2 = get_Sub_right(val);
2263 ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2266 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2267 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2268 match_dest_am | match_immediate |
2272 op1 = get_And_left(val);
2273 op2 = get_And_right(val);
2274 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2275 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2276 match_dest_am | match_commutative |
2280 op1 = get_Or_left(val);
2281 op2 = get_Or_right(val);
2282 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2283 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2284 match_dest_am | match_commutative |
2288 op1 = get_Eor_left(val);
2289 op2 = get_Eor_right(val);
2290 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2291 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2292 match_dest_am | match_commutative |
2296 op1 = get_Shl_left(val);
2297 op2 = get_Shl_right(val);
2298 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2299 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2300 match_dest_am | match_immediate);
2303 op1 = get_Shr_left(val);
2304 op2 = get_Shr_right(val);
2305 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2306 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2307 match_dest_am | match_immediate);
2310 op1 = get_Shrs_left(val);
2311 op2 = get_Shrs_right(val);
2312 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2313 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2314 match_dest_am | match_immediate);
2317 op1 = get_Rotl_left(val);
2318 op2 = get_Rotl_right(val);
2319 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2320 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2321 match_dest_am | match_immediate);
2323 /* TODO: match ROR patterns... */
2325 new_node = try_create_SetMem(val, ptr, mem);
2328 op1 = get_Minus_op(val);
2329 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2332 /* should be lowered already */
2333 assert(mode != mode_b);
2334 op1 = get_Not_op(val);
2335 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2341 if(new_node != NULL) {
2342 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2343 get_irn_pinned(node) == op_pin_state_pinned) {
2344 set_irn_pinned(new_node, op_pin_state_pinned);
2351 static int is_float_to_int32_conv(const ir_node *node)
2353 ir_mode *mode = get_irn_mode(node);
2357 if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode))
2362 conv_op = get_Conv_op(node);
2363 conv_mode = get_irn_mode(conv_op);
2365 if(!mode_is_float(conv_mode))
2372 * Transform a Store(floatConst).
2374 * @return the created ia32 Store node
2376 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2377 ir_mode *mode = get_irn_mode(cns);
2378 int size = get_mode_size_bits(mode);
2379 tarval *tv = get_Const_tarval(cns);
2380 ir_node *block = get_nodes_block(node);
2381 ir_node *new_block = be_transform_node(block);
2382 ir_node *ptr = get_Store_ptr(node);
2383 ir_node *mem = get_Store_mem(node);
2384 ir_graph *irg = current_ir_graph;
2385 dbg_info *dbgi = get_irn_dbg_info(node);
2386 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2389 ia32_address_t addr;
2391 unsigned val = get_tarval_sub_bits(tv, 0) |
2392 (get_tarval_sub_bits(tv, 1) << 8) |
2393 (get_tarval_sub_bits(tv, 2) << 16) |
2394 (get_tarval_sub_bits(tv, 3) << 24);
2395 ir_node *imm = create_Immediate(NULL, 0, val);
2397 /* construct store address */
2398 memset(&addr, 0, sizeof(addr));
2399 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2401 if (addr.base == NULL) {
2404 addr.base = be_transform_node(addr.base);
2407 if (addr.index == NULL) {
2410 addr.index = be_transform_node(addr.index);
2412 addr.mem = be_transform_node(mem);
2414 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2415 addr.index, addr.mem, imm);
2417 set_irn_pinned(new_node, get_irn_pinned(node));
2418 set_ia32_op_type(new_node, ia32_AddrModeD);
2419 set_ia32_ls_mode(new_node, mode_Iu);
2421 set_address(new_node, &addr);
2423 /** add more stores if needed */
2425 unsigned val = get_tarval_sub_bits(tv, ofs) |
2426 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2427 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2428 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2429 ir_node *imm = create_Immediate(NULL, 0, val);
2432 addr.mem = new_node;
2434 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2435 addr.index, addr.mem, imm);
2437 set_irn_pinned(new_node, get_irn_pinned(node));
2438 set_ia32_op_type(new_node, ia32_AddrModeD);
2439 set_ia32_ls_mode(new_node, mode_Iu);
2441 set_address(new_node, &addr);
2446 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2451 * Generate a vfist or vfisttp instruction.
2453 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2454 ir_node *mem, ir_node *val, ir_node **fist)
2458 if (ia32_cg_config.use_fisttp) {
2459 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2460 if other users exists */
2461 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2462 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2463 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2464 be_new_Keep(reg_class, irg, block, 1, &value);
2466 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2469 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2472 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2478 * Transforms a normal Store.
2480 * @return the created ia32 Store node
2482 static ir_node *gen_normal_Store(ir_node *node)
2484 ir_node *val = get_Store_value(node);
2485 ir_mode *mode = get_irn_mode(val);
2486 ir_node *block = get_nodes_block(node);
2487 ir_node *new_block = be_transform_node(block);
2488 ir_node *ptr = get_Store_ptr(node);
2489 ir_node *mem = get_Store_mem(node);
2490 ir_graph *irg = current_ir_graph;
2491 dbg_info *dbgi = get_irn_dbg_info(node);
2492 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2493 ir_node *new_val, *new_node, *store;
2494 ia32_address_t addr;
2496 /* check for destination address mode */
2497 new_node = try_create_dest_am(node);
2498 if (new_node != NULL)
2501 /* construct store address */
2502 memset(&addr, 0, sizeof(addr));
2503 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2505 if (addr.base == NULL) {
2508 addr.base = be_transform_node(addr.base);
2511 if (addr.index == NULL) {
2514 addr.index = be_transform_node(addr.index);
2516 addr.mem = be_transform_node(mem);
2518 if (mode_is_float(mode)) {
2519 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2521 while (is_Conv(val) && mode == get_irn_mode(val)) {
2522 ir_node *op = get_Conv_op(val);
2523 if (!mode_is_float(get_irn_mode(op)))
2527 new_val = be_transform_node(val);
2528 if (ia32_cg_config.use_sse2) {
2529 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2530 addr.index, addr.mem, new_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 dbg_info *dbgi = get_irn_dbg_info(node);
4321 ir_node *op = get_IJmp_target(node);
4323 ia32_address_mode_t am;
4324 ia32_address_t *addr = &am.addr;
4326 assert(get_irn_mode(op) == mode_P);
4328 match_arguments(&am, block, NULL, op, NULL,
4329 match_am | match_8bit_am | match_16bit_am |
4330 match_immediate | match_8bit | match_16bit);
4332 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
4333 addr->base, addr->index, addr->mem,
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);
4344 * Transform a Bound node.
4346 static ir_node *gen_Bound(ir_node *node)
4349 ir_node *lower = get_Bound_lower(node);
4350 dbg_info *dbgi = get_irn_dbg_info(node);
4352 if (is_Const_0(lower)) {
4353 /* typical case for Java */
4354 ir_node *sub, *res, *flags, *block;
4355 ir_graph *irg = current_ir_graph;
4357 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
4358 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
4360 block = get_nodes_block(res);
4361 if (! is_Proj(res)) {
4363 set_irn_mode(sub, mode_T);
4364 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
4366 sub = get_Proj_pred(res);
4368 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
4369 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
4370 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4372 panic("generic Bound not supported in ia32 Backend");
4378 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4381 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4382 ir_node *val, ir_node *mem);
4385 * Transforms a lowered Load into a "real" one.
4387 static ir_node *gen_lowered_Load(ir_node *node, construct_load_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 *mem = get_irn_n(node, 1);
4393 ir_node *new_mem = be_transform_node(mem);
4394 ir_graph *irg = current_ir_graph;
4395 dbg_info *dbgi = get_irn_dbg_info(node);
4396 ir_mode *mode = get_ia32_ls_mode(node);
4397 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4400 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4402 set_ia32_op_type(new_op, ia32_AddrModeS);
4403 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4404 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4405 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4406 if (is_ia32_am_sc_sign(node))
4407 set_ia32_am_sc_sign(new_op);
4408 set_ia32_ls_mode(new_op, mode);
4409 if (is_ia32_use_frame(node)) {
4410 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4411 set_ia32_use_frame(new_op);
4414 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4420 * Transforms a lowered Store into a "real" one.
4422 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4424 ir_node *block = be_transform_node(get_nodes_block(node));
4425 ir_node *ptr = get_irn_n(node, 0);
4426 ir_node *new_ptr = be_transform_node(ptr);
4427 ir_node *val = get_irn_n(node, 1);
4428 ir_node *new_val = be_transform_node(val);
4429 ir_node *mem = get_irn_n(node, 2);
4430 ir_node *new_mem = be_transform_node(mem);
4431 ir_graph *irg = current_ir_graph;
4432 dbg_info *dbgi = get_irn_dbg_info(node);
4433 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4434 ir_mode *mode = get_ia32_ls_mode(node);
4438 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4440 am_offs = get_ia32_am_offs_int(node);
4441 add_ia32_am_offs_int(new_op, am_offs);
4443 set_ia32_op_type(new_op, ia32_AddrModeD);
4444 set_ia32_ls_mode(new_op, mode);
4445 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4446 set_ia32_use_frame(new_op);
4448 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4453 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4455 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4456 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4458 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4459 match_immediate | match_mode_neutral);
4462 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4464 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4465 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4466 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4470 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4472 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4473 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4474 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4478 static ir_node *gen_ia32_l_Add(ir_node *node) {
4479 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4480 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4481 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4482 match_commutative | match_am | match_immediate |
4483 match_mode_neutral);
4485 if(is_Proj(lowered)) {
4486 lowered = get_Proj_pred(lowered);
4488 assert(is_ia32_Add(lowered));
4489 set_irn_mode(lowered, mode_T);
4495 static ir_node *gen_ia32_l_Adc(ir_node *node)
4497 return gen_binop_flags(node, new_rd_ia32_Adc,
4498 match_commutative | match_am | match_immediate |
4499 match_mode_neutral);
4503 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4505 * @param node The node to transform
4506 * @return the created ia32 vfild node
4508 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4509 return gen_lowered_Load(node, new_rd_ia32_vfild);
4513 * Transforms an ia32_l_Load into a "real" ia32_Load node
4515 * @param node The node to transform
4516 * @return the created ia32 Load node
4518 static ir_node *gen_ia32_l_Load(ir_node *node) {
4519 return gen_lowered_Load(node, new_rd_ia32_Load);
4523 * Transforms an ia32_l_Store into a "real" ia32_Store node
4525 * @param node The node to transform
4526 * @return the created ia32 Store node
4528 static ir_node *gen_ia32_l_Store(ir_node *node) {
4529 return gen_lowered_Store(node, new_rd_ia32_Store);
4533 * Transforms a l_vfist into a "real" vfist node.
4535 * @param node The node to transform
4536 * @return the created ia32 vfist node
4538 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4539 ir_node *block = be_transform_node(get_nodes_block(node));
4540 ir_node *ptr = get_irn_n(node, 0);
4541 ir_node *new_ptr = be_transform_node(ptr);
4542 ir_node *val = get_irn_n(node, 1);
4543 ir_node *new_val = be_transform_node(val);
4544 ir_node *mem = get_irn_n(node, 2);
4545 ir_node *new_mem = be_transform_node(mem);
4546 ir_graph *irg = current_ir_graph;
4547 dbg_info *dbgi = get_irn_dbg_info(node);
4548 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4549 ir_mode *mode = get_ia32_ls_mode(node);
4550 ir_node *memres, *fist;
4553 memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
4554 am_offs = get_ia32_am_offs_int(node);
4555 add_ia32_am_offs_int(fist, am_offs);
4557 set_ia32_op_type(fist, ia32_AddrModeD);
4558 set_ia32_ls_mode(fist, mode);
4559 set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
4560 set_ia32_use_frame(fist);
4562 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4568 * Transforms a l_MulS into a "real" MulS node.
4570 * @return the created ia32 Mul node
4572 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4573 ir_node *left = get_binop_left(node);
4574 ir_node *right = get_binop_right(node);
4576 return gen_binop(node, left, right, new_rd_ia32_Mul,
4577 match_commutative | match_am | match_mode_neutral);
4581 * Transforms a l_IMulS into a "real" IMul1OPS node.
4583 * @return the created ia32 IMul1OP node
4585 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4586 ir_node *left = get_binop_left(node);
4587 ir_node *right = get_binop_right(node);
4589 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4590 match_commutative | match_am | match_mode_neutral);
4593 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4594 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4595 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4596 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4597 match_am | match_immediate | match_mode_neutral);
4599 if(is_Proj(lowered)) {
4600 lowered = get_Proj_pred(lowered);
4602 assert(is_ia32_Sub(lowered));
4603 set_irn_mode(lowered, mode_T);
4609 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4610 return gen_binop_flags(node, new_rd_ia32_Sbb,
4611 match_am | match_immediate | match_mode_neutral);
4615 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4616 * op1 - target to be shifted
4617 * op2 - contains bits to be shifted into target
4619 * Only op3 can be an immediate.
4621 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4622 ir_node *low, ir_node *count)
4624 ir_node *block = get_nodes_block(node);
4625 ir_node *new_block = be_transform_node(block);
4626 ir_graph *irg = current_ir_graph;
4627 dbg_info *dbgi = get_irn_dbg_info(node);
4628 ir_node *new_high = be_transform_node(high);
4629 ir_node *new_low = be_transform_node(low);
4633 /* the shift amount can be any mode that is bigger than 5 bits, since all
4634 * other bits are ignored anyway */
4635 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4636 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4637 count = get_Conv_op(count);
4639 new_count = create_immediate_or_transform(count, 0);
4641 if (is_ia32_l_ShlD(node)) {
4642 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4645 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4648 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4653 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4655 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4656 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4657 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4658 return gen_lowered_64bit_shifts(node, high, low, count);
4661 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4663 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4664 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4665 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4666 return gen_lowered_64bit_shifts(node, high, low, count);
4669 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4670 ir_node *src_block = get_nodes_block(node);
4671 ir_node *block = be_transform_node(src_block);
4672 ir_graph *irg = current_ir_graph;
4673 dbg_info *dbgi = get_irn_dbg_info(node);
4674 ir_node *frame = get_irg_frame(irg);
4675 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4676 ir_node *nomem = new_NoMem();
4677 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4678 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4679 ir_node *new_val_low = be_transform_node(val_low);
4680 ir_node *new_val_high = be_transform_node(val_high);
4685 ir_node *store_high;
4687 if(!mode_is_signed(get_irn_mode(val_high))) {
4688 panic("unsigned long long -> float not supported yet (%+F)", node);
4692 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4694 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4696 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4697 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4699 set_ia32_use_frame(store_low);
4700 set_ia32_use_frame(store_high);
4701 set_ia32_op_type(store_low, ia32_AddrModeD);
4702 set_ia32_op_type(store_high, ia32_AddrModeD);
4703 set_ia32_ls_mode(store_low, mode_Iu);
4704 set_ia32_ls_mode(store_high, mode_Is);
4705 add_ia32_am_offs_int(store_high, 4);
4709 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4712 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4714 set_ia32_use_frame(fild);
4715 set_ia32_op_type(fild, ia32_AddrModeS);
4716 set_ia32_ls_mode(fild, mode_Ls);
4718 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4720 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4723 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4724 ir_node *src_block = get_nodes_block(node);
4725 ir_node *block = be_transform_node(src_block);
4726 ir_graph *irg = current_ir_graph;
4727 dbg_info *dbgi = get_irn_dbg_info(node);
4728 ir_node *frame = get_irg_frame(irg);
4729 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4730 ir_node *nomem = new_NoMem();
4731 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4732 ir_node *new_val = be_transform_node(val);
4733 ir_node *fist, *mem;
4735 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4736 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4737 set_ia32_use_frame(fist);
4738 set_ia32_op_type(fist, ia32_AddrModeD);
4739 set_ia32_ls_mode(fist, mode_Ls);
4745 * the BAD transformer.
4747 static ir_node *bad_transform(ir_node *node) {
4748 panic("No transform function for %+F available.\n", node);
4752 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4753 ir_graph *irg = current_ir_graph;
4754 ir_node *block = be_transform_node(get_nodes_block(node));
4755 ir_node *pred = get_Proj_pred(node);
4756 ir_node *new_pred = be_transform_node(pred);
4757 ir_node *frame = get_irg_frame(irg);
4758 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4759 dbg_info *dbgi = get_irn_dbg_info(node);
4760 long pn = get_Proj_proj(node);
4765 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4766 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4767 set_ia32_use_frame(load);
4768 set_ia32_op_type(load, ia32_AddrModeS);
4769 set_ia32_ls_mode(load, mode_Iu);
4770 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4771 * 32 bit from it with this particular load */
4772 attr = get_ia32_attr(load);
4773 attr->data.need_64bit_stackent = 1;
4775 if (pn == pn_ia32_l_FloattoLL_res_high) {
4776 add_ia32_am_offs_int(load, 4);
4778 assert(pn == pn_ia32_l_FloattoLL_res_low);
4781 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4787 * Transform the Projs of an AddSP.
4789 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4790 ir_node *block = be_transform_node(get_nodes_block(node));
4791 ir_node *pred = get_Proj_pred(node);
4792 ir_node *new_pred = be_transform_node(pred);
4793 ir_graph *irg = current_ir_graph;
4794 dbg_info *dbgi = get_irn_dbg_info(node);
4795 long proj = get_Proj_proj(node);
4797 if (proj == pn_be_AddSP_sp) {
4798 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4799 pn_ia32_SubSP_stack);
4800 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4802 } else if(proj == pn_be_AddSP_res) {
4803 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4804 pn_ia32_SubSP_addr);
4805 } else if (proj == pn_be_AddSP_M) {
4806 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4810 return new_rd_Unknown(irg, get_irn_mode(node));
4814 * Transform the Projs of a SubSP.
4816 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4817 ir_node *block = be_transform_node(get_nodes_block(node));
4818 ir_node *pred = get_Proj_pred(node);
4819 ir_node *new_pred = be_transform_node(pred);
4820 ir_graph *irg = current_ir_graph;
4821 dbg_info *dbgi = get_irn_dbg_info(node);
4822 long proj = get_Proj_proj(node);
4824 if (proj == pn_be_SubSP_sp) {
4825 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4826 pn_ia32_AddSP_stack);
4827 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4829 } else if (proj == pn_be_SubSP_M) {
4830 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4834 return new_rd_Unknown(irg, get_irn_mode(node));
4838 * Transform and renumber the Projs from a Load.
4840 static ir_node *gen_Proj_Load(ir_node *node) {
4842 ir_node *block = be_transform_node(get_nodes_block(node));
4843 ir_node *pred = get_Proj_pred(node);
4844 ir_graph *irg = current_ir_graph;
4845 dbg_info *dbgi = get_irn_dbg_info(node);
4846 long proj = get_Proj_proj(node);
4848 /* loads might be part of source address mode matches, so we don't
4849 * transform the ProjMs yet (with the exception of loads whose result is
4852 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4855 /* this is needed, because sometimes we have loops that are only
4856 reachable through the ProjM */
4857 be_enqueue_preds(node);
4858 /* do it in 2 steps, to silence firm verifier */
4859 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4860 set_Proj_proj(res, pn_ia32_mem);
4864 /* renumber the proj */
4865 new_pred = be_transform_node(pred);
4866 if (is_ia32_Load(new_pred)) {
4869 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4871 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4872 case pn_Load_X_regular:
4873 return new_rd_Jmp(dbgi, irg, block);
4874 case pn_Load_X_except:
4875 /* This Load might raise an exception. Mark it. */
4876 set_ia32_exc_label(new_pred, 1);
4877 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4881 } else if (is_ia32_Conv_I2I(new_pred) ||
4882 is_ia32_Conv_I2I8Bit(new_pred)) {
4883 set_irn_mode(new_pred, mode_T);
4884 if (proj == pn_Load_res) {
4885 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4886 } else if (proj == pn_Load_M) {
4887 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4889 } else if (is_ia32_xLoad(new_pred)) {
4892 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4894 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4895 case pn_Load_X_regular:
4896 return new_rd_Jmp(dbgi, irg, block);
4897 case pn_Load_X_except:
4898 /* This Load might raise an exception. Mark it. */
4899 set_ia32_exc_label(new_pred, 1);
4900 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4904 } else if (is_ia32_vfld(new_pred)) {
4907 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4909 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4910 case pn_Load_X_regular:
4911 return new_rd_Jmp(dbgi, irg, block);
4912 case pn_Load_X_except:
4913 /* This Load might raise an exception. Mark it. */
4914 set_ia32_exc_label(new_pred, 1);
4915 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4920 /* can happen for ProJMs when source address mode happened for the
4923 /* however it should not be the result proj, as that would mean the
4924 load had multiple users and should not have been used for
4926 if (proj != pn_Load_M) {
4927 panic("internal error: transformed node not a Load");
4929 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4933 return new_rd_Unknown(irg, get_irn_mode(node));
4937 * Transform and renumber the Projs from a DivMod like instruction.
4939 static ir_node *gen_Proj_DivMod(ir_node *node) {
4940 ir_node *block = be_transform_node(get_nodes_block(node));
4941 ir_node *pred = get_Proj_pred(node);
4942 ir_node *new_pred = be_transform_node(pred);
4943 ir_graph *irg = current_ir_graph;
4944 dbg_info *dbgi = get_irn_dbg_info(node);
4945 ir_mode *mode = get_irn_mode(node);
4946 long proj = get_Proj_proj(node);
4948 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4950 switch (get_irn_opcode(pred)) {
4954 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4956 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4957 case pn_Div_X_regular:
4958 return new_rd_Jmp(dbgi, irg, block);
4959 case pn_Div_X_except:
4960 set_ia32_exc_label(new_pred, 1);
4961 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4969 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4971 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4972 case pn_Mod_X_except:
4973 set_ia32_exc_label(new_pred, 1);
4974 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4982 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4983 case pn_DivMod_res_div:
4984 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4985 case pn_DivMod_res_mod:
4986 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4987 case pn_DivMod_X_regular:
4988 return new_rd_Jmp(dbgi, irg, block);
4989 case pn_DivMod_X_except:
4990 set_ia32_exc_label(new_pred, 1);
4991 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
5001 return new_rd_Unknown(irg, mode);
5005 * Transform and renumber the Projs from a CopyB.
5007 static ir_node *gen_Proj_CopyB(ir_node *node) {
5008 ir_node *block = be_transform_node(get_nodes_block(node));
5009 ir_node *pred = get_Proj_pred(node);
5010 ir_node *new_pred = be_transform_node(pred);
5011 ir_graph *irg = current_ir_graph;
5012 dbg_info *dbgi = get_irn_dbg_info(node);
5013 ir_mode *mode = get_irn_mode(node);
5014 long proj = get_Proj_proj(node);
5017 case pn_CopyB_M_regular:
5018 if (is_ia32_CopyB_i(new_pred)) {
5019 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
5020 } else if (is_ia32_CopyB(new_pred)) {
5021 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
5029 return new_rd_Unknown(irg, mode);
5033 * Transform and renumber the Projs from a Quot.
5035 static ir_node *gen_Proj_Quot(ir_node *node) {
5036 ir_node *block = be_transform_node(get_nodes_block(node));
5037 ir_node *pred = get_Proj_pred(node);
5038 ir_node *new_pred = be_transform_node(pred);
5039 ir_graph *irg = current_ir_graph;
5040 dbg_info *dbgi = get_irn_dbg_info(node);
5041 ir_mode *mode = get_irn_mode(node);
5042 long proj = get_Proj_proj(node);
5046 if (is_ia32_xDiv(new_pred)) {
5047 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
5048 } else if (is_ia32_vfdiv(new_pred)) {
5049 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
5053 if (is_ia32_xDiv(new_pred)) {
5054 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
5055 } else if (is_ia32_vfdiv(new_pred)) {
5056 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
5059 case pn_Quot_X_regular:
5060 case pn_Quot_X_except:
5066 return new_rd_Unknown(irg, mode);
5070 * Transform the Thread Local Storage Proj.
5072 static ir_node *gen_Proj_tls(ir_node *node) {
5073 ir_node *block = be_transform_node(get_nodes_block(node));
5074 ir_graph *irg = current_ir_graph;
5075 dbg_info *dbgi = NULL;
5076 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
5081 static ir_node *gen_be_Call(ir_node *node) {
5082 ir_node *res = be_duplicate_node(node);
5083 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5088 static ir_node *gen_be_IncSP(ir_node *node) {
5089 ir_node *res = be_duplicate_node(node);
5090 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5096 * Transform the Projs from a be_Call.
5098 static ir_node *gen_Proj_be_Call(ir_node *node) {
5099 ir_node *block = be_transform_node(get_nodes_block(node));
5100 ir_node *call = get_Proj_pred(node);
5101 ir_node *new_call = be_transform_node(call);
5102 ir_graph *irg = current_ir_graph;
5103 dbg_info *dbgi = get_irn_dbg_info(node);
5104 ir_type *method_type = be_Call_get_type(call);
5105 int n_res = get_method_n_ress(method_type);
5106 long proj = get_Proj_proj(node);
5107 ir_mode *mode = get_irn_mode(node);
5109 const arch_register_class_t *cls;
5111 /* The following is kinda tricky: If we're using SSE, then we have to
5112 * move the result value of the call in floating point registers to an
5113 * xmm register, we therefore construct a GetST0 -> xLoad sequence
5114 * after the call, we have to make sure to correctly make the
5115 * MemProj and the result Proj use these 2 nodes
5117 if (proj == pn_be_Call_M_regular) {
5118 // get new node for result, are we doing the sse load/store hack?
5119 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5120 ir_node *call_res_new;
5121 ir_node *call_res_pred = NULL;
5123 if (call_res != NULL) {
5124 call_res_new = be_transform_node(call_res);
5125 call_res_pred = get_Proj_pred(call_res_new);
5128 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
5129 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5130 pn_be_Call_M_regular);
5132 assert(is_ia32_xLoad(call_res_pred));
5133 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5137 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5138 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5140 ir_node *frame = get_irg_frame(irg);
5141 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
5143 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5146 /* in case there is no memory output: create one to serialize the copy
5148 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5149 pn_be_Call_M_regular);
5150 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5151 pn_be_Call_first_res);
5153 /* store st(0) onto stack */
5154 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
5156 set_ia32_op_type(fstp, ia32_AddrModeD);
5157 set_ia32_use_frame(fstp);
5159 /* load into SSE register */
5160 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5162 set_ia32_op_type(sse_load, ia32_AddrModeS);
5163 set_ia32_use_frame(sse_load);
5165 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5171 /* transform call modes */
5172 if (mode_is_data(mode)) {
5173 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5177 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5181 * Transform the Projs from a Cmp.
5183 static ir_node *gen_Proj_Cmp(ir_node *node)
5185 /* this probably means not all mode_b nodes were lowered... */
5186 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5191 * Transform the Projs from a Bound.
5193 static ir_node *gen_Proj_Bound(ir_node *node)
5195 ir_node *new_node, *block;
5196 ir_node *pred = get_Proj_pred(node);
5198 switch (get_Proj_proj(node)) {
5200 return be_transform_node(get_Bound_mem(pred));
5201 case pn_Bound_X_regular:
5202 new_node = be_transform_node(pred);
5203 block = get_nodes_block(new_node);
5204 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
5205 case pn_Bound_X_except:
5206 new_node = be_transform_node(pred);
5207 block = get_nodes_block(new_node);
5208 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
5210 return be_transform_node(get_Bound_index(pred));
5212 panic("unsupported Proj from Bound");
5217 * Transform and potentially renumber Proj nodes.
5219 static ir_node *gen_Proj(ir_node *node) {
5220 ir_node *pred = get_Proj_pred(node);
5223 switch (get_irn_opcode(pred)) {
5225 proj = get_Proj_proj(node);
5226 if (proj == pn_Store_M) {
5227 return be_transform_node(pred);
5230 return new_r_Bad(current_ir_graph);
5233 return gen_Proj_Load(node);
5237 return gen_Proj_DivMod(node);
5239 return gen_Proj_CopyB(node);
5241 return gen_Proj_Quot(node);
5243 return gen_Proj_be_SubSP(node);
5245 return gen_Proj_be_AddSP(node);
5247 return gen_Proj_be_Call(node);
5249 return gen_Proj_Cmp(node);
5251 return gen_Proj_Bound(node);
5253 proj = get_Proj_proj(node);
5254 if (proj == pn_Start_X_initial_exec) {
5255 ir_node *block = get_nodes_block(pred);
5256 dbg_info *dbgi = get_irn_dbg_info(node);
5259 /* we exchange the ProjX with a jump */
5260 block = be_transform_node(block);
5261 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
5264 if (node == be_get_old_anchor(anchor_tls)) {
5265 return gen_Proj_tls(node);
5270 if (is_ia32_l_FloattoLL(pred)) {
5271 return gen_Proj_l_FloattoLL(node);
5273 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5277 ir_mode *mode = get_irn_mode(node);
5278 if (mode_needs_gp_reg(mode)) {
5279 ir_node *new_pred = be_transform_node(pred);
5280 ir_node *block = be_transform_node(get_nodes_block(node));
5281 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5282 mode_Iu, get_Proj_proj(node));
5283 #ifdef DEBUG_libfirm
5284 new_proj->node_nr = node->node_nr;
5290 return be_duplicate_node(node);
5294 * Enters all transform functions into the generic pointer
5296 static void register_transformers(void)
5300 /* first clear the generic function pointer for all ops */
5301 clear_irp_opcodes_generic_func();
5303 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5304 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5343 /* transform ops from intrinsic lowering */
5359 GEN(ia32_l_LLtoFloat);
5360 GEN(ia32_l_FloattoLL);
5366 /* we should never see these nodes */
5381 /* handle generic backend nodes */
5390 op_Mulh = get_op_Mulh();
5399 * Pre-transform all unknown and noreg nodes.
5401 static void ia32_pretransform_node(void *arch_cg) {
5402 ia32_code_gen_t *cg = arch_cg;
5404 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5405 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5406 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5407 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5408 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5409 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5414 * Walker, checks if all ia32 nodes producing more than one result have
5415 * its Projs, otherwise creates new Projs and keep them using a be_Keep node.
5417 static void add_missing_keep_walker(ir_node *node, void *data)
5420 unsigned found_projs = 0;
5421 const ir_edge_t *edge;
5422 ir_mode *mode = get_irn_mode(node);
5427 if(!is_ia32_irn(node))
5430 n_outs = get_ia32_n_res(node);
5433 if(is_ia32_SwitchJmp(node))
5436 assert(n_outs < (int) sizeof(unsigned) * 8);
5437 foreach_out_edge(node, edge) {
5438 ir_node *proj = get_edge_src_irn(edge);
5439 int pn = get_Proj_proj(proj);
5441 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
5442 found_projs |= 1 << pn;
5446 /* are keeps missing? */
5448 for(i = 0; i < n_outs; ++i) {
5451 const arch_register_req_t *req;
5452 const arch_register_class_t *cls;
5454 if(found_projs & (1 << i)) {
5458 req = get_ia32_out_req(node, i);
5463 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
5467 block = get_nodes_block(node);
5468 in[0] = new_r_Proj(current_ir_graph, block, node,
5469 arch_register_class_mode(cls), i);
5470 if(last_keep != NULL) {
5471 be_Keep_add_node(last_keep, cls, in[0]);
5473 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
5474 if(sched_is_scheduled(node)) {
5475 sched_add_after(node, last_keep);
5482 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5485 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5487 ir_graph *irg = be_get_birg_irg(cg->birg);
5488 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5491 /* do the transformation */
5492 void ia32_transform_graph(ia32_code_gen_t *cg) {
5494 ir_graph *irg = cg->irg;
5496 register_transformers();
5498 initial_fpcw = NULL;
5500 BE_TIMER_PUSH(t_heights);
5501 heights = heights_new(irg);
5502 BE_TIMER_POP(t_heights);
5503 ia32_calculate_non_address_mode_nodes(cg->birg);
5505 /* the transform phase is not safe for CSE (yet) because several nodes get
5506 * attributes set after their creation */
5507 cse_last = get_opt_cse();
5510 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5512 set_opt_cse(cse_last);
5514 ia32_free_non_address_mode_nodes();
5515 heights_free(heights);
5519 void ia32_init_transform(void)
5521 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");