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 int ia32_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 ir_type *ia32_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 = ia32_get_prim_type(isa->types, mode);
242 tp = ia32_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 /* beware: some nodes are already pinned and did not allow to change the state */
724 if (get_irn_pinned(node) != op_pin_state_pinned)
725 set_irn_pinned(node, op_pin_state_pinned);
728 set_ia32_commutative(node);
732 * Check, if a given node is a Down-Conv, ie. a integer Conv
733 * from a mode with a mode with more bits to a mode with lesser bits.
734 * Moreover, we return only true if the node has not more than 1 user.
736 * @param node the node
737 * @return non-zero if node is a Down-Conv
739 static int is_downconv(const ir_node *node)
747 /* we only want to skip the conv when we're the only user
748 * (not optimal but for now...)
750 if(get_irn_n_edges(node) > 1)
753 src_mode = get_irn_mode(get_Conv_op(node));
754 dest_mode = get_irn_mode(node);
755 return ia32_mode_needs_gp_reg(src_mode)
756 && ia32_mode_needs_gp_reg(dest_mode)
757 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
760 /* Skip all Down-Conv's on a given node and return the resulting node. */
761 ir_node *ia32_skip_downconv(ir_node *node) {
762 while (is_downconv(node))
763 node = get_Conv_op(node);
768 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
770 ir_mode *mode = get_irn_mode(node);
775 if(mode_is_signed(mode)) {
780 block = get_nodes_block(node);
781 dbgi = get_irn_dbg_info(node);
783 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
787 * matches operands of a node into ia32 addressing/operand modes. This covers
788 * usage of source address mode, immediates, operations with non 32-bit modes,
790 * The resulting data is filled into the @p am struct. block is the block
791 * of the node whose arguments are matched. op1, op2 are the first and second
792 * input that are matched (op1 may be NULL). other_op is another unrelated
793 * input that is not matched! but which is needed sometimes to check if AM
794 * for op1/op2 is legal.
795 * @p flags describes the supported modes of the operation in detail.
797 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
798 ir_node *op1, ir_node *op2, ir_node *other_op,
801 ia32_address_t *addr = &am->addr;
802 ir_mode *mode = get_irn_mode(op2);
803 int mode_bits = get_mode_size_bits(mode);
804 ir_node *noreg_gp, *new_op1, *new_op2;
806 unsigned commutative;
807 int use_am_and_immediates;
810 memset(am, 0, sizeof(am[0]));
812 commutative = (flags & match_commutative) != 0;
813 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
814 use_am = (flags & match_am) != 0;
815 use_immediate = (flags & match_immediate) != 0;
816 assert(!use_am_and_immediates || use_immediate);
819 assert(!commutative || op1 != NULL);
820 assert(use_am || !(flags & match_8bit_am));
821 assert(use_am || !(flags & match_16bit_am));
823 if (mode_bits == 8) {
824 if (!(flags & match_8bit_am))
826 /* we don't automatically add upconvs yet */
827 assert((flags & match_mode_neutral) || (flags & match_8bit));
828 } else if (mode_bits == 16) {
829 if (!(flags & match_16bit_am))
831 /* we don't automatically add upconvs yet */
832 assert((flags & match_mode_neutral) || (flags & match_16bit));
835 /* we can simply skip downconvs for mode neutral nodes: the upper bits
836 * can be random for these operations */
837 if (flags & match_mode_neutral) {
838 op2 = ia32_skip_downconv(op2);
840 op1 = ia32_skip_downconv(op1);
844 /* match immediates. firm nodes are normalized: constants are always on the
847 if (!(flags & match_try_am) && use_immediate) {
848 new_op2 = try_create_Immediate(op2, 0);
851 noreg_gp = ia32_new_NoReg_gp(env_cg);
852 if (new_op2 == NULL &&
853 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
854 build_address(am, op2);
855 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
856 if (mode_is_float(mode)) {
857 new_op2 = ia32_new_NoReg_vfp(env_cg);
861 am->op_type = ia32_AddrModeS;
862 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
864 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
866 build_address(am, op1);
868 if (mode_is_float(mode)) {
869 noreg = ia32_new_NoReg_vfp(env_cg);
874 if (new_op2 != NULL) {
877 new_op1 = be_transform_node(op2);
879 am->ins_permuted = 1;
881 am->op_type = ia32_AddrModeS;
883 if (flags & match_try_am) {
886 am->op_type = ia32_Normal;
890 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
892 new_op2 = be_transform_node(op2);
893 am->op_type = ia32_Normal;
894 am->ls_mode = get_irn_mode(op2);
895 if (flags & match_mode_neutral)
896 am->ls_mode = mode_Iu;
898 if (addr->base == NULL)
899 addr->base = noreg_gp;
900 if (addr->index == NULL)
901 addr->index = noreg_gp;
902 if (addr->mem == NULL)
903 addr->mem = new_NoMem();
905 am->new_op1 = new_op1;
906 am->new_op2 = new_op2;
907 am->commutative = commutative;
910 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
915 if (am->mem_proj == NULL)
918 /* we have to create a mode_T so the old MemProj can attach to us */
919 mode = get_irn_mode(node);
920 load = get_Proj_pred(am->mem_proj);
922 mark_irn_visited(load);
923 be_set_transformed_node(load, node);
925 if (mode != mode_T) {
926 set_irn_mode(node, mode_T);
927 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
934 * Construct a standard binary operation, set AM and immediate if required.
936 * @param node The original node for which the binop is created
937 * @param op1 The first operand
938 * @param op2 The second operand
939 * @param func The node constructor function
940 * @return The constructed ia32 node.
942 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
943 construct_binop_func *func, match_flags_t flags)
946 ir_node *block, *new_block, *new_node;
947 ia32_address_mode_t am;
948 ia32_address_t *addr = &am.addr;
950 block = get_nodes_block(node);
951 match_arguments(&am, block, op1, op2, NULL, flags);
953 dbgi = get_irn_dbg_info(node);
954 new_block = be_transform_node(block);
955 new_node = func(dbgi, current_ir_graph, new_block,
956 addr->base, addr->index, addr->mem,
957 am.new_op1, am.new_op2);
958 set_am_attributes(new_node, &am);
959 /* we can't use source address mode anymore when using immediates */
960 if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
961 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
962 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
964 new_node = fix_mem_proj(new_node, &am);
971 n_ia32_l_binop_right,
972 n_ia32_l_binop_eflags
974 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
975 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
976 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
977 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
978 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
979 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
982 * Construct a binary operation which also consumes the eflags.
984 * @param node The node to transform
985 * @param func The node constructor function
986 * @param flags The match flags
987 * @return The constructor ia32 node
989 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
992 ir_node *src_block = get_nodes_block(node);
993 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
994 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
996 ir_node *block, *new_node, *eflags, *new_eflags;
997 ia32_address_mode_t am;
998 ia32_address_t *addr = &am.addr;
1000 match_arguments(&am, src_block, op1, op2, NULL, flags);
1002 dbgi = get_irn_dbg_info(node);
1003 block = be_transform_node(src_block);
1004 eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1005 new_eflags = be_transform_node(eflags);
1006 new_node = func(dbgi, current_ir_graph, block, addr->base, addr->index,
1007 addr->mem, am.new_op1, am.new_op2, new_eflags);
1008 set_am_attributes(new_node, &am);
1009 /* we can't use source address mode anymore when using immediates */
1010 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1011 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1012 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1014 new_node = fix_mem_proj(new_node, &am);
1019 static ir_node *get_fpcw(void)
1022 if (initial_fpcw != NULL)
1023 return initial_fpcw;
1025 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
1026 &ia32_fp_cw_regs[REG_FPCW]);
1027 initial_fpcw = be_transform_node(fpcw);
1029 return initial_fpcw;
1033 * Construct a standard binary operation, set AM and immediate if required.
1035 * @param op1 The first operand
1036 * @param op2 The second operand
1037 * @param func The node constructor function
1038 * @return The constructed ia32 node.
1040 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1041 construct_binop_float_func *func,
1042 match_flags_t flags)
1044 ir_mode *mode = get_irn_mode(node);
1046 ir_node *block, *new_block, *new_node;
1047 ia32_address_mode_t am;
1048 ia32_address_t *addr = &am.addr;
1050 /* cannot use address mode with long double on x87 */
1051 if (get_mode_size_bits(mode) > 64)
1054 block = get_nodes_block(node);
1055 match_arguments(&am, block, op1, op2, NULL, flags);
1057 dbgi = get_irn_dbg_info(node);
1058 new_block = be_transform_node(block);
1059 new_node = func(dbgi, current_ir_graph, new_block,
1060 addr->base, addr->index, addr->mem,
1061 am.new_op1, am.new_op2, get_fpcw());
1062 set_am_attributes(new_node, &am);
1064 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1066 new_node = fix_mem_proj(new_node, &am);
1072 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1074 * @param op1 The first operand
1075 * @param op2 The second operand
1076 * @param func The node constructor function
1077 * @return The constructed ia32 node.
1079 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1080 construct_shift_func *func,
1081 match_flags_t flags)
1084 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1086 assert(! mode_is_float(get_irn_mode(node)));
1087 assert(flags & match_immediate);
1088 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1090 if (flags & match_mode_neutral) {
1091 op1 = ia32_skip_downconv(op1);
1092 new_op1 = be_transform_node(op1);
1093 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1094 new_op1 = create_upconv(op1, node);
1096 new_op1 = be_transform_node(op1);
1099 /* the shift amount can be any mode that is bigger than 5 bits, since all
1100 * other bits are ignored anyway */
1101 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1102 ir_node *const op = get_Conv_op(op2);
1103 if (mode_is_float(get_irn_mode(op)))
1106 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1108 new_op2 = create_immediate_or_transform(op2, 0);
1110 dbgi = get_irn_dbg_info(node);
1111 block = get_nodes_block(node);
1112 new_block = be_transform_node(block);
1113 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1114 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1116 /* lowered shift instruction may have a dependency operand, handle it here */
1117 if (get_irn_arity(node) == 3) {
1118 /* we have a dependency */
1119 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1120 add_irn_dep(new_node, new_dep);
1128 * Construct a standard unary operation, set AM and immediate if required.
1130 * @param op The operand
1131 * @param func The node constructor function
1132 * @return The constructed ia32 node.
1134 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1135 match_flags_t flags)
1138 ir_node *block, *new_block, *new_op, *new_node;
1140 assert(flags == 0 || flags == match_mode_neutral);
1141 if (flags & match_mode_neutral) {
1142 op = ia32_skip_downconv(op);
1145 new_op = be_transform_node(op);
1146 dbgi = get_irn_dbg_info(node);
1147 block = get_nodes_block(node);
1148 new_block = be_transform_node(block);
1149 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1151 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1156 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1157 ia32_address_t *addr)
1159 ir_node *base, *index, *res;
1163 base = ia32_new_NoReg_gp(env_cg);
1165 base = be_transform_node(base);
1168 index = addr->index;
1169 if (index == NULL) {
1170 index = ia32_new_NoReg_gp(env_cg);
1172 index = be_transform_node(index);
1175 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1176 set_address(res, addr);
1182 * Returns non-zero if a given address mode has a symbolic or
1183 * numerical offset != 0.
1185 static int am_has_immediates(const ia32_address_t *addr)
1187 return addr->offset != 0 || addr->symconst_ent != NULL
1188 || addr->frame_entity || addr->use_frame;
1192 * Creates an ia32 Add.
1194 * @return the created ia32 Add node
1196 static ir_node *gen_Add(ir_node *node) {
1197 ir_mode *mode = get_irn_mode(node);
1198 ir_node *op1 = get_Add_left(node);
1199 ir_node *op2 = get_Add_right(node);
1201 ir_node *block, *new_block, *new_node, *add_immediate_op;
1202 ia32_address_t addr;
1203 ia32_address_mode_t am;
1205 if (mode_is_float(mode)) {
1206 if (ia32_cg_config.use_sse2)
1207 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1208 match_commutative | match_am);
1210 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1211 match_commutative | match_am);
1214 ia32_mark_non_am(node);
1216 op2 = ia32_skip_downconv(op2);
1217 op1 = ia32_skip_downconv(op1);
1221 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1222 * 1. Add with immediate -> Lea
1223 * 2. Add with possible source address mode -> Add
1224 * 3. Otherwise -> Lea
1226 memset(&addr, 0, sizeof(addr));
1227 ia32_create_address_mode(&addr, node, /*force=*/1);
1228 add_immediate_op = NULL;
1230 dbgi = get_irn_dbg_info(node);
1231 block = get_nodes_block(node);
1232 new_block = be_transform_node(block);
1235 if(addr.base == NULL && addr.index == NULL) {
1236 ir_graph *irg = current_ir_graph;
1237 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1238 addr.symconst_sign, addr.offset);
1239 add_irn_dep(new_node, get_irg_frame(irg));
1240 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1243 /* add with immediate? */
1244 if(addr.index == NULL) {
1245 add_immediate_op = addr.base;
1246 } else if(addr.base == NULL && addr.scale == 0) {
1247 add_immediate_op = addr.index;
1250 if(add_immediate_op != NULL) {
1251 if(!am_has_immediates(&addr)) {
1252 #ifdef DEBUG_libfirm
1253 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1256 return be_transform_node(add_immediate_op);
1259 new_node = create_lea_from_address(dbgi, new_block, &addr);
1260 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1264 /* test if we can use source address mode */
1265 match_arguments(&am, block, op1, op2, NULL, match_commutative
1266 | match_mode_neutral | match_am | match_immediate | match_try_am);
1268 /* construct an Add with source address mode */
1269 if (am.op_type == ia32_AddrModeS) {
1270 ir_graph *irg = current_ir_graph;
1271 ia32_address_t *am_addr = &am.addr;
1272 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1273 am_addr->index, am_addr->mem, am.new_op1,
1275 set_am_attributes(new_node, &am);
1276 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1278 new_node = fix_mem_proj(new_node, &am);
1283 /* otherwise construct a lea */
1284 new_node = create_lea_from_address(dbgi, new_block, &addr);
1285 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1290 * Creates an ia32 Mul.
1292 * @return the created ia32 Mul node
1294 static ir_node *gen_Mul(ir_node *node) {
1295 ir_node *op1 = get_Mul_left(node);
1296 ir_node *op2 = get_Mul_right(node);
1297 ir_mode *mode = get_irn_mode(node);
1299 if (mode_is_float(mode)) {
1300 if (ia32_cg_config.use_sse2)
1301 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1302 match_commutative | match_am);
1304 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1305 match_commutative | match_am);
1307 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1308 match_commutative | match_am | match_mode_neutral |
1309 match_immediate | match_am_and_immediates);
1313 * Creates an ia32 Mulh.
1314 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1315 * this result while Mul returns the lower 32 bit.
1317 * @return the created ia32 Mulh node
1319 static ir_node *gen_Mulh(ir_node *node)
1321 ir_node *block = get_nodes_block(node);
1322 ir_node *new_block = be_transform_node(block);
1323 ir_graph *irg = current_ir_graph;
1324 dbg_info *dbgi = get_irn_dbg_info(node);
1325 ir_mode *mode = get_irn_mode(node);
1326 ir_node *op1 = get_Mulh_left(node);
1327 ir_node *op2 = get_Mulh_right(node);
1328 ir_node *proj_res_high;
1330 ia32_address_mode_t am;
1331 ia32_address_t *addr = &am.addr;
1333 assert(!mode_is_float(mode) && "Mulh with float not supported");
1334 assert(get_mode_size_bits(mode) == 32);
1336 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1338 if (mode_is_signed(mode)) {
1339 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1340 addr->index, addr->mem, am.new_op1,
1343 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1344 addr->index, addr->mem, am.new_op1,
1348 set_am_attributes(new_node, &am);
1349 /* we can't use source address mode anymore when using immediates */
1350 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1351 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1352 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1354 assert(get_irn_mode(new_node) == mode_T);
1356 fix_mem_proj(new_node, &am);
1358 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1359 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1360 mode_Iu, pn_ia32_IMul1OP_res_high);
1362 return proj_res_high;
1368 * Creates an ia32 And.
1370 * @return The created ia32 And node
1372 static ir_node *gen_And(ir_node *node) {
1373 ir_node *op1 = get_And_left(node);
1374 ir_node *op2 = get_And_right(node);
1375 assert(! mode_is_float(get_irn_mode(node)));
1377 /* is it a zero extension? */
1378 if (is_Const(op2)) {
1379 tarval *tv = get_Const_tarval(op2);
1380 long v = get_tarval_long(tv);
1382 if (v == 0xFF || v == 0xFFFF) {
1383 dbg_info *dbgi = get_irn_dbg_info(node);
1384 ir_node *block = get_nodes_block(node);
1391 assert(v == 0xFFFF);
1394 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1399 return gen_binop(node, op1, op2, new_rd_ia32_And,
1400 match_commutative | match_mode_neutral | match_am
1407 * Creates an ia32 Or.
1409 * @return The created ia32 Or node
1411 static ir_node *gen_Or(ir_node *node) {
1412 ir_node *op1 = get_Or_left(node);
1413 ir_node *op2 = get_Or_right(node);
1415 assert (! mode_is_float(get_irn_mode(node)));
1416 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1417 | match_mode_neutral | match_am | match_immediate);
1423 * Creates an ia32 Eor.
1425 * @return The created ia32 Eor node
1427 static ir_node *gen_Eor(ir_node *node) {
1428 ir_node *op1 = get_Eor_left(node);
1429 ir_node *op2 = get_Eor_right(node);
1431 assert(! mode_is_float(get_irn_mode(node)));
1432 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1433 | match_mode_neutral | match_am | match_immediate);
1438 * Creates an ia32 Sub.
1440 * @return The created ia32 Sub node
1442 static ir_node *gen_Sub(ir_node *node) {
1443 ir_node *op1 = get_Sub_left(node);
1444 ir_node *op2 = get_Sub_right(node);
1445 ir_mode *mode = get_irn_mode(node);
1447 if (mode_is_float(mode)) {
1448 if (ia32_cg_config.use_sse2)
1449 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1451 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1455 if (is_Const(op2)) {
1456 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1460 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1461 | match_am | match_immediate);
1465 * Generates an ia32 DivMod with additional infrastructure for the
1466 * register allocator if needed.
1468 static ir_node *create_Div(ir_node *node)
1470 ir_graph *irg = current_ir_graph;
1471 dbg_info *dbgi = get_irn_dbg_info(node);
1472 ir_node *block = get_nodes_block(node);
1473 ir_node *new_block = be_transform_node(block);
1480 ir_node *sign_extension;
1481 ia32_address_mode_t am;
1482 ia32_address_t *addr = &am.addr;
1484 /* the upper bits have random contents for smaller modes */
1485 switch (get_irn_opcode(node)) {
1487 op1 = get_Div_left(node);
1488 op2 = get_Div_right(node);
1489 mem = get_Div_mem(node);
1490 mode = get_Div_resmode(node);
1493 op1 = get_Mod_left(node);
1494 op2 = get_Mod_right(node);
1495 mem = get_Mod_mem(node);
1496 mode = get_Mod_resmode(node);
1499 op1 = get_DivMod_left(node);
1500 op2 = get_DivMod_right(node);
1501 mem = get_DivMod_mem(node);
1502 mode = get_DivMod_resmode(node);
1505 panic("invalid divmod node %+F", node);
1508 match_arguments(&am, block, op1, op2, NULL, match_am);
1510 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1511 is the memory of the consumed address. We can have only the second op as address
1512 in Div nodes, so check only op2. */
1513 if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1514 new_mem = be_transform_node(mem);
1515 if(!is_NoMem(addr->mem)) {
1519 new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1522 new_mem = addr->mem;
1525 if (mode_is_signed(mode)) {
1526 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1527 add_irn_dep(produceval, get_irg_frame(irg));
1528 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1531 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1532 addr->index, new_mem, am.new_op2,
1533 am.new_op1, sign_extension);
1535 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1536 add_irn_dep(sign_extension, get_irg_frame(irg));
1538 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1539 addr->index, new_mem, am.new_op2,
1540 am.new_op1, sign_extension);
1543 set_irn_pinned(new_node, get_irn_pinned(node));
1545 set_am_attributes(new_node, &am);
1546 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1548 new_node = fix_mem_proj(new_node, &am);
1554 static ir_node *gen_Mod(ir_node *node) {
1555 return create_Div(node);
1558 static ir_node *gen_Div(ir_node *node) {
1559 return create_Div(node);
1562 static ir_node *gen_DivMod(ir_node *node) {
1563 return create_Div(node);
1569 * Creates an ia32 floating Div.
1571 * @return The created ia32 xDiv node
1573 static ir_node *gen_Quot(ir_node *node)
1575 ir_node *op1 = get_Quot_left(node);
1576 ir_node *op2 = get_Quot_right(node);
1578 if (ia32_cg_config.use_sse2) {
1579 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1581 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1587 * Creates an ia32 Shl.
1589 * @return The created ia32 Shl node
1591 static ir_node *gen_Shl(ir_node *node) {
1592 ir_node *left = get_Shl_left(node);
1593 ir_node *right = get_Shl_right(node);
1595 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1596 match_mode_neutral | match_immediate);
1600 * Creates an ia32 Shr.
1602 * @return The created ia32 Shr node
1604 static ir_node *gen_Shr(ir_node *node) {
1605 ir_node *left = get_Shr_left(node);
1606 ir_node *right = get_Shr_right(node);
1608 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1614 * Creates an ia32 Sar.
1616 * @return The created ia32 Shrs node
1618 static ir_node *gen_Shrs(ir_node *node) {
1619 ir_node *left = get_Shrs_left(node);
1620 ir_node *right = get_Shrs_right(node);
1621 ir_mode *mode = get_irn_mode(node);
1623 if(is_Const(right) && mode == mode_Is) {
1624 tarval *tv = get_Const_tarval(right);
1625 long val = get_tarval_long(tv);
1627 /* this is a sign extension */
1628 ir_graph *irg = current_ir_graph;
1629 dbg_info *dbgi = get_irn_dbg_info(node);
1630 ir_node *block = be_transform_node(get_nodes_block(node));
1632 ir_node *new_op = be_transform_node(op);
1633 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1634 add_irn_dep(pval, get_irg_frame(irg));
1636 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1640 /* 8 or 16 bit sign extension? */
1641 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1642 ir_node *shl_left = get_Shl_left(left);
1643 ir_node *shl_right = get_Shl_right(left);
1644 if(is_Const(shl_right)) {
1645 tarval *tv1 = get_Const_tarval(right);
1646 tarval *tv2 = get_Const_tarval(shl_right);
1647 if(tv1 == tv2 && tarval_is_long(tv1)) {
1648 long val = get_tarval_long(tv1);
1649 if(val == 16 || val == 24) {
1650 dbg_info *dbgi = get_irn_dbg_info(node);
1651 ir_node *block = get_nodes_block(node);
1661 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1670 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1676 * Creates an ia32 Rol.
1678 * @param op1 The first operator
1679 * @param op2 The second operator
1680 * @return The created ia32 RotL node
1682 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1683 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1689 * Creates an ia32 Ror.
1690 * NOTE: There is no RotR with immediate because this would always be a RotL
1691 * "imm-mode_size_bits" which can be pre-calculated.
1693 * @param op1 The first operator
1694 * @param op2 The second operator
1695 * @return The created ia32 RotR node
1697 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1698 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1704 * Creates an ia32 RotR or RotL (depending on the found pattern).
1706 * @return The created ia32 RotL or RotR node
1708 static ir_node *gen_Rotl(ir_node *node) {
1709 ir_node *rotate = NULL;
1710 ir_node *op1 = get_Rotl_left(node);
1711 ir_node *op2 = get_Rotl_right(node);
1713 /* Firm has only RotL, so we are looking for a right (op2)
1714 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1715 that means we can create a RotR instead of an Add and a RotL */
1719 ir_node *left = get_Add_left(add);
1720 ir_node *right = get_Add_right(add);
1721 if (is_Const(right)) {
1722 tarval *tv = get_Const_tarval(right);
1723 ir_mode *mode = get_irn_mode(node);
1724 long bits = get_mode_size_bits(mode);
1726 if (is_Minus(left) &&
1727 tarval_is_long(tv) &&
1728 get_tarval_long(tv) == bits &&
1731 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1732 rotate = gen_Ror(node, op1, get_Minus_op(left));
1737 if (rotate == NULL) {
1738 rotate = gen_Rol(node, op1, op2);
1747 * Transforms a Minus node.
1749 * @return The created ia32 Minus node
1751 static ir_node *gen_Minus(ir_node *node)
1753 ir_node *op = get_Minus_op(node);
1754 ir_node *block = be_transform_node(get_nodes_block(node));
1755 ir_graph *irg = current_ir_graph;
1756 dbg_info *dbgi = get_irn_dbg_info(node);
1757 ir_mode *mode = get_irn_mode(node);
1762 if (mode_is_float(mode)) {
1763 ir_node *new_op = be_transform_node(op);
1764 if (ia32_cg_config.use_sse2) {
1765 /* TODO: non-optimal... if we have many xXors, then we should
1766 * rather create a load for the const and use that instead of
1767 * several AM nodes... */
1768 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1769 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1770 ir_node *nomem = new_rd_NoMem(irg);
1772 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1773 nomem, new_op, noreg_xmm);
1775 size = get_mode_size_bits(mode);
1776 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1778 set_ia32_am_sc(new_node, ent);
1779 set_ia32_op_type(new_node, ia32_AddrModeS);
1780 set_ia32_ls_mode(new_node, mode);
1782 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1785 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1788 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1794 * Transforms a Not node.
1796 * @return The created ia32 Not node
1798 static ir_node *gen_Not(ir_node *node) {
1799 ir_node *op = get_Not_op(node);
1801 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1802 assert (! mode_is_float(get_irn_mode(node)));
1804 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1810 * Transforms an Abs node.
1812 * @return The created ia32 Abs node
1814 static ir_node *gen_Abs(ir_node *node)
1816 ir_node *block = get_nodes_block(node);
1817 ir_node *new_block = be_transform_node(block);
1818 ir_node *op = get_Abs_op(node);
1819 ir_graph *irg = current_ir_graph;
1820 dbg_info *dbgi = get_irn_dbg_info(node);
1821 ir_mode *mode = get_irn_mode(node);
1822 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1823 ir_node *nomem = new_NoMem();
1829 if (mode_is_float(mode)) {
1830 new_op = be_transform_node(op);
1832 if (ia32_cg_config.use_sse2) {
1833 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1834 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1835 nomem, new_op, noreg_fp);
1837 size = get_mode_size_bits(mode);
1838 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1840 set_ia32_am_sc(new_node, ent);
1842 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1844 set_ia32_op_type(new_node, ia32_AddrModeS);
1845 set_ia32_ls_mode(new_node, mode);
1847 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1848 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1851 ir_node *xor, *pval, *sign_extension;
1853 if (get_mode_size_bits(mode) == 32) {
1854 new_op = be_transform_node(op);
1856 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1859 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1860 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1863 add_irn_dep(pval, get_irg_frame(irg));
1864 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1866 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1867 nomem, new_op, sign_extension);
1868 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1870 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1871 nomem, xor, sign_extension);
1872 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1879 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1881 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1882 dbg_info *dbgi = get_irn_dbg_info(cmp);
1883 ir_node *block = get_nodes_block(cmp);
1884 ir_node *new_block = be_transform_node(block);
1885 ir_node *op1 = be_transform_node(x);
1886 ir_node *op2 = be_transform_node(n);
1888 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1892 * Transform a node returning a "flag" result.
1894 * @param node the node to transform
1895 * @param pnc_out the compare mode to use
1897 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1906 /* we have a Cmp as input */
1907 if (is_Proj(node)) {
1908 ir_node *pred = get_Proj_pred(node);
1910 pn_Cmp pnc = get_Proj_proj(node);
1911 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1912 ir_node *l = get_Cmp_left(pred);
1913 ir_node *r = get_Cmp_right(pred);
1915 ir_node *la = get_And_left(l);
1916 ir_node *ra = get_And_right(l);
1918 ir_node *c = get_Shl_left(la);
1919 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1920 /* (1 << n) & ra) */
1921 ir_node *n = get_Shl_right(la);
1922 flags = gen_bt(pred, ra, n);
1923 /* we must generate a Jc/Jnc jump */
1924 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1927 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1932 ir_node *c = get_Shl_left(ra);
1933 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1934 /* la & (1 << n)) */
1935 ir_node *n = get_Shl_right(ra);
1936 flags = gen_bt(pred, la, n);
1937 /* we must generate a Jc/Jnc jump */
1938 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1941 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1947 flags = be_transform_node(pred);
1953 /* a mode_b value, we have to compare it against 0 */
1954 dbgi = get_irn_dbg_info(node);
1955 new_block = be_transform_node(get_nodes_block(node));
1956 new_op = be_transform_node(node);
1957 noreg = ia32_new_NoReg_gp(env_cg);
1958 nomem = new_NoMem();
1959 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1960 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1961 *pnc_out = pn_Cmp_Lg;
1966 * Transforms a Load.
1968 * @return the created ia32 Load node
1970 static ir_node *gen_Load(ir_node *node) {
1971 ir_node *old_block = get_nodes_block(node);
1972 ir_node *block = be_transform_node(old_block);
1973 ir_node *ptr = get_Load_ptr(node);
1974 ir_node *mem = get_Load_mem(node);
1975 ir_node *new_mem = be_transform_node(mem);
1978 ir_graph *irg = current_ir_graph;
1979 dbg_info *dbgi = get_irn_dbg_info(node);
1980 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1981 ir_mode *mode = get_Load_mode(node);
1984 ia32_address_t addr;
1986 /* construct load address */
1987 memset(&addr, 0, sizeof(addr));
1988 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1995 base = be_transform_node(base);
2001 index = be_transform_node(index);
2004 if (mode_is_float(mode)) {
2005 if (ia32_cg_config.use_sse2) {
2006 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
2008 res_mode = mode_xmm;
2010 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
2012 res_mode = mode_vfp;
2015 assert(mode != mode_b);
2017 /* create a conv node with address mode for smaller modes */
2018 if(get_mode_size_bits(mode) < 32) {
2019 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
2020 new_mem, noreg, mode);
2022 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
2027 set_irn_pinned(new_node, get_irn_pinned(node));
2028 set_ia32_op_type(new_node, ia32_AddrModeS);
2029 set_ia32_ls_mode(new_node, mode);
2030 set_address(new_node, &addr);
2032 if(get_irn_pinned(node) == op_pin_state_floats) {
2033 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
2036 /* make sure we are scheduled behind the initial IncSP/Barrier
2037 * to avoid spills being placed before it
2039 if (block == get_irg_start_block(irg)) {
2040 add_irn_dep(new_node, get_irg_frame(irg));
2043 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2048 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2049 ir_node *ptr, ir_node *other)
2056 /* we only use address mode if we're the only user of the load */
2057 if(get_irn_n_edges(node) > 1)
2060 load = get_Proj_pred(node);
2063 if(get_nodes_block(load) != block)
2066 /* Store should be attached to the load */
2067 if(!is_Proj(mem) || get_Proj_pred(mem) != load)
2069 /* store should have the same pointer as the load */
2070 if(get_Load_ptr(load) != ptr)
2073 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2074 if(other != NULL && get_nodes_block(other) == block
2075 && heights_reachable_in_block(heights, other, load))
2081 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
2083 mark_irn_visited(old_node);
2084 be_set_transformed_node(old_node, new_node);
2087 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2088 ir_node *mem, ir_node *ptr, ir_mode *mode,
2089 construct_binop_dest_func *func,
2090 construct_binop_dest_func *func8bit,
2091 match_flags_t flags)
2093 ir_node *src_block = get_nodes_block(node);
2095 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2096 ir_graph *irg = current_ir_graph;
2102 ia32_address_mode_t am;
2103 ia32_address_t *addr = &am.addr;
2104 memset(&am, 0, sizeof(am));
2106 assert(flags & match_dest_am);
2107 assert(flags & match_immediate); /* there is no destam node without... */
2108 commutative = (flags & match_commutative) != 0;
2110 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2111 build_address(&am, op1);
2112 new_op = create_immediate_or_transform(op2, 0);
2113 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2114 build_address(&am, op2);
2115 new_op = create_immediate_or_transform(op1, 0);
2120 if(addr->base == NULL)
2121 addr->base = noreg_gp;
2122 if(addr->index == NULL)
2123 addr->index = noreg_gp;
2124 if(addr->mem == NULL)
2125 addr->mem = new_NoMem();
2127 dbgi = get_irn_dbg_info(node);
2128 block = be_transform_node(src_block);
2129 if(get_mode_size_bits(mode) == 8) {
2130 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2133 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
2136 set_address(new_node, addr);
2137 set_ia32_op_type(new_node, ia32_AddrModeD);
2138 set_ia32_ls_mode(new_node, mode);
2139 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2141 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2142 mem_proj = be_transform_node(am.mem_proj);
2143 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2148 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2149 ir_node *ptr, ir_mode *mode,
2150 construct_unop_dest_func *func)
2152 ir_graph *irg = current_ir_graph;
2153 ir_node *src_block = get_nodes_block(node);
2158 ia32_address_mode_t am;
2159 ia32_address_t *addr = &am.addr;
2160 memset(&am, 0, sizeof(am));
2162 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2165 build_address(&am, op);
2167 dbgi = get_irn_dbg_info(node);
2168 block = be_transform_node(src_block);
2169 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2170 set_address(new_node, addr);
2171 set_ia32_op_type(new_node, ia32_AddrModeD);
2172 set_ia32_ls_mode(new_node, mode);
2173 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2175 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2176 mem_proj = be_transform_node(am.mem_proj);
2177 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2182 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2183 ir_mode *mode = get_irn_mode(node);
2184 ir_node *psi_true = get_Psi_val(node, 0);
2185 ir_node *psi_default = get_Psi_default(node);
2196 ia32_address_t addr;
2198 if(get_mode_size_bits(mode) != 8)
2201 if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2203 } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2209 build_address_ptr(&addr, ptr, mem);
2211 irg = current_ir_graph;
2212 dbgi = get_irn_dbg_info(node);
2213 block = get_nodes_block(node);
2214 new_block = be_transform_node(block);
2215 cond = get_Psi_cond(node, 0);
2216 flags = get_flags_node(cond, &pnc);
2217 new_mem = be_transform_node(mem);
2218 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2219 addr.index, addr.mem, flags, pnc, negated);
2220 set_address(new_node, &addr);
2221 set_ia32_op_type(new_node, ia32_AddrModeD);
2222 set_ia32_ls_mode(new_node, mode);
2223 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2228 static ir_node *try_create_dest_am(ir_node *node) {
2229 ir_node *val = get_Store_value(node);
2230 ir_node *mem = get_Store_mem(node);
2231 ir_node *ptr = get_Store_ptr(node);
2232 ir_mode *mode = get_irn_mode(val);
2233 unsigned bits = get_mode_size_bits(mode);
2238 /* handle only GP modes for now... */
2239 if(!ia32_mode_needs_gp_reg(mode))
2243 /* store must be the only user of the val node */
2244 if(get_irn_n_edges(val) > 1)
2246 /* skip pointless convs */
2248 ir_node *conv_op = get_Conv_op(val);
2249 ir_mode *pred_mode = get_irn_mode(conv_op);
2250 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2258 /* value must be in the same block */
2259 if(get_nodes_block(node) != get_nodes_block(val))
2262 switch (get_irn_opcode(val)) {
2264 op1 = get_Add_left(val);
2265 op2 = get_Add_right(val);
2266 if(is_Const_1(op2)) {
2267 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2268 new_rd_ia32_IncMem);
2270 } else if(is_Const_Minus_1(op2)) {
2271 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2272 new_rd_ia32_DecMem);
2275 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2276 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2277 match_dest_am | match_commutative |
2281 op1 = get_Sub_left(val);
2282 op2 = get_Sub_right(val);
2284 ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2287 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2288 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2289 match_dest_am | match_immediate |
2293 op1 = get_And_left(val);
2294 op2 = get_And_right(val);
2295 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2296 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2297 match_dest_am | match_commutative |
2301 op1 = get_Or_left(val);
2302 op2 = get_Or_right(val);
2303 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2304 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2305 match_dest_am | match_commutative |
2309 op1 = get_Eor_left(val);
2310 op2 = get_Eor_right(val);
2311 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2312 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2313 match_dest_am | match_commutative |
2317 op1 = get_Shl_left(val);
2318 op2 = get_Shl_right(val);
2319 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2320 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2321 match_dest_am | match_immediate);
2324 op1 = get_Shr_left(val);
2325 op2 = get_Shr_right(val);
2326 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2327 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2328 match_dest_am | match_immediate);
2331 op1 = get_Shrs_left(val);
2332 op2 = get_Shrs_right(val);
2333 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2334 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2335 match_dest_am | match_immediate);
2338 op1 = get_Rotl_left(val);
2339 op2 = get_Rotl_right(val);
2340 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2341 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2342 match_dest_am | match_immediate);
2344 /* TODO: match ROR patterns... */
2346 new_node = try_create_SetMem(val, ptr, mem);
2349 op1 = get_Minus_op(val);
2350 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2353 /* should be lowered already */
2354 assert(mode != mode_b);
2355 op1 = get_Not_op(val);
2356 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2362 if(new_node != NULL) {
2363 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2364 get_irn_pinned(node) == op_pin_state_pinned) {
2365 set_irn_pinned(new_node, op_pin_state_pinned);
2372 static int is_float_to_int32_conv(const ir_node *node)
2374 ir_mode *mode = get_irn_mode(node);
2378 if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode))
2380 /* don't report unsigned as conv to 32bit, because we really need to do
2381 * a vfist with 64bit signed in this case */
2382 if(!mode_is_signed(mode))
2387 conv_op = get_Conv_op(node);
2388 conv_mode = get_irn_mode(conv_op);
2390 if(!mode_is_float(conv_mode))
2397 * Transform a Store(floatConst).
2399 * @return the created ia32 Store node
2401 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2402 ir_mode *mode = get_irn_mode(cns);
2403 int size = get_mode_size_bits(mode);
2404 tarval *tv = get_Const_tarval(cns);
2405 ir_node *block = get_nodes_block(node);
2406 ir_node *new_block = be_transform_node(block);
2407 ir_node *ptr = get_Store_ptr(node);
2408 ir_node *mem = get_Store_mem(node);
2409 ir_graph *irg = current_ir_graph;
2410 dbg_info *dbgi = get_irn_dbg_info(node);
2411 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2414 ia32_address_t addr;
2416 unsigned val = get_tarval_sub_bits(tv, 0) |
2417 (get_tarval_sub_bits(tv, 1) << 8) |
2418 (get_tarval_sub_bits(tv, 2) << 16) |
2419 (get_tarval_sub_bits(tv, 3) << 24);
2420 ir_node *imm = create_Immediate(NULL, 0, val);
2422 /* construct store address */
2423 memset(&addr, 0, sizeof(addr));
2424 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2426 if (addr.base == NULL) {
2429 addr.base = be_transform_node(addr.base);
2432 if (addr.index == NULL) {
2435 addr.index = be_transform_node(addr.index);
2437 addr.mem = be_transform_node(mem);
2439 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2440 addr.index, addr.mem, imm);
2442 set_irn_pinned(new_node, get_irn_pinned(node));
2443 set_ia32_op_type(new_node, ia32_AddrModeD);
2444 set_ia32_ls_mode(new_node, mode_Iu);
2446 set_address(new_node, &addr);
2448 /** add more stores if needed */
2450 unsigned val = get_tarval_sub_bits(tv, ofs) |
2451 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2452 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2453 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2454 ir_node *imm = create_Immediate(NULL, 0, val);
2457 addr.mem = new_node;
2459 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2460 addr.index, addr.mem, imm);
2462 set_irn_pinned(new_node, get_irn_pinned(node));
2463 set_ia32_op_type(new_node, ia32_AddrModeD);
2464 set_ia32_ls_mode(new_node, mode_Iu);
2466 set_address(new_node, &addr);
2471 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2476 * Generate a vfist or vfisttp instruction.
2478 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2479 ir_node *mem, ir_node *val, ir_node **fist)
2483 if (ia32_cg_config.use_fisttp) {
2484 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2485 if other users exists */
2486 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2487 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2488 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2489 be_new_Keep(reg_class, irg, block, 1, &value);
2491 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2494 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2497 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2503 * Transforms a normal Store.
2505 * @return the created ia32 Store node
2507 static ir_node *gen_normal_Store(ir_node *node)
2509 ir_node *val = get_Store_value(node);
2510 ir_mode *mode = get_irn_mode(val);
2511 ir_node *block = get_nodes_block(node);
2512 ir_node *new_block = be_transform_node(block);
2513 ir_node *ptr = get_Store_ptr(node);
2514 ir_node *mem = get_Store_mem(node);
2515 ir_graph *irg = current_ir_graph;
2516 dbg_info *dbgi = get_irn_dbg_info(node);
2517 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2518 ir_node *new_val, *new_node, *store;
2519 ia32_address_t addr;
2521 /* check for destination address mode */
2522 new_node = try_create_dest_am(node);
2523 if (new_node != NULL)
2526 /* construct store address */
2527 memset(&addr, 0, sizeof(addr));
2528 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2530 if (addr.base == NULL) {
2533 addr.base = be_transform_node(addr.base);
2536 if (addr.index == NULL) {
2539 addr.index = be_transform_node(addr.index);
2541 addr.mem = be_transform_node(mem);
2543 if (mode_is_float(mode)) {
2544 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2546 while (is_Conv(val) && mode == get_irn_mode(val)) {
2547 ir_node *op = get_Conv_op(val);
2548 if (!mode_is_float(get_irn_mode(op)))
2552 new_val = be_transform_node(val);
2553 if (ia32_cg_config.use_sse2) {
2554 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2555 addr.index, addr.mem, new_val);
2557 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2558 addr.index, addr.mem, new_val, mode);
2561 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2562 val = get_Conv_op(val);
2564 /* TODO: is this optimisation still necessary at all (middleend)? */
2565 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2566 while (is_Conv(val)) {
2567 ir_node *op = get_Conv_op(val);
2568 if (!mode_is_float(get_irn_mode(op)))
2570 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2574 new_val = be_transform_node(val);
2575 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2577 new_val = create_immediate_or_transform(val, 0);
2578 assert(mode != mode_b);
2580 if (get_mode_size_bits(mode) == 8) {
2581 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2582 addr.index, addr.mem, new_val);
2584 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2585 addr.index, addr.mem, new_val);
2590 set_irn_pinned(store, get_irn_pinned(node));
2591 set_ia32_op_type(store, ia32_AddrModeD);
2592 set_ia32_ls_mode(store, mode);
2594 set_address(store, &addr);
2595 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2601 * Transforms a Store.
2603 * @return the created ia32 Store node
2605 static ir_node *gen_Store(ir_node *node)
2607 ir_node *val = get_Store_value(node);
2608 ir_mode *mode = get_irn_mode(val);
2610 if (mode_is_float(mode) && is_Const(val)) {
2613 /* we are storing a floating point constant */
2614 if (ia32_cg_config.use_sse2) {
2615 transform = !is_simple_sse_Const(val);
2617 transform = !is_simple_x87_Const(val);
2620 return gen_float_const_Store(node, val);
2622 return gen_normal_Store(node);
2626 * Transforms a Switch.
2628 * @return the created ia32 SwitchJmp node
2630 static ir_node *create_Switch(ir_node *node)
2632 ir_graph *irg = current_ir_graph;
2633 dbg_info *dbgi = get_irn_dbg_info(node);
2634 ir_node *block = be_transform_node(get_nodes_block(node));
2635 ir_node *sel = get_Cond_selector(node);
2636 ir_node *new_sel = be_transform_node(sel);
2637 int switch_min = INT_MAX;
2638 int switch_max = INT_MIN;
2639 long default_pn = get_Cond_defaultProj(node);
2641 const ir_edge_t *edge;
2643 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2645 /* determine the smallest switch case value */
2646 foreach_out_edge(node, edge) {
2647 ir_node *proj = get_edge_src_irn(edge);
2648 long pn = get_Proj_proj(proj);
2649 if(pn == default_pn)
2658 if((unsigned) (switch_max - switch_min) > 256000) {
2659 panic("Size of switch %+F bigger than 256000", node);
2662 if (switch_min != 0) {
2663 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2665 /* if smallest switch case is not 0 we need an additional sub */
2666 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2667 add_ia32_am_offs_int(new_sel, -switch_min);
2668 set_ia32_op_type(new_sel, ia32_AddrModeS);
2670 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2673 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2674 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2680 * Transform a Cond node.
2682 static ir_node *gen_Cond(ir_node *node) {
2683 ir_node *block = get_nodes_block(node);
2684 ir_node *new_block = be_transform_node(block);
2685 ir_graph *irg = current_ir_graph;
2686 dbg_info *dbgi = get_irn_dbg_info(node);
2687 ir_node *sel = get_Cond_selector(node);
2688 ir_mode *sel_mode = get_irn_mode(sel);
2689 ir_node *flags = NULL;
2693 if (sel_mode != mode_b) {
2694 return create_Switch(node);
2697 /* we get flags from a Cmp */
2698 flags = get_flags_node(sel, &pnc);
2700 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2701 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2707 * Transforms a CopyB node.
2709 * @return The transformed node.
2711 static ir_node *gen_CopyB(ir_node *node) {
2712 ir_node *block = be_transform_node(get_nodes_block(node));
2713 ir_node *src = get_CopyB_src(node);
2714 ir_node *new_src = be_transform_node(src);
2715 ir_node *dst = get_CopyB_dst(node);
2716 ir_node *new_dst = be_transform_node(dst);
2717 ir_node *mem = get_CopyB_mem(node);
2718 ir_node *new_mem = be_transform_node(mem);
2719 ir_node *res = NULL;
2720 ir_graph *irg = current_ir_graph;
2721 dbg_info *dbgi = get_irn_dbg_info(node);
2722 int size = get_type_size_bytes(get_CopyB_type(node));
2725 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2726 /* then we need the size explicitly in ECX. */
2727 if (size >= 32 * 4) {
2728 rem = size & 0x3; /* size % 4 */
2731 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2732 add_irn_dep(res, get_irg_frame(irg));
2734 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2737 ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2740 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2743 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2748 static ir_node *gen_be_Copy(ir_node *node)
2750 ir_node *new_node = be_duplicate_node(node);
2751 ir_mode *mode = get_irn_mode(new_node);
2753 if (ia32_mode_needs_gp_reg(mode)) {
2754 set_irn_mode(new_node, mode_Iu);
2760 static ir_node *create_Fucom(ir_node *node)
2762 ir_graph *irg = current_ir_graph;
2763 dbg_info *dbgi = get_irn_dbg_info(node);
2764 ir_node *block = get_nodes_block(node);
2765 ir_node *new_block = be_transform_node(block);
2766 ir_node *left = get_Cmp_left(node);
2767 ir_node *new_left = be_transform_node(left);
2768 ir_node *right = get_Cmp_right(node);
2772 if(ia32_cg_config.use_fucomi) {
2773 new_right = be_transform_node(right);
2774 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2776 set_ia32_commutative(new_node);
2777 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2779 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2780 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2783 new_right = be_transform_node(right);
2784 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2788 set_ia32_commutative(new_node);
2790 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2792 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2793 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2799 static ir_node *create_Ucomi(ir_node *node)
2801 ir_graph *irg = current_ir_graph;
2802 dbg_info *dbgi = get_irn_dbg_info(node);
2803 ir_node *src_block = get_nodes_block(node);
2804 ir_node *new_block = be_transform_node(src_block);
2805 ir_node *left = get_Cmp_left(node);
2806 ir_node *right = get_Cmp_right(node);
2808 ia32_address_mode_t am;
2809 ia32_address_t *addr = &am.addr;
2811 match_arguments(&am, src_block, left, right, NULL,
2812 match_commutative | match_am);
2814 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2815 addr->mem, am.new_op1, am.new_op2,
2817 set_am_attributes(new_node, &am);
2819 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2821 new_node = fix_mem_proj(new_node, &am);
2827 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2828 * to fold an and into a test node
2830 static int can_fold_test_and(ir_node *node)
2832 const ir_edge_t *edge;
2834 /** we can only have eq and lg projs */
2835 foreach_out_edge(node, edge) {
2836 ir_node *proj = get_edge_src_irn(edge);
2837 pn_Cmp pnc = get_Proj_proj(proj);
2838 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2846 * Generate code for a Cmp.
2848 static ir_node *gen_Cmp(ir_node *node)
2850 ir_graph *irg = current_ir_graph;
2851 dbg_info *dbgi = get_irn_dbg_info(node);
2852 ir_node *block = get_nodes_block(node);
2853 ir_node *new_block = be_transform_node(block);
2854 ir_node *left = get_Cmp_left(node);
2855 ir_node *right = get_Cmp_right(node);
2856 ir_mode *cmp_mode = get_irn_mode(left);
2858 ia32_address_mode_t am;
2859 ia32_address_t *addr = &am.addr;
2862 if(mode_is_float(cmp_mode)) {
2863 if (ia32_cg_config.use_sse2) {
2864 return create_Ucomi(node);
2866 return create_Fucom(node);
2870 assert(ia32_mode_needs_gp_reg(cmp_mode));
2872 /* we prefer the Test instruction where possible except cases where
2873 * we can use SourceAM */
2874 cmp_unsigned = !mode_is_signed(cmp_mode);
2875 if (is_Const_0(right)) {
2877 get_irn_n_edges(left) == 1 &&
2878 can_fold_test_and(node)) {
2879 /* Test(and_left, and_right) */
2880 ir_node *and_left = get_And_left(left);
2881 ir_node *and_right = get_And_right(left);
2882 ir_mode *mode = get_irn_mode(and_left);
2884 match_arguments(&am, block, and_left, and_right, NULL,
2886 match_am | match_8bit_am | match_16bit_am |
2887 match_am_and_immediates | match_immediate |
2888 match_8bit | match_16bit);
2889 if (get_mode_size_bits(mode) == 8) {
2890 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2891 addr->index, addr->mem, am.new_op1,
2892 am.new_op2, am.ins_permuted,
2895 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2896 addr->index, addr->mem, am.new_op1,
2897 am.new_op2, am.ins_permuted, cmp_unsigned);
2900 match_arguments(&am, block, NULL, left, NULL,
2901 match_am | match_8bit_am | match_16bit_am |
2902 match_8bit | match_16bit);
2903 if (am.op_type == ia32_AddrModeS) {
2905 ir_node *imm_zero = try_create_Immediate(right, 0);
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_op2,
2909 imm_zero, am.ins_permuted,
2912 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2913 addr->index, addr->mem, am.new_op2,
2914 imm_zero, am.ins_permuted, cmp_unsigned);
2917 /* Test(left, left) */
2918 if (get_mode_size_bits(cmp_mode) == 8) {
2919 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2920 addr->index, addr->mem, am.new_op2,
2921 am.new_op2, am.ins_permuted,
2924 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2925 addr->index, addr->mem, am.new_op2,
2926 am.new_op2, am.ins_permuted,
2932 /* Cmp(left, right) */
2933 match_arguments(&am, block, left, right, NULL,
2934 match_commutative | match_am | match_8bit_am |
2935 match_16bit_am | match_am_and_immediates |
2936 match_immediate | match_8bit | match_16bit);
2937 if (get_mode_size_bits(cmp_mode) == 8) {
2938 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2939 addr->index, addr->mem, am.new_op1,
2940 am.new_op2, am.ins_permuted,
2943 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2944 addr->index, addr->mem, am.new_op1,
2945 am.new_op2, am.ins_permuted, cmp_unsigned);
2948 set_am_attributes(new_node, &am);
2949 assert(cmp_mode != NULL);
2950 set_ia32_ls_mode(new_node, cmp_mode);
2952 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2954 new_node = fix_mem_proj(new_node, &am);
2959 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2962 ir_graph *irg = current_ir_graph;
2963 dbg_info *dbgi = get_irn_dbg_info(node);
2964 ir_node *block = get_nodes_block(node);
2965 ir_node *new_block = be_transform_node(block);
2966 ir_node *val_true = get_Psi_val(node, 0);
2967 ir_node *val_false = get_Psi_default(node);
2969 match_flags_t match_flags;
2970 ia32_address_mode_t am;
2971 ia32_address_t *addr;
2973 assert(ia32_cg_config.use_cmov);
2974 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2978 match_flags = match_commutative | match_am | match_16bit_am |
2981 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2983 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2984 addr->mem, am.new_op1, am.new_op2, new_flags,
2985 am.ins_permuted, pnc);
2986 set_am_attributes(new_node, &am);
2988 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2990 new_node = fix_mem_proj(new_node, &am);
2996 * Creates a ia32 Setcc instruction.
2998 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2999 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
3002 ir_graph *irg = current_ir_graph;
3003 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3004 ir_node *nomem = new_NoMem();
3005 ir_mode *mode = get_irn_mode(orig_node);
3008 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
3009 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
3011 /* we might need to conv the result up */
3012 if (get_mode_size_bits(mode) > 8) {
3013 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
3014 nomem, new_node, mode_Bu);
3015 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
3022 * Create instruction for an unsigned Difference or Zero.
3024 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
3025 ir_graph *irg = current_ir_graph;
3026 ir_mode *mode = get_irn_mode(psi);
3027 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
3030 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
3031 match_mode_neutral | match_am | match_immediate | match_two_users);
3033 block = get_nodes_block(new_node);
3035 if (is_Proj(new_node)) {
3036 sub = get_Proj_pred(new_node);
3037 assert(is_ia32_Sub(sub));
3040 set_irn_mode(sub, mode_T);
3041 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
3043 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3045 dbgi = get_irn_dbg_info(psi);
3046 noreg = ia32_new_NoReg_gp(env_cg);
3047 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
3048 nomem = new_NoMem();
3049 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
3051 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
3052 set_ia32_commutative(new_node);
3057 * Transforms a Psi node into CMov.
3059 * @return The transformed node.
3061 static ir_node *gen_Psi(ir_node *node)
3063 dbg_info *dbgi = get_irn_dbg_info(node);
3064 ir_node *block = get_nodes_block(node);
3065 ir_node *new_block = be_transform_node(block);
3066 ir_node *psi_true = get_Psi_val(node, 0);
3067 ir_node *psi_default = get_Psi_default(node);
3068 ir_node *cond = get_Psi_cond(node, 0);
3069 ir_mode *mode = get_irn_mode(node);
3072 assert(get_Psi_n_conds(node) == 1);
3073 assert(get_irn_mode(cond) == mode_b);
3075 /* Note: a Psi node uses a Load two times IFF it's used in the compare AND in the result */
3076 if (mode_is_float(mode)) {
3077 ir_node *cmp = get_Proj_pred(cond);
3078 ir_node *cmp_left = get_Cmp_left(cmp);
3079 ir_node *cmp_right = get_Cmp_right(cmp);
3080 pn_Cmp pnc = get_Proj_proj(cond);
3082 if (ia32_cg_config.use_sse2) {
3083 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3084 if (cmp_left == psi_true && cmp_right == psi_default) {
3085 /* psi(a <= b, a, b) => MIN */
3086 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3087 match_commutative | match_am | match_two_users);
3088 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3089 /* psi(a <= b, b, a) => MAX */
3090 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3091 match_commutative | match_am | match_two_users);
3093 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3094 if (cmp_left == psi_true && cmp_right == psi_default) {
3095 /* psi(a >= b, a, b) => MAX */
3096 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3097 match_commutative | match_am | match_two_users);
3098 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3099 /* psi(a >= b, b, a) => MIN */
3100 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3101 match_commutative | match_am | match_two_users);
3105 panic("cannot transform floating point Psi");
3111 assert(ia32_mode_needs_gp_reg(mode));
3113 if (is_Proj(cond)) {
3114 ir_node *cmp = get_Proj_pred(cond);
3116 ir_node *cmp_left = get_Cmp_left(cmp);
3117 ir_node *cmp_right = get_Cmp_right(cmp);
3118 pn_Cmp pnc = get_Proj_proj(cond);
3120 /* check for unsigned Doz first */
3121 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3122 is_Const_0(psi_default) && is_Sub(psi_true) &&
3123 get_Sub_left(psi_true) == cmp_left && get_Sub_right(psi_true) == cmp_right) {
3124 /* Psi(a >=u b, a - b, 0) unsigned Doz */
3125 return create_Doz(node, cmp_left, cmp_right);
3126 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3127 is_Const_0(psi_true) && is_Sub(psi_default) &&
3128 get_Sub_left(psi_default) == cmp_left && get_Sub_right(psi_default) == cmp_right) {
3129 /* Psi(a <=u b, 0, a - b) unsigned Doz */
3130 return create_Doz(node, cmp_left, cmp_right);
3135 flags = get_flags_node(cond, &pnc);
3137 if (is_Const(psi_true) && is_Const(psi_default)) {
3138 /* both are const, good */
3139 if (is_Const_1(psi_true) && is_Const_0(psi_default)) {
3140 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3141 } else if (is_Const_0(psi_true) && is_Const_1(psi_default)) {
3142 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3144 /* Not that simple. */
3149 new_node = create_CMov(node, cond, flags, pnc);
3157 * Create a conversion from x87 state register to general purpose.
3159 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3160 ir_node *block = be_transform_node(get_nodes_block(node));
3161 ir_node *op = get_Conv_op(node);
3162 ir_node *new_op = be_transform_node(op);
3163 ia32_code_gen_t *cg = env_cg;
3164 ir_graph *irg = current_ir_graph;
3165 dbg_info *dbgi = get_irn_dbg_info(node);
3166 ir_node *noreg = ia32_new_NoReg_gp(cg);
3167 ir_mode *mode = get_irn_mode(node);
3168 ir_node *fist, *load, *mem;
3170 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3171 set_irn_pinned(fist, op_pin_state_floats);
3172 set_ia32_use_frame(fist);
3173 set_ia32_op_type(fist, ia32_AddrModeD);
3175 assert(get_mode_size_bits(mode) <= 32);
3176 /* exception we can only store signed 32 bit integers, so for unsigned
3177 we store a 64bit (signed) integer and load the lower bits */
3178 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3179 set_ia32_ls_mode(fist, mode_Ls);
3181 set_ia32_ls_mode(fist, mode_Is);
3183 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3186 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3188 set_irn_pinned(load, op_pin_state_floats);
3189 set_ia32_use_frame(load);
3190 set_ia32_op_type(load, ia32_AddrModeS);
3191 set_ia32_ls_mode(load, mode_Is);
3192 if(get_ia32_ls_mode(fist) == mode_Ls) {
3193 ia32_attr_t *attr = get_ia32_attr(load);
3194 attr->data.need_64bit_stackent = 1;
3196 ia32_attr_t *attr = get_ia32_attr(load);
3197 attr->data.need_32bit_stackent = 1;
3199 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3201 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3205 * Creates a x87 strict Conv by placing a Store and a Load
3207 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3209 ir_node *block = get_nodes_block(node);
3210 ir_graph *irg = current_ir_graph;
3211 dbg_info *dbgi = get_irn_dbg_info(node);
3212 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3213 ir_node *nomem = new_NoMem();
3214 ir_node *frame = get_irg_frame(irg);
3215 ir_node *store, *load;
3218 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3220 set_ia32_use_frame(store);
3221 set_ia32_op_type(store, ia32_AddrModeD);
3222 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3224 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3226 set_ia32_use_frame(load);
3227 set_ia32_op_type(load, ia32_AddrModeS);
3228 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3230 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3235 * Create a conversion from general purpose to x87 register
3237 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3238 ir_node *src_block = get_nodes_block(node);
3239 ir_node *block = be_transform_node(src_block);
3240 ir_graph *irg = current_ir_graph;
3241 dbg_info *dbgi = get_irn_dbg_info(node);
3242 ir_node *op = get_Conv_op(node);
3243 ir_node *new_op = NULL;
3247 ir_mode *store_mode;
3253 /* fild can use source AM if the operand is a signed 32bit integer */
3254 if (src_mode == mode_Is) {
3255 ia32_address_mode_t am;
3257 match_arguments(&am, src_block, NULL, op, NULL,
3258 match_am | match_try_am);
3259 if (am.op_type == ia32_AddrModeS) {
3260 ia32_address_t *addr = &am.addr;
3262 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3263 addr->index, addr->mem);
3264 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3267 set_am_attributes(fild, &am);
3268 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3270 fix_mem_proj(fild, &am);
3275 if(new_op == NULL) {
3276 new_op = be_transform_node(op);
3279 noreg = ia32_new_NoReg_gp(env_cg);
3280 nomem = new_NoMem();
3281 mode = get_irn_mode(op);
3283 /* first convert to 32 bit signed if necessary */
3284 src_bits = get_mode_size_bits(src_mode);
3285 if (src_bits == 8) {
3286 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3288 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3290 } else if (src_bits < 32) {
3291 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3293 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3297 assert(get_mode_size_bits(mode) == 32);
3300 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3303 set_ia32_use_frame(store);
3304 set_ia32_op_type(store, ia32_AddrModeD);
3305 set_ia32_ls_mode(store, mode_Iu);
3307 /* exception for 32bit unsigned, do a 64bit spill+load */
3308 if(!mode_is_signed(mode)) {
3311 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3313 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3314 get_irg_frame(irg), noreg, nomem,
3317 set_ia32_use_frame(zero_store);
3318 set_ia32_op_type(zero_store, ia32_AddrModeD);
3319 add_ia32_am_offs_int(zero_store, 4);
3320 set_ia32_ls_mode(zero_store, mode_Iu);
3325 store = new_rd_Sync(dbgi, irg, block, 2, in);
3326 store_mode = mode_Ls;
3328 store_mode = mode_Is;
3332 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3334 set_ia32_use_frame(fild);
3335 set_ia32_op_type(fild, ia32_AddrModeS);
3336 set_ia32_ls_mode(fild, store_mode);
3338 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3344 * Create a conversion from one integer mode into another one
3346 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3347 dbg_info *dbgi, ir_node *block, ir_node *op,
3350 ir_graph *irg = current_ir_graph;
3351 int src_bits = get_mode_size_bits(src_mode);
3352 int tgt_bits = get_mode_size_bits(tgt_mode);
3353 ir_node *new_block = be_transform_node(block);
3355 ir_mode *smaller_mode;
3357 ia32_address_mode_t am;
3358 ia32_address_t *addr = &am.addr;
3361 if (src_bits < tgt_bits) {
3362 smaller_mode = src_mode;
3363 smaller_bits = src_bits;
3365 smaller_mode = tgt_mode;
3366 smaller_bits = tgt_bits;
3369 #ifdef DEBUG_libfirm
3371 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3376 match_arguments(&am, block, NULL, op, NULL,
3377 match_8bit | match_16bit |
3378 match_am | match_8bit_am | match_16bit_am);
3379 if (smaller_bits == 8) {
3380 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3381 addr->index, addr->mem, am.new_op2,
3384 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3385 addr->index, addr->mem, am.new_op2,
3388 set_am_attributes(new_node, &am);
3389 /* match_arguments assume that out-mode = in-mode, this isn't true here
3391 set_ia32_ls_mode(new_node, smaller_mode);
3392 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3393 new_node = fix_mem_proj(new_node, &am);
3398 * Transforms a Conv node.
3400 * @return The created ia32 Conv node
3402 static ir_node *gen_Conv(ir_node *node) {
3403 ir_node *block = get_nodes_block(node);
3404 ir_node *new_block = be_transform_node(block);
3405 ir_node *op = get_Conv_op(node);
3406 ir_node *new_op = NULL;
3407 ir_graph *irg = current_ir_graph;
3408 dbg_info *dbgi = get_irn_dbg_info(node);
3409 ir_mode *src_mode = get_irn_mode(op);
3410 ir_mode *tgt_mode = get_irn_mode(node);
3411 int src_bits = get_mode_size_bits(src_mode);
3412 int tgt_bits = get_mode_size_bits(tgt_mode);
3413 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3414 ir_node *nomem = new_rd_NoMem(irg);
3415 ir_node *res = NULL;
3417 if (src_mode == mode_b) {
3418 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3419 /* nothing to do, we already model bools as 0/1 ints */
3420 return be_transform_node(op);
3423 if (src_mode == tgt_mode) {
3424 if (get_Conv_strict(node)) {
3425 if (ia32_cg_config.use_sse2) {
3426 /* when we are in SSE mode, we can kill all strict no-op conversion */
3427 return be_transform_node(op);
3430 /* this should be optimized already, but who knows... */
3431 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3432 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3433 return be_transform_node(op);
3437 if (mode_is_float(src_mode)) {
3438 new_op = be_transform_node(op);
3439 /* we convert from float ... */
3440 if (mode_is_float(tgt_mode)) {
3441 if(src_mode == mode_E && tgt_mode == mode_D
3442 && !get_Conv_strict(node)) {
3443 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3448 if (ia32_cg_config.use_sse2) {
3449 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3450 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3452 set_ia32_ls_mode(res, tgt_mode);
3454 if(get_Conv_strict(node)) {
3455 res = gen_x87_strict_conv(tgt_mode, new_op);
3456 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3459 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3464 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3465 if (ia32_cg_config.use_sse2) {
3466 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3468 set_ia32_ls_mode(res, src_mode);
3470 return gen_x87_fp_to_gp(node);
3474 /* we convert from int ... */
3475 if (mode_is_float(tgt_mode)) {
3477 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3478 if (ia32_cg_config.use_sse2) {
3479 new_op = be_transform_node(op);
3480 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3482 set_ia32_ls_mode(res, tgt_mode);
3484 res = gen_x87_gp_to_fp(node, src_mode);
3485 if(get_Conv_strict(node)) {
3486 /* The strict-Conv is only necessary, if the int mode has more bits
3487 * than the float mantissa */
3488 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3489 size_t float_mantissa;
3490 /* FIXME There is no way to get the mantissa size of a mode */
3491 switch (get_mode_size_bits(tgt_mode)) {
3492 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3493 case 64: float_mantissa = 52 + 1; break;
3494 case 80: float_mantissa = 64 + 1; break;
3495 default: float_mantissa = 0; break;
3497 if (float_mantissa < int_mantissa) {
3498 res = gen_x87_strict_conv(tgt_mode, res);
3499 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3504 } else if(tgt_mode == mode_b) {
3505 /* mode_b lowering already took care that we only have 0/1 values */
3506 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3507 src_mode, tgt_mode));
3508 return be_transform_node(op);
3511 if (src_bits == tgt_bits) {
3512 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3513 src_mode, tgt_mode));
3514 return be_transform_node(op);
3517 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3525 static int check_immediate_constraint(long val, char immediate_constraint_type)
3527 switch (immediate_constraint_type) {
3532 return val >= 0 && val <= 32;
3534 return val >= 0 && val <= 63;
3536 return val >= -128 && val <= 127;
3538 return val == 0xff || val == 0xffff;
3540 return val >= 0 && val <= 3;
3542 return val >= 0 && val <= 255;
3544 return val >= 0 && val <= 127;
3548 panic("Invalid immediate constraint found");
3552 static ir_node *try_create_Immediate(ir_node *node,
3553 char immediate_constraint_type)
3556 tarval *offset = NULL;
3557 int offset_sign = 0;
3559 ir_entity *symconst_ent = NULL;
3560 int symconst_sign = 0;
3562 ir_node *cnst = NULL;
3563 ir_node *symconst = NULL;
3566 mode = get_irn_mode(node);
3567 if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3571 if(is_Minus(node)) {
3573 node = get_Minus_op(node);
3576 if(is_Const(node)) {
3579 offset_sign = minus;
3580 } else if(is_SymConst(node)) {
3583 symconst_sign = minus;
3584 } else if(is_Add(node)) {
3585 ir_node *left = get_Add_left(node);
3586 ir_node *right = get_Add_right(node);
3587 if(is_Const(left) && is_SymConst(right)) {
3590 symconst_sign = minus;
3591 offset_sign = minus;
3592 } else if(is_SymConst(left) && is_Const(right)) {
3595 symconst_sign = minus;
3596 offset_sign = minus;
3598 } else if(is_Sub(node)) {
3599 ir_node *left = get_Sub_left(node);
3600 ir_node *right = get_Sub_right(node);
3601 if(is_Const(left) && is_SymConst(right)) {
3604 symconst_sign = !minus;
3605 offset_sign = minus;
3606 } else if(is_SymConst(left) && is_Const(right)) {
3609 symconst_sign = minus;
3610 offset_sign = !minus;
3617 offset = get_Const_tarval(cnst);
3618 if(tarval_is_long(offset)) {
3619 val = get_tarval_long(offset);
3621 ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3626 if(!check_immediate_constraint(val, immediate_constraint_type))
3629 if(symconst != NULL) {
3630 if(immediate_constraint_type != 0) {
3631 /* we need full 32bits for symconsts */
3635 /* unfortunately the assembler/linker doesn't support -symconst */
3639 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3641 symconst_ent = get_SymConst_entity(symconst);
3643 if(cnst == NULL && symconst == NULL)
3646 if(offset_sign && offset != NULL) {
3647 offset = tarval_neg(offset);
3650 new_node = create_Immediate(symconst_ent, symconst_sign, val);
3655 static ir_node *create_immediate_or_transform(ir_node *node,
3656 char immediate_constraint_type)
3658 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3659 if (new_node == NULL) {
3660 new_node = be_transform_node(node);
3667 void parse_asm_constraints(constraint_t *constraint, const char *c,
3670 asm_constraint_flags_t flags = 0;
3671 char immediate_type = '\0';
3672 unsigned limited = 0;
3673 const arch_register_class_t *cls = NULL;
3674 int memory_possible = 0;
3675 int all_registers_allowed = 0;
3679 memset(constraint, 0, sizeof(constraint[0]));
3680 constraint->same_as = -1;
3683 /* a memory constraint: no need to do anything in backend about it
3684 * (the dependencies are already respected by the memory edge of
3689 /* TODO: improve error messages with node and source info. (As users can
3690 * easily hit these) */
3699 flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE
3700 | ASM_CONSTRAINT_FLAG_MODIFIER_NO_READ;
3704 flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE
3705 | ASM_CONSTRAINT_FLAG_MODIFIER_READ;
3712 while(*c != 0 && *c != ',')
3717 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3718 cls = &ia32_reg_classes[CLASS_ia32_gp];
3719 limited |= 1 << REG_EAX;
3722 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3723 cls = &ia32_reg_classes[CLASS_ia32_gp];
3724 limited |= 1 << REG_EBX;
3727 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3728 cls = &ia32_reg_classes[CLASS_ia32_gp];
3729 limited |= 1 << REG_ECX;
3732 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3733 cls = &ia32_reg_classes[CLASS_ia32_gp];
3734 limited |= 1 << REG_EDX;
3737 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3738 cls = &ia32_reg_classes[CLASS_ia32_gp];
3739 limited |= 1 << REG_EDI;
3742 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3743 cls = &ia32_reg_classes[CLASS_ia32_gp];
3744 limited |= 1 << REG_ESI;
3748 /* q means lower part of the regs only, this makes no
3749 * difference to Q for us (we only assign whole registers) */
3750 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3751 cls = &ia32_reg_classes[CLASS_ia32_gp];
3752 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3756 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3757 cls = &ia32_reg_classes[CLASS_ia32_gp];
3758 limited |= 1 << REG_EAX | 1 << REG_EDX;
3761 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3762 cls = &ia32_reg_classes[CLASS_ia32_gp];
3763 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3764 1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3771 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3772 panic("multiple register classes not supported");
3773 cls = &ia32_reg_classes[CLASS_ia32_gp];
3774 all_registers_allowed = 1;
3780 /* TODO: mark values so the x87 simulator knows about t and u */
3781 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_vfp])
3782 panic("multiple register classes not supported");
3783 cls = &ia32_reg_classes[CLASS_ia32_vfp];
3784 all_registers_allowed = 1;
3789 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_xmm])
3790 panic("multiple register classes not supproted");
3791 cls = &ia32_reg_classes[CLASS_ia32_xmm];
3792 all_registers_allowed = 1;
3802 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3803 panic("multiple register classes not supported");
3804 if (immediate_type != '\0')
3805 panic("multiple immediate types not supported");
3806 cls = &ia32_reg_classes[CLASS_ia32_gp];
3807 immediate_type = *c;
3811 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3812 panic("multiple register classes not supported");
3813 if (immediate_type != '\0')
3814 panic("multiple immediate types not supported");
3815 cls = &ia32_reg_classes[CLASS_ia32_gp];
3816 immediate_type = 'i';
3821 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3822 panic("multiple register classes not supported");
3823 if (immediate_type != '\0')
3824 panic("multiple immediate types not supported");
3825 immediate_type = 'i';
3826 cls = &ia32_reg_classes[CLASS_ia32_gp];
3827 all_registers_allowed = 1;
3828 memory_possible = 1;
3842 panic("can only specify same constraint on input");
3844 sscanf(c, "%d%n", &same_as, &p);
3854 /* memory constraint no need to do anything in backend about it
3855 * (the dependencies are already respected by the memory edge of
3857 memory_possible = 1;
3860 case 'E': /* no float consts yet */
3861 case 'F': /* no float consts yet */
3862 case 's': /* makes no sense on x86 */
3863 case '<': /* no autodecrement on x86 */
3864 case '>': /* no autoincrement on x86 */
3865 case 'C': /* sse constant not supported yet */
3866 case 'G': /* 80387 constant not supported yet */
3867 case 'y': /* we don't support mmx registers yet */
3868 case 'Z': /* not available in 32 bit mode */
3869 case 'e': /* not available in 32 bit mode */
3870 panic("unsupported asm constraint '%c' found in (%+F)",
3871 *c, current_ir_graph);
3874 panic("unknown asm constraint '%c' found in (%+F)", *c,
3883 panic("same as and register constraint not supported");
3884 if (immediate_type != '\0')
3885 panic("same as and immediate constraint not supported");
3888 if (cls == NULL && same_as < 0) {
3889 if (!memory_possible)
3890 panic("no constraint specified for assembler input");
3893 constraint->same_as = same_as;
3894 constraint->cls = cls;
3895 constraint->allowed_registers = limited;
3896 constraint->all_registers_allowed = all_registers_allowed;
3897 constraint->memory_possible = memory_possible;
3898 constraint->immediate_type = immediate_type;
3901 const arch_register_req_t *make_register_req(const constraint_t *constraint,
3902 int n_outs, const arch_register_req_t **out_reqs, int pos)
3904 struct obstack *obst = get_irg_obstack(current_ir_graph);
3905 int same_as = constraint->same_as;
3906 arch_register_req_t *req;
3909 const arch_register_req_t *other_constr;
3911 if (same_as >= n_outs)
3912 panic("invalid output number in same_as constraint");
3914 other_constr = out_reqs[same_as];
3916 req = obstack_alloc(obst, sizeof(req[0]));
3917 req->cls = other_constr->cls;
3918 req->type = arch_register_req_type_should_be_same;
3919 req->limited = NULL;
3920 req->other_same = 1U << pos;
3921 req->other_different = 0;
3923 /* switch constraints. This is because in firm we have same_as
3924 * constraints on the output constraints while in the gcc asm syntax
3925 * they are specified on the input constraints */
3926 out_reqs[same_as] = req;
3927 return other_constr;
3930 /* pure memory ops */
3931 if (constraint->cls == NULL) {
3932 return &no_register_req;
3935 if (constraint->allowed_registers != 0
3936 && !constraint->all_registers_allowed) {
3937 unsigned *limited_ptr;
3939 req = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3940 memset(req, 0, sizeof(req[0]));
3941 limited_ptr = (unsigned*) (req+1);
3943 req->type = arch_register_req_type_limited;
3944 *limited_ptr = constraint->allowed_registers;
3945 req->limited = limited_ptr;
3947 req = obstack_alloc(obst, sizeof(req[0]));
3948 memset(req, 0, sizeof(req[0]));
3949 req->type = arch_register_req_type_normal;
3951 req->cls = constraint->cls;
3956 const arch_register_t *ia32_get_clobber_register(const char *clobber)
3958 const arch_register_t *reg = NULL;
3961 const arch_register_class_t *cls;
3963 /* TODO: construct a hashmap instead of doing linear search for clobber
3965 for(c = 0; c < N_CLASSES; ++c) {
3966 cls = & ia32_reg_classes[c];
3967 for(r = 0; r < cls->n_regs; ++r) {
3968 const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3969 if(strcmp(temp_reg->name, clobber) == 0
3970 || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3982 const arch_register_req_t *parse_clobber(const char *clobber)
3984 struct obstack *obst = get_irg_obstack(current_ir_graph);
3985 const arch_register_t *reg = ia32_get_clobber_register(clobber);
3986 arch_register_req_t *req;
3990 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3993 assert(reg->index < 32);
3995 limited = obstack_alloc(obst, sizeof(limited[0]));
3996 *limited = 1 << reg->index;
3998 req = obstack_alloc(obst, sizeof(req[0]));
3999 memset(req, 0, sizeof(req[0]));
4000 req->type = arch_register_req_type_limited;
4001 req->cls = arch_register_get_class(reg);
4002 req->limited = limited;
4008 * generates code for a ASM node
4010 static ir_node *gen_ASM(ir_node *node)
4012 ir_graph *irg = current_ir_graph;
4013 ir_node *block = get_nodes_block(node);
4014 ir_node *new_block = be_transform_node(block);
4015 dbg_info *dbgi = get_irn_dbg_info(node);
4021 int n_out_constraints;
4023 const arch_register_req_t **out_reg_reqs;
4024 const arch_register_req_t **in_reg_reqs;
4025 ia32_asm_reg_t *register_map;
4026 unsigned reg_map_size = 0;
4027 struct obstack *obst;
4028 const ir_asm_constraint *in_constraints;
4029 const ir_asm_constraint *out_constraints;
4031 int clobbers_flags = 0;
4033 /* workaround for lots of buggy code out there as most people think volatile
4034 * asm is enough for everything and forget the flags (linux kernel, etc.)
4036 if (get_irn_pinned(node) == op_pin_state_pinned) {
4040 arity = get_irn_arity(node);
4041 in = alloca(arity * sizeof(in[0]));
4042 memset(in, 0, arity * sizeof(in[0]));
4044 clobbers = get_ASM_clobbers(node);
4046 for(i = 0; i < get_ASM_n_clobbers(node); ++i) {
4047 const char *c = get_id_str(clobbers[i]);
4048 if (strcmp(c, "memory") == 0)
4050 if (strcmp(c, "cc") == 0) {
4056 n_out_constraints = get_ASM_n_output_constraints(node);
4057 out_arity = n_out_constraints + n_clobbers;
4059 in_constraints = get_ASM_input_constraints(node);
4060 out_constraints = get_ASM_output_constraints(node);
4062 /* determine size of register_map */
4063 for(out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
4064 const ir_asm_constraint *constraint = &out_constraints[out_idx];
4065 if (constraint->pos > reg_map_size)
4066 reg_map_size = constraint->pos;
4068 for(i = 0; i < arity; ++i) {
4069 const ir_asm_constraint *constraint = &in_constraints[i];
4070 if(constraint->pos > reg_map_size)
4071 reg_map_size = constraint->pos;
4075 obst = get_irg_obstack(irg);
4076 register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
4077 memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
4079 /* construct output constraints */
4080 out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
4082 for(out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
4083 const ir_asm_constraint *constraint = &out_constraints[out_idx];
4084 const char *c = get_id_str(constraint->constraint);
4085 unsigned pos = constraint->pos;
4086 constraint_t parsed_constraint;
4087 const arch_register_req_t *req;
4089 parse_asm_constraints(&parsed_constraint, c, 1);
4090 req = make_register_req(&parsed_constraint, n_out_constraints,
4091 out_reg_reqs, out_idx);
4092 out_reg_reqs[out_idx] = req;
4094 register_map[pos].use_input = 0;
4095 register_map[pos].valid = 1;
4096 register_map[pos].memory = 0;
4097 register_map[pos].inout_pos = out_idx;
4098 register_map[pos].mode = constraint->mode;
4101 /* inputs + input constraints */
4102 in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
4103 for(i = 0; i < arity; ++i) {
4104 ir_node *pred = get_irn_n(node, i);
4105 const ir_asm_constraint *constraint = &in_constraints[i];
4106 ident *constr_id = constraint->constraint;
4107 const char *c = get_id_str(constr_id);
4108 unsigned pos = constraint->pos;
4109 int is_memory_op = 0;
4110 ir_node *input = NULL;
4111 constraint_t parsed_constraint;
4112 const arch_register_req_t *req;
4114 parse_asm_constraints(&parsed_constraint, c, 0);
4115 req = make_register_req(&parsed_constraint, n_out_constraints,
4117 in_reg_reqs[i] = req;
4119 if (parsed_constraint.immediate_type != '\0') {
4120 char imm_type = parsed_constraint.immediate_type;
4121 input = try_create_Immediate(pred, imm_type);
4124 if (input == NULL) {
4125 ir_node *pred = get_irn_n(node, i);
4126 input = be_transform_node(pred);
4128 if (parsed_constraint.cls == NULL
4129 && parsed_constraint.same_as < 0) {
4131 } else if(parsed_constraint.memory_possible) {
4132 /* TODO: match Load or Load/Store if memory possible is set */
4137 register_map[pos].use_input = 1;
4138 register_map[pos].valid = 1;
4139 register_map[pos].memory = is_memory_op;
4140 register_map[pos].inout_pos = i;
4141 register_map[pos].mode = constraint->mode;
4144 /* parse clobbers */
4145 for(i = 0; i < get_ASM_n_clobbers(node); ++i) {
4146 const char *c = get_id_str(clobbers[i]);
4147 const arch_register_req_t *req;
4149 if (strcmp(c, "memory") == 0 || strcmp(c, "cc") == 0)
4152 req = parse_clobber(c);
4153 out_reg_reqs[out_idx] = req;
4157 new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
4158 get_ASM_text(node), register_map);
4160 set_ia32_out_req_all(new_node, out_reg_reqs);
4161 set_ia32_in_req_all(new_node, in_reg_reqs);
4163 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4169 * Transforms a FrameAddr into an ia32 Add.
4171 static ir_node *gen_be_FrameAddr(ir_node *node) {
4172 ir_node *block = be_transform_node(get_nodes_block(node));
4173 ir_node *op = be_get_FrameAddr_frame(node);
4174 ir_node *new_op = be_transform_node(op);
4175 ir_graph *irg = current_ir_graph;
4176 dbg_info *dbgi = get_irn_dbg_info(node);
4177 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4180 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
4181 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
4182 set_ia32_use_frame(new_node);
4184 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4190 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
4192 static ir_node *gen_be_Return(ir_node *node) {
4193 ir_graph *irg = current_ir_graph;
4194 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
4195 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
4196 ir_entity *ent = get_irg_entity(irg);
4197 ir_type *tp = get_entity_type(ent);
4202 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
4203 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
4206 int pn_ret_val, pn_ret_mem, arity, i;
4208 assert(ret_val != NULL);
4209 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4210 return be_duplicate_node(node);
4213 res_type = get_method_res_type(tp, 0);
4215 if (! is_Primitive_type(res_type)) {
4216 return be_duplicate_node(node);
4219 mode = get_type_mode(res_type);
4220 if (! mode_is_float(mode)) {
4221 return be_duplicate_node(node);
4224 assert(get_method_n_ress(tp) == 1);
4226 pn_ret_val = get_Proj_proj(ret_val);
4227 pn_ret_mem = get_Proj_proj(ret_mem);
4229 /* get the Barrier */
4230 barrier = get_Proj_pred(ret_val);
4232 /* get result input of the Barrier */
4233 ret_val = get_irn_n(barrier, pn_ret_val);
4234 new_ret_val = be_transform_node(ret_val);
4236 /* get memory input of the Barrier */
4237 ret_mem = get_irn_n(barrier, pn_ret_mem);
4238 new_ret_mem = be_transform_node(ret_mem);
4240 frame = get_irg_frame(irg);
4242 dbgi = get_irn_dbg_info(barrier);
4243 block = be_transform_node(get_nodes_block(barrier));
4245 noreg = ia32_new_NoReg_gp(env_cg);
4247 /* store xmm0 onto stack */
4248 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
4249 new_ret_mem, new_ret_val);
4250 set_ia32_ls_mode(sse_store, mode);
4251 set_ia32_op_type(sse_store, ia32_AddrModeD);
4252 set_ia32_use_frame(sse_store);
4254 /* load into x87 register */
4255 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
4256 set_ia32_op_type(fld, ia32_AddrModeS);
4257 set_ia32_use_frame(fld);
4259 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
4260 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
4262 /* create a new barrier */
4263 arity = get_irn_arity(barrier);
4264 in = alloca(arity * sizeof(in[0]));
4265 for (i = 0; i < arity; ++i) {
4268 if (i == pn_ret_val) {
4270 } else if (i == pn_ret_mem) {
4273 ir_node *in = get_irn_n(barrier, i);
4274 new_in = be_transform_node(in);
4279 new_barrier = new_ir_node(dbgi, irg, block,
4280 get_irn_op(barrier), get_irn_mode(barrier),
4282 copy_node_attr(barrier, new_barrier);
4283 be_duplicate_deps(barrier, new_barrier);
4284 be_set_transformed_node(barrier, new_barrier);
4285 mark_irn_visited(barrier);
4287 /* transform normally */
4288 return be_duplicate_node(node);
4292 * Transform a be_AddSP into an ia32_SubSP.
4294 static ir_node *gen_be_AddSP(ir_node *node)
4296 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4297 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4299 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
4303 * Transform a be_SubSP into an ia32_AddSP
4305 static ir_node *gen_be_SubSP(ir_node *node)
4307 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4308 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4310 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
4314 * This function just sets the register for the Unknown node
4315 * as this is not done during register allocation because Unknown
4316 * is an "ignore" node.
4318 static ir_node *gen_Unknown(ir_node *node) {
4319 ir_mode *mode = get_irn_mode(node);
4321 if (mode_is_float(mode)) {
4322 if (ia32_cg_config.use_sse2) {
4323 return ia32_new_Unknown_xmm(env_cg);
4325 /* Unknown nodes are buggy in x87 simulator, use zero for now... */
4326 ir_graph *irg = current_ir_graph;
4327 dbg_info *dbgi = get_irn_dbg_info(node);
4328 ir_node *block = get_irg_start_block(irg);
4329 ir_node *ret = new_rd_ia32_vfldz(dbgi, irg, block);
4331 /* Const Nodes before the initial IncSP are a bad idea, because
4332 * they could be spilled and we have no SP ready at that point yet.
4333 * So add a dependency to the initial frame pointer calculation to
4334 * avoid that situation.
4336 add_irn_dep(ret, get_irg_frame(irg));
4339 } else if (ia32_mode_needs_gp_reg(mode)) {
4340 return ia32_new_Unknown_gp(env_cg);
4342 panic("unsupported Unknown-Mode");
4348 * Change some phi modes
4350 static ir_node *gen_Phi(ir_node *node) {
4351 ir_node *block = be_transform_node(get_nodes_block(node));
4352 ir_graph *irg = current_ir_graph;
4353 dbg_info *dbgi = get_irn_dbg_info(node);
4354 ir_mode *mode = get_irn_mode(node);
4357 if(ia32_mode_needs_gp_reg(mode)) {
4358 /* we shouldn't have any 64bit stuff around anymore */
4359 assert(get_mode_size_bits(mode) <= 32);
4360 /* all integer operations are on 32bit registers now */
4362 } else if(mode_is_float(mode)) {
4363 if (ia32_cg_config.use_sse2) {
4370 /* phi nodes allow loops, so we use the old arguments for now
4371 * and fix this later */
4372 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4373 get_irn_in(node) + 1);
4374 copy_node_attr(node, phi);
4375 be_duplicate_deps(node, phi);
4377 be_set_transformed_node(node, phi);
4378 be_enqueue_preds(node);
4386 static ir_node *gen_IJmp(ir_node *node)
4388 ir_node *block = get_nodes_block(node);
4389 ir_node *new_block = be_transform_node(block);
4390 dbg_info *dbgi = get_irn_dbg_info(node);
4391 ir_node *op = get_IJmp_target(node);
4393 ia32_address_mode_t am;
4394 ia32_address_t *addr = &am.addr;
4396 assert(get_irn_mode(op) == mode_P);
4398 match_arguments(&am, block, NULL, op, NULL,
4399 match_am | match_8bit_am | match_16bit_am |
4400 match_immediate | match_8bit | match_16bit);
4402 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
4403 addr->base, addr->index, addr->mem,
4405 set_am_attributes(new_node, &am);
4406 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4408 new_node = fix_mem_proj(new_node, &am);
4414 * Transform a Bound node.
4416 static ir_node *gen_Bound(ir_node *node)
4419 ir_node *lower = get_Bound_lower(node);
4420 dbg_info *dbgi = get_irn_dbg_info(node);
4422 if (is_Const_0(lower)) {
4423 /* typical case for Java */
4424 ir_node *sub, *res, *flags, *block;
4425 ir_graph *irg = current_ir_graph;
4427 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
4428 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
4430 block = get_nodes_block(res);
4431 if (! is_Proj(res)) {
4433 set_irn_mode(sub, mode_T);
4434 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
4436 sub = get_Proj_pred(res);
4438 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
4439 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
4440 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4442 panic("generic Bound not supported in ia32 Backend");
4448 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4451 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4452 ir_node *val, ir_node *mem);
4455 * Transforms a lowered Load into a "real" one.
4457 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4459 ir_node *block = be_transform_node(get_nodes_block(node));
4460 ir_node *ptr = get_irn_n(node, 0);
4461 ir_node *new_ptr = be_transform_node(ptr);
4462 ir_node *mem = get_irn_n(node, 1);
4463 ir_node *new_mem = be_transform_node(mem);
4464 ir_graph *irg = current_ir_graph;
4465 dbg_info *dbgi = get_irn_dbg_info(node);
4466 ir_mode *mode = get_ia32_ls_mode(node);
4467 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4470 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4472 set_ia32_op_type(new_op, ia32_AddrModeS);
4473 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4474 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4475 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4476 if (is_ia32_am_sc_sign(node))
4477 set_ia32_am_sc_sign(new_op);
4478 set_ia32_ls_mode(new_op, mode);
4479 if (is_ia32_use_frame(node)) {
4480 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4481 set_ia32_use_frame(new_op);
4484 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4490 * Transforms a lowered Store into a "real" one.
4492 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4494 ir_node *block = be_transform_node(get_nodes_block(node));
4495 ir_node *ptr = get_irn_n(node, 0);
4496 ir_node *new_ptr = be_transform_node(ptr);
4497 ir_node *val = get_irn_n(node, 1);
4498 ir_node *new_val = be_transform_node(val);
4499 ir_node *mem = get_irn_n(node, 2);
4500 ir_node *new_mem = be_transform_node(mem);
4501 ir_graph *irg = current_ir_graph;
4502 dbg_info *dbgi = get_irn_dbg_info(node);
4503 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4504 ir_mode *mode = get_ia32_ls_mode(node);
4508 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4510 am_offs = get_ia32_am_offs_int(node);
4511 add_ia32_am_offs_int(new_op, am_offs);
4513 set_ia32_op_type(new_op, ia32_AddrModeD);
4514 set_ia32_ls_mode(new_op, mode);
4515 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4516 set_ia32_use_frame(new_op);
4518 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4523 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4525 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4526 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4528 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4529 match_immediate | match_mode_neutral);
4532 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4534 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4535 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4536 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4540 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4542 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4543 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4544 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4548 static ir_node *gen_ia32_l_Add(ir_node *node) {
4549 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4550 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4551 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4552 match_commutative | match_am | match_immediate |
4553 match_mode_neutral);
4555 if(is_Proj(lowered)) {
4556 lowered = get_Proj_pred(lowered);
4558 assert(is_ia32_Add(lowered));
4559 set_irn_mode(lowered, mode_T);
4565 static ir_node *gen_ia32_l_Adc(ir_node *node)
4567 return gen_binop_flags(node, new_rd_ia32_Adc,
4568 match_commutative | match_am | match_immediate |
4569 match_mode_neutral);
4573 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4575 * @param node The node to transform
4576 * @return the created ia32 vfild node
4578 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4579 return gen_lowered_Load(node, new_rd_ia32_vfild);
4583 * Transforms an ia32_l_Load into a "real" ia32_Load node
4585 * @param node The node to transform
4586 * @return the created ia32 Load node
4588 static ir_node *gen_ia32_l_Load(ir_node *node) {
4589 return gen_lowered_Load(node, new_rd_ia32_Load);
4593 * Transforms an ia32_l_Store into a "real" ia32_Store node
4595 * @param node The node to transform
4596 * @return the created ia32 Store node
4598 static ir_node *gen_ia32_l_Store(ir_node *node) {
4599 return gen_lowered_Store(node, new_rd_ia32_Store);
4603 * Transforms a l_vfist into a "real" vfist node.
4605 * @param node The node to transform
4606 * @return the created ia32 vfist node
4608 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4609 ir_node *block = be_transform_node(get_nodes_block(node));
4610 ir_node *ptr = get_irn_n(node, 0);
4611 ir_node *new_ptr = be_transform_node(ptr);
4612 ir_node *val = get_irn_n(node, 1);
4613 ir_node *new_val = be_transform_node(val);
4614 ir_node *mem = get_irn_n(node, 2);
4615 ir_node *new_mem = be_transform_node(mem);
4616 ir_graph *irg = current_ir_graph;
4617 dbg_info *dbgi = get_irn_dbg_info(node);
4618 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4619 ir_mode *mode = get_ia32_ls_mode(node);
4620 ir_node *memres, *fist;
4623 memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
4624 am_offs = get_ia32_am_offs_int(node);
4625 add_ia32_am_offs_int(fist, am_offs);
4627 set_ia32_op_type(fist, ia32_AddrModeD);
4628 set_ia32_ls_mode(fist, mode);
4629 set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
4630 set_ia32_use_frame(fist);
4632 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4638 * Transforms a l_MulS into a "real" MulS node.
4640 * @return the created ia32 Mul node
4642 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4643 ir_node *left = get_binop_left(node);
4644 ir_node *right = get_binop_right(node);
4646 return gen_binop(node, left, right, new_rd_ia32_Mul,
4647 match_commutative | match_am | match_mode_neutral);
4651 * Transforms a l_IMulS into a "real" IMul1OPS node.
4653 * @return the created ia32 IMul1OP node
4655 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4656 ir_node *left = get_binop_left(node);
4657 ir_node *right = get_binop_right(node);
4659 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4660 match_commutative | match_am | match_mode_neutral);
4663 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4664 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4665 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4666 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4667 match_am | match_immediate | match_mode_neutral);
4669 if(is_Proj(lowered)) {
4670 lowered = get_Proj_pred(lowered);
4672 assert(is_ia32_Sub(lowered));
4673 set_irn_mode(lowered, mode_T);
4679 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4680 return gen_binop_flags(node, new_rd_ia32_Sbb,
4681 match_am | match_immediate | match_mode_neutral);
4685 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4686 * op1 - target to be shifted
4687 * op2 - contains bits to be shifted into target
4689 * Only op3 can be an immediate.
4691 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4692 ir_node *low, ir_node *count)
4694 ir_node *block = get_nodes_block(node);
4695 ir_node *new_block = be_transform_node(block);
4696 ir_graph *irg = current_ir_graph;
4697 dbg_info *dbgi = get_irn_dbg_info(node);
4698 ir_node *new_high = be_transform_node(high);
4699 ir_node *new_low = be_transform_node(low);
4703 /* the shift amount can be any mode that is bigger than 5 bits, since all
4704 * other bits are ignored anyway */
4705 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4706 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4707 count = get_Conv_op(count);
4709 new_count = create_immediate_or_transform(count, 0);
4711 if (is_ia32_l_ShlD(node)) {
4712 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4715 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4718 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4723 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4725 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4726 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4727 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4728 return gen_lowered_64bit_shifts(node, high, low, count);
4731 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4733 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4734 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4735 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4736 return gen_lowered_64bit_shifts(node, high, low, count);
4739 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4740 ir_node *src_block = get_nodes_block(node);
4741 ir_node *block = be_transform_node(src_block);
4742 ir_graph *irg = current_ir_graph;
4743 dbg_info *dbgi = get_irn_dbg_info(node);
4744 ir_node *frame = get_irg_frame(irg);
4745 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4746 ir_node *nomem = new_NoMem();
4747 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4748 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4749 ir_node *new_val_low = be_transform_node(val_low);
4750 ir_node *new_val_high = be_transform_node(val_high);
4755 ir_node *store_high;
4757 if(!mode_is_signed(get_irn_mode(val_high))) {
4758 panic("unsigned long long -> float not supported yet (%+F)", node);
4762 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4764 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4766 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4767 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4769 set_ia32_use_frame(store_low);
4770 set_ia32_use_frame(store_high);
4771 set_ia32_op_type(store_low, ia32_AddrModeD);
4772 set_ia32_op_type(store_high, ia32_AddrModeD);
4773 set_ia32_ls_mode(store_low, mode_Iu);
4774 set_ia32_ls_mode(store_high, mode_Is);
4775 add_ia32_am_offs_int(store_high, 4);
4779 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4782 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4784 set_ia32_use_frame(fild);
4785 set_ia32_op_type(fild, ia32_AddrModeS);
4786 set_ia32_ls_mode(fild, mode_Ls);
4788 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4790 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4793 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4794 ir_node *src_block = get_nodes_block(node);
4795 ir_node *block = be_transform_node(src_block);
4796 ir_graph *irg = current_ir_graph;
4797 dbg_info *dbgi = get_irn_dbg_info(node);
4798 ir_node *frame = get_irg_frame(irg);
4799 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4800 ir_node *nomem = new_NoMem();
4801 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4802 ir_node *new_val = be_transform_node(val);
4803 ir_node *fist, *mem;
4805 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4806 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4807 set_ia32_use_frame(fist);
4808 set_ia32_op_type(fist, ia32_AddrModeD);
4809 set_ia32_ls_mode(fist, mode_Ls);
4815 * the BAD transformer.
4817 static ir_node *bad_transform(ir_node *node) {
4818 panic("No transform function for %+F available.\n", node);
4822 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4823 ir_graph *irg = current_ir_graph;
4824 ir_node *block = be_transform_node(get_nodes_block(node));
4825 ir_node *pred = get_Proj_pred(node);
4826 ir_node *new_pred = be_transform_node(pred);
4827 ir_node *frame = get_irg_frame(irg);
4828 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4829 dbg_info *dbgi = get_irn_dbg_info(node);
4830 long pn = get_Proj_proj(node);
4835 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4836 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4837 set_ia32_use_frame(load);
4838 set_ia32_op_type(load, ia32_AddrModeS);
4839 set_ia32_ls_mode(load, mode_Iu);
4840 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4841 * 32 bit from it with this particular load */
4842 attr = get_ia32_attr(load);
4843 attr->data.need_64bit_stackent = 1;
4845 if (pn == pn_ia32_l_FloattoLL_res_high) {
4846 add_ia32_am_offs_int(load, 4);
4848 assert(pn == pn_ia32_l_FloattoLL_res_low);
4851 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4857 * Transform the Projs of an AddSP.
4859 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4860 ir_node *block = be_transform_node(get_nodes_block(node));
4861 ir_node *pred = get_Proj_pred(node);
4862 ir_node *new_pred = be_transform_node(pred);
4863 ir_graph *irg = current_ir_graph;
4864 dbg_info *dbgi = get_irn_dbg_info(node);
4865 long proj = get_Proj_proj(node);
4867 if (proj == pn_be_AddSP_sp) {
4868 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4869 pn_ia32_SubSP_stack);
4870 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4872 } else if(proj == pn_be_AddSP_res) {
4873 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4874 pn_ia32_SubSP_addr);
4875 } else if (proj == pn_be_AddSP_M) {
4876 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4880 return new_rd_Unknown(irg, get_irn_mode(node));
4884 * Transform the Projs of a SubSP.
4886 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4887 ir_node *block = be_transform_node(get_nodes_block(node));
4888 ir_node *pred = get_Proj_pred(node);
4889 ir_node *new_pred = be_transform_node(pred);
4890 ir_graph *irg = current_ir_graph;
4891 dbg_info *dbgi = get_irn_dbg_info(node);
4892 long proj = get_Proj_proj(node);
4894 if (proj == pn_be_SubSP_sp) {
4895 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4896 pn_ia32_AddSP_stack);
4897 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4899 } else if (proj == pn_be_SubSP_M) {
4900 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4904 return new_rd_Unknown(irg, get_irn_mode(node));
4908 * Transform and renumber the Projs from a Load.
4910 static ir_node *gen_Proj_Load(ir_node *node) {
4912 ir_node *block = be_transform_node(get_nodes_block(node));
4913 ir_node *pred = get_Proj_pred(node);
4914 ir_graph *irg = current_ir_graph;
4915 dbg_info *dbgi = get_irn_dbg_info(node);
4916 long proj = get_Proj_proj(node);
4918 /* loads might be part of source address mode matches, so we don't
4919 * transform the ProjMs yet (with the exception of loads whose result is
4922 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4925 /* this is needed, because sometimes we have loops that are only
4926 reachable through the ProjM */
4927 be_enqueue_preds(node);
4928 /* do it in 2 steps, to silence firm verifier */
4929 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4930 set_Proj_proj(res, pn_ia32_mem);
4934 /* renumber the proj */
4935 new_pred = be_transform_node(pred);
4936 if (is_ia32_Load(new_pred)) {
4939 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4941 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4942 case pn_Load_X_regular:
4943 return new_rd_Jmp(dbgi, irg, block);
4944 case pn_Load_X_except:
4945 /* This Load might raise an exception. Mark it. */
4946 set_ia32_exc_label(new_pred, 1);
4947 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4951 } else if (is_ia32_Conv_I2I(new_pred) ||
4952 is_ia32_Conv_I2I8Bit(new_pred)) {
4953 set_irn_mode(new_pred, mode_T);
4954 if (proj == pn_Load_res) {
4955 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4956 } else if (proj == pn_Load_M) {
4957 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4959 } else if (is_ia32_xLoad(new_pred)) {
4962 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4964 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4965 case pn_Load_X_regular:
4966 return new_rd_Jmp(dbgi, irg, block);
4967 case pn_Load_X_except:
4968 /* This Load might raise an exception. Mark it. */
4969 set_ia32_exc_label(new_pred, 1);
4970 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4974 } else if (is_ia32_vfld(new_pred)) {
4977 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4979 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4980 case pn_Load_X_regular:
4981 return new_rd_Jmp(dbgi, irg, block);
4982 case pn_Load_X_except:
4983 /* This Load might raise an exception. Mark it. */
4984 set_ia32_exc_label(new_pred, 1);
4985 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4990 /* can happen for ProJMs when source address mode happened for the
4993 /* however it should not be the result proj, as that would mean the
4994 load had multiple users and should not have been used for
4996 if (proj != pn_Load_M) {
4997 panic("internal error: transformed node not a Load");
4999 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
5003 return new_rd_Unknown(irg, get_irn_mode(node));
5007 * Transform and renumber the Projs from a DivMod like instruction.
5009 static ir_node *gen_Proj_DivMod(ir_node *node) {
5010 ir_node *block = be_transform_node(get_nodes_block(node));
5011 ir_node *pred = get_Proj_pred(node);
5012 ir_node *new_pred = be_transform_node(pred);
5013 ir_graph *irg = current_ir_graph;
5014 dbg_info *dbgi = get_irn_dbg_info(node);
5015 ir_mode *mode = get_irn_mode(node);
5016 long proj = get_Proj_proj(node);
5018 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
5020 switch (get_irn_opcode(pred)) {
5024 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
5026 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
5027 case pn_Div_X_regular:
5028 return new_rd_Jmp(dbgi, irg, block);
5029 case pn_Div_X_except:
5030 set_ia32_exc_label(new_pred, 1);
5031 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
5039 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
5041 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
5042 case pn_Mod_X_except:
5043 set_ia32_exc_label(new_pred, 1);
5044 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
5052 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
5053 case pn_DivMod_res_div:
5054 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
5055 case pn_DivMod_res_mod:
5056 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
5057 case pn_DivMod_X_regular:
5058 return new_rd_Jmp(dbgi, irg, block);
5059 case pn_DivMod_X_except:
5060 set_ia32_exc_label(new_pred, 1);
5061 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
5071 return new_rd_Unknown(irg, mode);
5075 * Transform and renumber the Projs from a CopyB.
5077 static ir_node *gen_Proj_CopyB(ir_node *node) {
5078 ir_node *block = be_transform_node(get_nodes_block(node));
5079 ir_node *pred = get_Proj_pred(node);
5080 ir_node *new_pred = be_transform_node(pred);
5081 ir_graph *irg = current_ir_graph;
5082 dbg_info *dbgi = get_irn_dbg_info(node);
5083 ir_mode *mode = get_irn_mode(node);
5084 long proj = get_Proj_proj(node);
5087 case pn_CopyB_M_regular:
5088 if (is_ia32_CopyB_i(new_pred)) {
5089 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
5090 } else if (is_ia32_CopyB(new_pred)) {
5091 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
5099 return new_rd_Unknown(irg, mode);
5103 * Transform and renumber the Projs from a Quot.
5105 static ir_node *gen_Proj_Quot(ir_node *node) {
5106 ir_node *block = be_transform_node(get_nodes_block(node));
5107 ir_node *pred = get_Proj_pred(node);
5108 ir_node *new_pred = be_transform_node(pred);
5109 ir_graph *irg = current_ir_graph;
5110 dbg_info *dbgi = get_irn_dbg_info(node);
5111 ir_mode *mode = get_irn_mode(node);
5112 long proj = get_Proj_proj(node);
5116 if (is_ia32_xDiv(new_pred)) {
5117 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
5118 } else if (is_ia32_vfdiv(new_pred)) {
5119 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
5123 if (is_ia32_xDiv(new_pred)) {
5124 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
5125 } else if (is_ia32_vfdiv(new_pred)) {
5126 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
5129 case pn_Quot_X_regular:
5130 case pn_Quot_X_except:
5136 return new_rd_Unknown(irg, mode);
5140 * Transform the Thread Local Storage Proj.
5142 static ir_node *gen_Proj_tls(ir_node *node) {
5143 ir_node *block = be_transform_node(get_nodes_block(node));
5144 ir_graph *irg = current_ir_graph;
5145 dbg_info *dbgi = NULL;
5146 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
5151 static ir_node *gen_be_Call(ir_node *node) {
5152 ir_node *res = be_duplicate_node(node);
5153 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5158 static ir_node *gen_be_IncSP(ir_node *node) {
5159 ir_node *res = be_duplicate_node(node);
5160 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5166 * Transform the Projs from a be_Call.
5168 static ir_node *gen_Proj_be_Call(ir_node *node) {
5169 ir_node *block = be_transform_node(get_nodes_block(node));
5170 ir_node *call = get_Proj_pred(node);
5171 ir_node *new_call = be_transform_node(call);
5172 ir_graph *irg = current_ir_graph;
5173 dbg_info *dbgi = get_irn_dbg_info(node);
5174 ir_type *method_type = be_Call_get_type(call);
5175 int n_res = get_method_n_ress(method_type);
5176 long proj = get_Proj_proj(node);
5177 ir_mode *mode = get_irn_mode(node);
5179 const arch_register_class_t *cls;
5181 /* The following is kinda tricky: If we're using SSE, then we have to
5182 * move the result value of the call in floating point registers to an
5183 * xmm register, we therefore construct a GetST0 -> xLoad sequence
5184 * after the call, we have to make sure to correctly make the
5185 * MemProj and the result Proj use these 2 nodes
5187 if (proj == pn_be_Call_M_regular) {
5188 // get new node for result, are we doing the sse load/store hack?
5189 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5190 ir_node *call_res_new;
5191 ir_node *call_res_pred = NULL;
5193 if (call_res != NULL) {
5194 call_res_new = be_transform_node(call_res);
5195 call_res_pred = get_Proj_pred(call_res_new);
5198 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
5199 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5200 pn_be_Call_M_regular);
5202 assert(is_ia32_xLoad(call_res_pred));
5203 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5207 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5208 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5210 ir_node *frame = get_irg_frame(irg);
5211 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
5213 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5216 /* in case there is no memory output: create one to serialize the copy
5218 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5219 pn_be_Call_M_regular);
5220 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5221 pn_be_Call_first_res);
5223 /* store st(0) onto stack */
5224 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
5226 set_ia32_op_type(fstp, ia32_AddrModeD);
5227 set_ia32_use_frame(fstp);
5229 /* load into SSE register */
5230 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5232 set_ia32_op_type(sse_load, ia32_AddrModeS);
5233 set_ia32_use_frame(sse_load);
5235 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5241 /* transform call modes */
5242 if (mode_is_data(mode)) {
5243 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5247 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5251 * Transform the Projs from a Cmp.
5253 static ir_node *gen_Proj_Cmp(ir_node *node)
5255 /* this probably means not all mode_b nodes were lowered... */
5256 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5261 * Transform the Projs from a Bound.
5263 static ir_node *gen_Proj_Bound(ir_node *node)
5265 ir_node *new_node, *block;
5266 ir_node *pred = get_Proj_pred(node);
5268 switch (get_Proj_proj(node)) {
5270 return be_transform_node(get_Bound_mem(pred));
5271 case pn_Bound_X_regular:
5272 new_node = be_transform_node(pred);
5273 block = get_nodes_block(new_node);
5274 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
5275 case pn_Bound_X_except:
5276 new_node = be_transform_node(pred);
5277 block = get_nodes_block(new_node);
5278 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
5280 return be_transform_node(get_Bound_index(pred));
5282 panic("unsupported Proj from Bound");
5286 static ir_node *gen_Proj_ASM(ir_node *node)
5292 if (get_irn_mode(node) != mode_M)
5293 return be_duplicate_node(node);
5295 pred = get_Proj_pred(node);
5296 new_pred = be_transform_node(pred);
5297 block = get_nodes_block(new_pred);
5298 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
5299 get_ia32_n_res(new_pred) + 1);
5303 * Transform and potentially renumber Proj nodes.
5305 static ir_node *gen_Proj(ir_node *node) {
5306 ir_node *pred = get_Proj_pred(node);
5309 switch (get_irn_opcode(pred)) {
5311 proj = get_Proj_proj(node);
5312 if (proj == pn_Store_M) {
5313 return be_transform_node(pred);
5316 return new_r_Bad(current_ir_graph);
5319 return gen_Proj_Load(node);
5321 return gen_Proj_ASM(node);
5325 return gen_Proj_DivMod(node);
5327 return gen_Proj_CopyB(node);
5329 return gen_Proj_Quot(node);
5331 return gen_Proj_be_SubSP(node);
5333 return gen_Proj_be_AddSP(node);
5335 return gen_Proj_be_Call(node);
5337 return gen_Proj_Cmp(node);
5339 return gen_Proj_Bound(node);
5341 proj = get_Proj_proj(node);
5342 if (proj == pn_Start_X_initial_exec) {
5343 ir_node *block = get_nodes_block(pred);
5344 dbg_info *dbgi = get_irn_dbg_info(node);
5347 /* we exchange the ProjX with a jump */
5348 block = be_transform_node(block);
5349 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
5352 if (node == be_get_old_anchor(anchor_tls)) {
5353 return gen_Proj_tls(node);
5358 if (is_ia32_l_FloattoLL(pred)) {
5359 return gen_Proj_l_FloattoLL(node);
5361 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5365 ir_mode *mode = get_irn_mode(node);
5366 if (ia32_mode_needs_gp_reg(mode)) {
5367 ir_node *new_pred = be_transform_node(pred);
5368 ir_node *block = be_transform_node(get_nodes_block(node));
5369 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5370 mode_Iu, get_Proj_proj(node));
5371 #ifdef DEBUG_libfirm
5372 new_proj->node_nr = node->node_nr;
5378 return be_duplicate_node(node);
5382 * Enters all transform functions into the generic pointer
5384 static void register_transformers(void)
5388 /* first clear the generic function pointer for all ops */
5389 clear_irp_opcodes_generic_func();
5391 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5392 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5431 /* transform ops from intrinsic lowering */
5447 GEN(ia32_l_LLtoFloat);
5448 GEN(ia32_l_FloattoLL);
5454 /* we should never see these nodes */
5469 /* handle generic backend nodes */
5478 op_Mulh = get_op_Mulh();
5487 * Pre-transform all unknown and noreg nodes.
5489 static void ia32_pretransform_node(void *arch_cg) {
5490 ia32_code_gen_t *cg = arch_cg;
5492 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5493 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5494 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5495 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5496 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5497 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5502 * Walker, checks if all ia32 nodes producing more than one result have
5503 * its Projs, otherwise creates new Projs and keep them using a be_Keep node.
5505 static void add_missing_keep_walker(ir_node *node, void *data)
5508 unsigned found_projs = 0;
5509 const ir_edge_t *edge;
5510 ir_mode *mode = get_irn_mode(node);
5515 if(!is_ia32_irn(node))
5518 n_outs = get_ia32_n_res(node);
5521 if(is_ia32_SwitchJmp(node))
5524 assert(n_outs < (int) sizeof(unsigned) * 8);
5525 foreach_out_edge(node, edge) {
5526 ir_node *proj = get_edge_src_irn(edge);
5527 int pn = get_Proj_proj(proj);
5529 if (get_irn_mode(proj) == mode_M)
5532 assert(pn < n_outs);
5533 found_projs |= 1 << pn;
5537 /* are keeps missing? */
5539 for(i = 0; i < n_outs; ++i) {
5542 const arch_register_req_t *req;
5543 const arch_register_class_t *cls;
5545 if(found_projs & (1 << i)) {
5549 req = get_ia32_out_req(node, i);
5554 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
5558 block = get_nodes_block(node);
5559 in[0] = new_r_Proj(current_ir_graph, block, node,
5560 arch_register_class_mode(cls), i);
5561 if(last_keep != NULL) {
5562 be_Keep_add_node(last_keep, cls, in[0]);
5564 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
5565 if(sched_is_scheduled(node)) {
5566 sched_add_after(node, last_keep);
5573 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5576 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5578 ir_graph *irg = be_get_birg_irg(cg->birg);
5579 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5582 /* do the transformation */
5583 void ia32_transform_graph(ia32_code_gen_t *cg) {
5585 ir_graph *irg = cg->irg;
5587 register_transformers();
5589 initial_fpcw = NULL;
5591 BE_TIMER_PUSH(t_heights);
5592 heights = heights_new(irg);
5593 BE_TIMER_POP(t_heights);
5594 ia32_calculate_non_address_mode_nodes(cg->birg);
5596 /* the transform phase is not safe for CSE (yet) because several nodes get
5597 * attributes set after their creation */
5598 cse_last = get_opt_cse();
5601 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5603 set_opt_cse(cse_last);
5605 ia32_free_non_address_mode_nodes();
5606 heights_free(heights);
5610 void ia32_init_transform(void)
5612 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");