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 op2 = get_Conv_op(op2);
1103 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1105 new_op2 = create_immediate_or_transform(op2, 0);
1107 dbgi = get_irn_dbg_info(node);
1108 block = get_nodes_block(node);
1109 new_block = be_transform_node(block);
1110 new_node = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1111 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1113 /* lowered shift instruction may have a dependency operand, handle it here */
1114 if (get_irn_arity(node) == 3) {
1115 /* we have a dependency */
1116 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1117 add_irn_dep(new_node, new_dep);
1125 * Construct a standard unary operation, set AM and immediate if required.
1127 * @param op The operand
1128 * @param func The node constructor function
1129 * @return The constructed ia32 node.
1131 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1132 match_flags_t flags)
1135 ir_node *block, *new_block, *new_op, *new_node;
1137 assert(flags == 0 || flags == match_mode_neutral);
1138 if (flags & match_mode_neutral) {
1139 op = ia32_skip_downconv(op);
1142 new_op = be_transform_node(op);
1143 dbgi = get_irn_dbg_info(node);
1144 block = get_nodes_block(node);
1145 new_block = be_transform_node(block);
1146 new_node = func(dbgi, current_ir_graph, new_block, new_op);
1148 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1153 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1154 ia32_address_t *addr)
1156 ir_node *base, *index, *res;
1160 base = ia32_new_NoReg_gp(env_cg);
1162 base = be_transform_node(base);
1165 index = addr->index;
1166 if (index == NULL) {
1167 index = ia32_new_NoReg_gp(env_cg);
1169 index = be_transform_node(index);
1172 res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1173 set_address(res, addr);
1179 * Returns non-zero if a given address mode has a symbolic or
1180 * numerical offset != 0.
1182 static int am_has_immediates(const ia32_address_t *addr)
1184 return addr->offset != 0 || addr->symconst_ent != NULL
1185 || addr->frame_entity || addr->use_frame;
1189 * Creates an ia32 Add.
1191 * @return the created ia32 Add node
1193 static ir_node *gen_Add(ir_node *node) {
1194 ir_mode *mode = get_irn_mode(node);
1195 ir_node *op1 = get_Add_left(node);
1196 ir_node *op2 = get_Add_right(node);
1198 ir_node *block, *new_block, *new_node, *add_immediate_op;
1199 ia32_address_t addr;
1200 ia32_address_mode_t am;
1202 if (mode_is_float(mode)) {
1203 if (ia32_cg_config.use_sse2)
1204 return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1205 match_commutative | match_am);
1207 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1208 match_commutative | match_am);
1211 ia32_mark_non_am(node);
1213 op2 = ia32_skip_downconv(op2);
1214 op1 = ia32_skip_downconv(op1);
1218 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1219 * 1. Add with immediate -> Lea
1220 * 2. Add with possible source address mode -> Add
1221 * 3. Otherwise -> Lea
1223 memset(&addr, 0, sizeof(addr));
1224 ia32_create_address_mode(&addr, node, /*force=*/1);
1225 add_immediate_op = NULL;
1227 dbgi = get_irn_dbg_info(node);
1228 block = get_nodes_block(node);
1229 new_block = be_transform_node(block);
1232 if(addr.base == NULL && addr.index == NULL) {
1233 ir_graph *irg = current_ir_graph;
1234 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1235 addr.symconst_sign, addr.offset);
1236 add_irn_dep(new_node, get_irg_frame(irg));
1237 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1240 /* add with immediate? */
1241 if(addr.index == NULL) {
1242 add_immediate_op = addr.base;
1243 } else if(addr.base == NULL && addr.scale == 0) {
1244 add_immediate_op = addr.index;
1247 if(add_immediate_op != NULL) {
1248 if(!am_has_immediates(&addr)) {
1249 #ifdef DEBUG_libfirm
1250 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1253 return be_transform_node(add_immediate_op);
1256 new_node = create_lea_from_address(dbgi, new_block, &addr);
1257 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1261 /* test if we can use source address mode */
1262 match_arguments(&am, block, op1, op2, NULL, match_commutative
1263 | match_mode_neutral | match_am | match_immediate | match_try_am);
1265 /* construct an Add with source address mode */
1266 if (am.op_type == ia32_AddrModeS) {
1267 ir_graph *irg = current_ir_graph;
1268 ia32_address_t *am_addr = &am.addr;
1269 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1270 am_addr->index, am_addr->mem, am.new_op1,
1272 set_am_attributes(new_node, &am);
1273 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1275 new_node = fix_mem_proj(new_node, &am);
1280 /* otherwise construct a lea */
1281 new_node = create_lea_from_address(dbgi, new_block, &addr);
1282 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1287 * Creates an ia32 Mul.
1289 * @return the created ia32 Mul node
1291 static ir_node *gen_Mul(ir_node *node) {
1292 ir_node *op1 = get_Mul_left(node);
1293 ir_node *op2 = get_Mul_right(node);
1294 ir_mode *mode = get_irn_mode(node);
1296 if (mode_is_float(mode)) {
1297 if (ia32_cg_config.use_sse2)
1298 return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1299 match_commutative | match_am);
1301 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1302 match_commutative | match_am);
1304 return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1305 match_commutative | match_am | match_mode_neutral |
1306 match_immediate | match_am_and_immediates);
1310 * Creates an ia32 Mulh.
1311 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1312 * this result while Mul returns the lower 32 bit.
1314 * @return the created ia32 Mulh node
1316 static ir_node *gen_Mulh(ir_node *node)
1318 ir_node *block = get_nodes_block(node);
1319 ir_node *new_block = be_transform_node(block);
1320 ir_graph *irg = current_ir_graph;
1321 dbg_info *dbgi = get_irn_dbg_info(node);
1322 ir_mode *mode = get_irn_mode(node);
1323 ir_node *op1 = get_Mulh_left(node);
1324 ir_node *op2 = get_Mulh_right(node);
1325 ir_node *proj_res_high;
1327 ia32_address_mode_t am;
1328 ia32_address_t *addr = &am.addr;
1330 assert(!mode_is_float(mode) && "Mulh with float not supported");
1331 assert(get_mode_size_bits(mode) == 32);
1333 match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1335 if (mode_is_signed(mode)) {
1336 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1337 addr->index, addr->mem, am.new_op1,
1340 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1341 addr->index, addr->mem, am.new_op1,
1345 set_am_attributes(new_node, &am);
1346 /* we can't use source address mode anymore when using immediates */
1347 if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1348 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1349 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1351 assert(get_irn_mode(new_node) == mode_T);
1353 fix_mem_proj(new_node, &am);
1355 assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1356 proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1357 mode_Iu, pn_ia32_IMul1OP_res_high);
1359 return proj_res_high;
1365 * Creates an ia32 And.
1367 * @return The created ia32 And node
1369 static ir_node *gen_And(ir_node *node) {
1370 ir_node *op1 = get_And_left(node);
1371 ir_node *op2 = get_And_right(node);
1372 assert(! mode_is_float(get_irn_mode(node)));
1374 /* is it a zero extension? */
1375 if (is_Const(op2)) {
1376 tarval *tv = get_Const_tarval(op2);
1377 long v = get_tarval_long(tv);
1379 if (v == 0xFF || v == 0xFFFF) {
1380 dbg_info *dbgi = get_irn_dbg_info(node);
1381 ir_node *block = get_nodes_block(node);
1388 assert(v == 0xFFFF);
1391 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1396 return gen_binop(node, op1, op2, new_rd_ia32_And,
1397 match_commutative | match_mode_neutral | match_am
1404 * Creates an ia32 Or.
1406 * @return The created ia32 Or node
1408 static ir_node *gen_Or(ir_node *node) {
1409 ir_node *op1 = get_Or_left(node);
1410 ir_node *op2 = get_Or_right(node);
1412 assert (! mode_is_float(get_irn_mode(node)));
1413 return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1414 | match_mode_neutral | match_am | match_immediate);
1420 * Creates an ia32 Eor.
1422 * @return The created ia32 Eor node
1424 static ir_node *gen_Eor(ir_node *node) {
1425 ir_node *op1 = get_Eor_left(node);
1426 ir_node *op2 = get_Eor_right(node);
1428 assert(! mode_is_float(get_irn_mode(node)));
1429 return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1430 | match_mode_neutral | match_am | match_immediate);
1435 * Creates an ia32 Sub.
1437 * @return The created ia32 Sub node
1439 static ir_node *gen_Sub(ir_node *node) {
1440 ir_node *op1 = get_Sub_left(node);
1441 ir_node *op2 = get_Sub_right(node);
1442 ir_mode *mode = get_irn_mode(node);
1444 if (mode_is_float(mode)) {
1445 if (ia32_cg_config.use_sse2)
1446 return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1448 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1452 if (is_Const(op2)) {
1453 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1457 return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1458 | match_am | match_immediate);
1462 * Generates an ia32 DivMod with additional infrastructure for the
1463 * register allocator if needed.
1465 static ir_node *create_Div(ir_node *node)
1467 ir_graph *irg = current_ir_graph;
1468 dbg_info *dbgi = get_irn_dbg_info(node);
1469 ir_node *block = get_nodes_block(node);
1470 ir_node *new_block = be_transform_node(block);
1477 ir_node *sign_extension;
1478 ia32_address_mode_t am;
1479 ia32_address_t *addr = &am.addr;
1481 /* the upper bits have random contents for smaller modes */
1482 switch (get_irn_opcode(node)) {
1484 op1 = get_Div_left(node);
1485 op2 = get_Div_right(node);
1486 mem = get_Div_mem(node);
1487 mode = get_Div_resmode(node);
1490 op1 = get_Mod_left(node);
1491 op2 = get_Mod_right(node);
1492 mem = get_Mod_mem(node);
1493 mode = get_Mod_resmode(node);
1496 op1 = get_DivMod_left(node);
1497 op2 = get_DivMod_right(node);
1498 mem = get_DivMod_mem(node);
1499 mode = get_DivMod_resmode(node);
1502 panic("invalid divmod node %+F", node);
1505 match_arguments(&am, block, op1, op2, NULL, match_am);
1507 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1508 is the memory of the consumed address. We can have only the second op as address
1509 in Div nodes, so check only op2. */
1510 if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1511 new_mem = be_transform_node(mem);
1512 if(!is_NoMem(addr->mem)) {
1516 new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1519 new_mem = addr->mem;
1522 if (mode_is_signed(mode)) {
1523 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1524 add_irn_dep(produceval, get_irg_frame(irg));
1525 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1528 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1529 addr->index, new_mem, am.new_op2,
1530 am.new_op1, sign_extension);
1532 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1533 add_irn_dep(sign_extension, get_irg_frame(irg));
1535 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1536 addr->index, new_mem, am.new_op2,
1537 am.new_op1, sign_extension);
1540 set_irn_pinned(new_node, get_irn_pinned(node));
1542 set_am_attributes(new_node, &am);
1543 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1545 new_node = fix_mem_proj(new_node, &am);
1551 static ir_node *gen_Mod(ir_node *node) {
1552 return create_Div(node);
1555 static ir_node *gen_Div(ir_node *node) {
1556 return create_Div(node);
1559 static ir_node *gen_DivMod(ir_node *node) {
1560 return create_Div(node);
1566 * Creates an ia32 floating Div.
1568 * @return The created ia32 xDiv node
1570 static ir_node *gen_Quot(ir_node *node)
1572 ir_node *op1 = get_Quot_left(node);
1573 ir_node *op2 = get_Quot_right(node);
1575 if (ia32_cg_config.use_sse2) {
1576 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1578 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1584 * Creates an ia32 Shl.
1586 * @return The created ia32 Shl node
1588 static ir_node *gen_Shl(ir_node *node) {
1589 ir_node *left = get_Shl_left(node);
1590 ir_node *right = get_Shl_right(node);
1592 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1593 match_mode_neutral | match_immediate);
1597 * Creates an ia32 Shr.
1599 * @return The created ia32 Shr node
1601 static ir_node *gen_Shr(ir_node *node) {
1602 ir_node *left = get_Shr_left(node);
1603 ir_node *right = get_Shr_right(node);
1605 return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1611 * Creates an ia32 Sar.
1613 * @return The created ia32 Shrs node
1615 static ir_node *gen_Shrs(ir_node *node) {
1616 ir_node *left = get_Shrs_left(node);
1617 ir_node *right = get_Shrs_right(node);
1618 ir_mode *mode = get_irn_mode(node);
1620 if(is_Const(right) && mode == mode_Is) {
1621 tarval *tv = get_Const_tarval(right);
1622 long val = get_tarval_long(tv);
1624 /* this is a sign extension */
1625 ir_graph *irg = current_ir_graph;
1626 dbg_info *dbgi = get_irn_dbg_info(node);
1627 ir_node *block = be_transform_node(get_nodes_block(node));
1629 ir_node *new_op = be_transform_node(op);
1630 ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block);
1631 add_irn_dep(pval, get_irg_frame(irg));
1633 return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1637 /* 8 or 16 bit sign extension? */
1638 if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1639 ir_node *shl_left = get_Shl_left(left);
1640 ir_node *shl_right = get_Shl_right(left);
1641 if(is_Const(shl_right)) {
1642 tarval *tv1 = get_Const_tarval(right);
1643 tarval *tv2 = get_Const_tarval(shl_right);
1644 if(tv1 == tv2 && tarval_is_long(tv1)) {
1645 long val = get_tarval_long(tv1);
1646 if(val == 16 || val == 24) {
1647 dbg_info *dbgi = get_irn_dbg_info(node);
1648 ir_node *block = get_nodes_block(node);
1658 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1667 return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1673 * Creates an ia32 Rol.
1675 * @param op1 The first operator
1676 * @param op2 The second operator
1677 * @return The created ia32 RotL node
1679 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1680 return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1686 * Creates an ia32 Ror.
1687 * NOTE: There is no RotR with immediate because this would always be a RotL
1688 * "imm-mode_size_bits" which can be pre-calculated.
1690 * @param op1 The first operator
1691 * @param op2 The second operator
1692 * @return The created ia32 RotR node
1694 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1695 return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1701 * Creates an ia32 RotR or RotL (depending on the found pattern).
1703 * @return The created ia32 RotL or RotR node
1705 static ir_node *gen_Rotl(ir_node *node) {
1706 ir_node *rotate = NULL;
1707 ir_node *op1 = get_Rotl_left(node);
1708 ir_node *op2 = get_Rotl_right(node);
1710 /* Firm has only RotL, so we are looking for a right (op2)
1711 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1712 that means we can create a RotR instead of an Add and a RotL */
1716 ir_node *left = get_Add_left(add);
1717 ir_node *right = get_Add_right(add);
1718 if (is_Const(right)) {
1719 tarval *tv = get_Const_tarval(right);
1720 ir_mode *mode = get_irn_mode(node);
1721 long bits = get_mode_size_bits(mode);
1723 if (is_Minus(left) &&
1724 tarval_is_long(tv) &&
1725 get_tarval_long(tv) == bits &&
1728 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1729 rotate = gen_Ror(node, op1, get_Minus_op(left));
1734 if (rotate == NULL) {
1735 rotate = gen_Rol(node, op1, op2);
1744 * Transforms a Minus node.
1746 * @return The created ia32 Minus node
1748 static ir_node *gen_Minus(ir_node *node)
1750 ir_node *op = get_Minus_op(node);
1751 ir_node *block = be_transform_node(get_nodes_block(node));
1752 ir_graph *irg = current_ir_graph;
1753 dbg_info *dbgi = get_irn_dbg_info(node);
1754 ir_mode *mode = get_irn_mode(node);
1759 if (mode_is_float(mode)) {
1760 ir_node *new_op = be_transform_node(op);
1761 if (ia32_cg_config.use_sse2) {
1762 /* TODO: non-optimal... if we have many xXors, then we should
1763 * rather create a load for the const and use that instead of
1764 * several AM nodes... */
1765 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1766 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1767 ir_node *nomem = new_rd_NoMem(irg);
1769 new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1770 nomem, new_op, noreg_xmm);
1772 size = get_mode_size_bits(mode);
1773 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1775 set_ia32_am_sc(new_node, ent);
1776 set_ia32_op_type(new_node, ia32_AddrModeS);
1777 set_ia32_ls_mode(new_node, mode);
1779 new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1782 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1785 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1791 * Transforms a Not node.
1793 * @return The created ia32 Not node
1795 static ir_node *gen_Not(ir_node *node) {
1796 ir_node *op = get_Not_op(node);
1798 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1799 assert (! mode_is_float(get_irn_mode(node)));
1801 return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1807 * Transforms an Abs node.
1809 * @return The created ia32 Abs node
1811 static ir_node *gen_Abs(ir_node *node)
1813 ir_node *block = get_nodes_block(node);
1814 ir_node *new_block = be_transform_node(block);
1815 ir_node *op = get_Abs_op(node);
1816 ir_graph *irg = current_ir_graph;
1817 dbg_info *dbgi = get_irn_dbg_info(node);
1818 ir_mode *mode = get_irn_mode(node);
1819 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1820 ir_node *nomem = new_NoMem();
1826 if (mode_is_float(mode)) {
1827 new_op = be_transform_node(op);
1829 if (ia32_cg_config.use_sse2) {
1830 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1831 new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1832 nomem, new_op, noreg_fp);
1834 size = get_mode_size_bits(mode);
1835 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1837 set_ia32_am_sc(new_node, ent);
1839 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1841 set_ia32_op_type(new_node, ia32_AddrModeS);
1842 set_ia32_ls_mode(new_node, mode);
1844 new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1845 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1848 ir_node *xor, *pval, *sign_extension;
1850 if (get_mode_size_bits(mode) == 32) {
1851 new_op = be_transform_node(op);
1853 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1856 pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1857 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1860 add_irn_dep(pval, get_irg_frame(irg));
1861 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1863 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1864 nomem, new_op, sign_extension);
1865 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1867 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1868 nomem, xor, sign_extension);
1869 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1876 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1878 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1879 dbg_info *dbgi = get_irn_dbg_info(cmp);
1880 ir_node *block = get_nodes_block(cmp);
1881 ir_node *new_block = be_transform_node(block);
1882 ir_node *op1 = be_transform_node(x);
1883 ir_node *op2 = be_transform_node(n);
1885 return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1889 * Transform a node returning a "flag" result.
1891 * @param node the node to transform
1892 * @param pnc_out the compare mode to use
1894 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1903 /* we have a Cmp as input */
1904 if (is_Proj(node)) {
1905 ir_node *pred = get_Proj_pred(node);
1907 pn_Cmp pnc = get_Proj_proj(node);
1908 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1909 ir_node *l = get_Cmp_left(pred);
1910 ir_node *r = get_Cmp_right(pred);
1912 ir_node *la = get_And_left(l);
1913 ir_node *ra = get_And_right(l);
1915 ir_node *c = get_Shl_left(la);
1916 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1917 /* (1 << n) & ra) */
1918 ir_node *n = get_Shl_right(la);
1919 flags = gen_bt(pred, ra, n);
1920 /* we must generate a Jc/Jnc jump */
1921 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1924 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1929 ir_node *c = get_Shl_left(ra);
1930 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1931 /* la & (1 << n)) */
1932 ir_node *n = get_Shl_right(ra);
1933 flags = gen_bt(pred, la, n);
1934 /* we must generate a Jc/Jnc jump */
1935 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1938 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1944 flags = be_transform_node(pred);
1950 /* a mode_b value, we have to compare it against 0 */
1951 dbgi = get_irn_dbg_info(node);
1952 new_block = be_transform_node(get_nodes_block(node));
1953 new_op = be_transform_node(node);
1954 noreg = ia32_new_NoReg_gp(env_cg);
1955 nomem = new_NoMem();
1956 flags = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1957 new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1958 *pnc_out = pn_Cmp_Lg;
1963 * Transforms a Load.
1965 * @return the created ia32 Load node
1967 static ir_node *gen_Load(ir_node *node) {
1968 ir_node *old_block = get_nodes_block(node);
1969 ir_node *block = be_transform_node(old_block);
1970 ir_node *ptr = get_Load_ptr(node);
1971 ir_node *mem = get_Load_mem(node);
1972 ir_node *new_mem = be_transform_node(mem);
1975 ir_graph *irg = current_ir_graph;
1976 dbg_info *dbgi = get_irn_dbg_info(node);
1977 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1978 ir_mode *mode = get_Load_mode(node);
1981 ia32_address_t addr;
1983 /* construct load address */
1984 memset(&addr, 0, sizeof(addr));
1985 ia32_create_address_mode(&addr, ptr, /*force=*/0);
1992 base = be_transform_node(base);
1998 index = be_transform_node(index);
2001 if (mode_is_float(mode)) {
2002 if (ia32_cg_config.use_sse2) {
2003 new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
2005 res_mode = mode_xmm;
2007 new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
2009 res_mode = mode_vfp;
2012 assert(mode != mode_b);
2014 /* create a conv node with address mode for smaller modes */
2015 if(get_mode_size_bits(mode) < 32) {
2016 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
2017 new_mem, noreg, mode);
2019 new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
2024 set_irn_pinned(new_node, get_irn_pinned(node));
2025 set_ia32_op_type(new_node, ia32_AddrModeS);
2026 set_ia32_ls_mode(new_node, mode);
2027 set_address(new_node, &addr);
2029 if(get_irn_pinned(node) == op_pin_state_floats) {
2030 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
2033 /* make sure we are scheduled behind the initial IncSP/Barrier
2034 * to avoid spills being placed before it
2036 if (block == get_irg_start_block(irg)) {
2037 add_irn_dep(new_node, get_irg_frame(irg));
2040 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2045 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2046 ir_node *ptr, ir_node *other)
2053 /* we only use address mode if we're the only user of the load */
2054 if(get_irn_n_edges(node) > 1)
2057 load = get_Proj_pred(node);
2060 if(get_nodes_block(load) != block)
2063 /* Store should be attached to the load */
2064 if(!is_Proj(mem) || get_Proj_pred(mem) != load)
2066 /* store should have the same pointer as the load */
2067 if(get_Load_ptr(load) != ptr)
2070 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2071 if(other != NULL && get_nodes_block(other) == block
2072 && heights_reachable_in_block(heights, other, load))
2078 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
2080 mark_irn_visited(old_node);
2081 be_set_transformed_node(old_node, new_node);
2084 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2085 ir_node *mem, ir_node *ptr, ir_mode *mode,
2086 construct_binop_dest_func *func,
2087 construct_binop_dest_func *func8bit,
2088 match_flags_t flags)
2090 ir_node *src_block = get_nodes_block(node);
2092 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2093 ir_graph *irg = current_ir_graph;
2099 ia32_address_mode_t am;
2100 ia32_address_t *addr = &am.addr;
2101 memset(&am, 0, sizeof(am));
2103 assert(flags & match_dest_am);
2104 assert(flags & match_immediate); /* there is no destam node without... */
2105 commutative = (flags & match_commutative) != 0;
2107 if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2108 build_address(&am, op1);
2109 new_op = create_immediate_or_transform(op2, 0);
2110 } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2111 build_address(&am, op2);
2112 new_op = create_immediate_or_transform(op1, 0);
2117 if(addr->base == NULL)
2118 addr->base = noreg_gp;
2119 if(addr->index == NULL)
2120 addr->index = noreg_gp;
2121 if(addr->mem == NULL)
2122 addr->mem = new_NoMem();
2124 dbgi = get_irn_dbg_info(node);
2125 block = be_transform_node(src_block);
2126 if(get_mode_size_bits(mode) == 8) {
2127 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2130 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
2133 set_address(new_node, addr);
2134 set_ia32_op_type(new_node, ia32_AddrModeD);
2135 set_ia32_ls_mode(new_node, mode);
2136 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2138 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2139 mem_proj = be_transform_node(am.mem_proj);
2140 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2145 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2146 ir_node *ptr, ir_mode *mode,
2147 construct_unop_dest_func *func)
2149 ir_graph *irg = current_ir_graph;
2150 ir_node *src_block = get_nodes_block(node);
2155 ia32_address_mode_t am;
2156 ia32_address_t *addr = &am.addr;
2157 memset(&am, 0, sizeof(am));
2159 if(!use_dest_am(src_block, op, mem, ptr, NULL))
2162 build_address(&am, op);
2164 dbgi = get_irn_dbg_info(node);
2165 block = be_transform_node(src_block);
2166 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2167 set_address(new_node, addr);
2168 set_ia32_op_type(new_node, ia32_AddrModeD);
2169 set_ia32_ls_mode(new_node, mode);
2170 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2172 set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2173 mem_proj = be_transform_node(am.mem_proj);
2174 set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2179 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2180 ir_mode *mode = get_irn_mode(node);
2181 ir_node *psi_true = get_Psi_val(node, 0);
2182 ir_node *psi_default = get_Psi_default(node);
2193 ia32_address_t addr;
2195 if(get_mode_size_bits(mode) != 8)
2198 if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2200 } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2206 build_address_ptr(&addr, ptr, mem);
2208 irg = current_ir_graph;
2209 dbgi = get_irn_dbg_info(node);
2210 block = get_nodes_block(node);
2211 new_block = be_transform_node(block);
2212 cond = get_Psi_cond(node, 0);
2213 flags = get_flags_node(cond, &pnc);
2214 new_mem = be_transform_node(mem);
2215 new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2216 addr.index, addr.mem, flags, pnc, negated);
2217 set_address(new_node, &addr);
2218 set_ia32_op_type(new_node, ia32_AddrModeD);
2219 set_ia32_ls_mode(new_node, mode);
2220 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2225 static ir_node *try_create_dest_am(ir_node *node) {
2226 ir_node *val = get_Store_value(node);
2227 ir_node *mem = get_Store_mem(node);
2228 ir_node *ptr = get_Store_ptr(node);
2229 ir_mode *mode = get_irn_mode(val);
2230 unsigned bits = get_mode_size_bits(mode);
2235 /* handle only GP modes for now... */
2236 if(!ia32_mode_needs_gp_reg(mode))
2240 /* store must be the only user of the val node */
2241 if(get_irn_n_edges(val) > 1)
2243 /* skip pointless convs */
2245 ir_node *conv_op = get_Conv_op(val);
2246 ir_mode *pred_mode = get_irn_mode(conv_op);
2247 if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2255 /* value must be in the same block */
2256 if(get_nodes_block(node) != get_nodes_block(val))
2259 switch (get_irn_opcode(val)) {
2261 op1 = get_Add_left(val);
2262 op2 = get_Add_right(val);
2263 if(is_Const_1(op2)) {
2264 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2265 new_rd_ia32_IncMem);
2267 } else if(is_Const_Minus_1(op2)) {
2268 new_node = dest_am_unop(val, op1, mem, ptr, mode,
2269 new_rd_ia32_DecMem);
2272 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2273 new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2274 match_dest_am | match_commutative |
2278 op1 = get_Sub_left(val);
2279 op2 = get_Sub_right(val);
2281 ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2284 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2285 new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2286 match_dest_am | match_immediate |
2290 op1 = get_And_left(val);
2291 op2 = get_And_right(val);
2292 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2293 new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2294 match_dest_am | match_commutative |
2298 op1 = get_Or_left(val);
2299 op2 = get_Or_right(val);
2300 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2301 new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2302 match_dest_am | match_commutative |
2306 op1 = get_Eor_left(val);
2307 op2 = get_Eor_right(val);
2308 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2309 new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2310 match_dest_am | match_commutative |
2314 op1 = get_Shl_left(val);
2315 op2 = get_Shl_right(val);
2316 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2317 new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2318 match_dest_am | match_immediate);
2321 op1 = get_Shr_left(val);
2322 op2 = get_Shr_right(val);
2323 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2324 new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2325 match_dest_am | match_immediate);
2328 op1 = get_Shrs_left(val);
2329 op2 = get_Shrs_right(val);
2330 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2331 new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2332 match_dest_am | match_immediate);
2335 op1 = get_Rotl_left(val);
2336 op2 = get_Rotl_right(val);
2337 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2338 new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2339 match_dest_am | match_immediate);
2341 /* TODO: match ROR patterns... */
2343 new_node = try_create_SetMem(val, ptr, mem);
2346 op1 = get_Minus_op(val);
2347 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2350 /* should be lowered already */
2351 assert(mode != mode_b);
2352 op1 = get_Not_op(val);
2353 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2359 if(new_node != NULL) {
2360 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2361 get_irn_pinned(node) == op_pin_state_pinned) {
2362 set_irn_pinned(new_node, op_pin_state_pinned);
2369 static int is_float_to_int32_conv(const ir_node *node)
2371 ir_mode *mode = get_irn_mode(node);
2375 if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode))
2377 /* don't report unsigned as conv to 32bit, because we really need to do
2378 * a vfist with 64bit signed in this case */
2379 if(!mode_is_signed(mode))
2384 conv_op = get_Conv_op(node);
2385 conv_mode = get_irn_mode(conv_op);
2387 if(!mode_is_float(conv_mode))
2394 * Transform a Store(floatConst).
2396 * @return the created ia32 Store node
2398 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2399 ir_mode *mode = get_irn_mode(cns);
2400 int size = get_mode_size_bits(mode);
2401 tarval *tv = get_Const_tarval(cns);
2402 ir_node *block = get_nodes_block(node);
2403 ir_node *new_block = be_transform_node(block);
2404 ir_node *ptr = get_Store_ptr(node);
2405 ir_node *mem = get_Store_mem(node);
2406 ir_graph *irg = current_ir_graph;
2407 dbg_info *dbgi = get_irn_dbg_info(node);
2408 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2411 ia32_address_t addr;
2413 unsigned val = get_tarval_sub_bits(tv, 0) |
2414 (get_tarval_sub_bits(tv, 1) << 8) |
2415 (get_tarval_sub_bits(tv, 2) << 16) |
2416 (get_tarval_sub_bits(tv, 3) << 24);
2417 ir_node *imm = create_Immediate(NULL, 0, val);
2419 /* construct store address */
2420 memset(&addr, 0, sizeof(addr));
2421 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2423 if (addr.base == NULL) {
2426 addr.base = be_transform_node(addr.base);
2429 if (addr.index == NULL) {
2432 addr.index = be_transform_node(addr.index);
2434 addr.mem = be_transform_node(mem);
2436 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2437 addr.index, addr.mem, imm);
2439 set_irn_pinned(new_node, get_irn_pinned(node));
2440 set_ia32_op_type(new_node, ia32_AddrModeD);
2441 set_ia32_ls_mode(new_node, mode_Iu);
2443 set_address(new_node, &addr);
2445 /** add more stores if needed */
2447 unsigned val = get_tarval_sub_bits(tv, ofs) |
2448 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2449 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2450 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2451 ir_node *imm = create_Immediate(NULL, 0, val);
2454 addr.mem = new_node;
2456 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2457 addr.index, addr.mem, imm);
2459 set_irn_pinned(new_node, get_irn_pinned(node));
2460 set_ia32_op_type(new_node, ia32_AddrModeD);
2461 set_ia32_ls_mode(new_node, mode_Iu);
2463 set_address(new_node, &addr);
2468 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2473 * Generate a vfist or vfisttp instruction.
2475 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2476 ir_node *mem, ir_node *val, ir_node **fist)
2480 if (ia32_cg_config.use_fisttp) {
2481 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2482 if other users exists */
2483 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2484 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2485 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2486 be_new_Keep(reg_class, irg, block, 1, &value);
2488 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2491 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2494 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2500 * Transforms a normal Store.
2502 * @return the created ia32 Store node
2504 static ir_node *gen_normal_Store(ir_node *node)
2506 ir_node *val = get_Store_value(node);
2507 ir_mode *mode = get_irn_mode(val);
2508 ir_node *block = get_nodes_block(node);
2509 ir_node *new_block = be_transform_node(block);
2510 ir_node *ptr = get_Store_ptr(node);
2511 ir_node *mem = get_Store_mem(node);
2512 ir_graph *irg = current_ir_graph;
2513 dbg_info *dbgi = get_irn_dbg_info(node);
2514 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2515 ir_node *new_val, *new_node, *store;
2516 ia32_address_t addr;
2518 /* check for destination address mode */
2519 new_node = try_create_dest_am(node);
2520 if (new_node != NULL)
2523 /* construct store address */
2524 memset(&addr, 0, sizeof(addr));
2525 ia32_create_address_mode(&addr, ptr, /*force=*/0);
2527 if (addr.base == NULL) {
2530 addr.base = be_transform_node(addr.base);
2533 if (addr.index == NULL) {
2536 addr.index = be_transform_node(addr.index);
2538 addr.mem = be_transform_node(mem);
2540 if (mode_is_float(mode)) {
2541 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2543 while (is_Conv(val) && mode == get_irn_mode(val)) {
2544 ir_node *op = get_Conv_op(val);
2545 if (!mode_is_float(get_irn_mode(op)))
2549 new_val = be_transform_node(val);
2550 if (ia32_cg_config.use_sse2) {
2551 new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2552 addr.index, addr.mem, new_val);
2554 new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2555 addr.index, addr.mem, new_val, mode);
2558 } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2559 val = get_Conv_op(val);
2561 /* We can skip ALL Convs (and strict-Convs) before stores. */
2562 while (is_Conv(val)) {
2563 val = get_Conv_op(val);
2565 new_val = be_transform_node(val);
2566 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2568 new_val = create_immediate_or_transform(val, 0);
2569 assert(mode != mode_b);
2571 if (get_mode_size_bits(mode) == 8) {
2572 new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2573 addr.index, addr.mem, new_val);
2575 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2576 addr.index, addr.mem, new_val);
2581 set_irn_pinned(store, get_irn_pinned(node));
2582 set_ia32_op_type(store, ia32_AddrModeD);
2583 set_ia32_ls_mode(store, mode);
2585 set_address(store, &addr);
2586 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2592 * Transforms a Store.
2594 * @return the created ia32 Store node
2596 static ir_node *gen_Store(ir_node *node)
2598 ir_node *val = get_Store_value(node);
2599 ir_mode *mode = get_irn_mode(val);
2601 if (mode_is_float(mode) && is_Const(val)) {
2604 /* we are storing a floating point constant */
2605 if (ia32_cg_config.use_sse2) {
2606 transform = !is_simple_sse_Const(val);
2608 transform = !is_simple_x87_Const(val);
2611 return gen_float_const_Store(node, val);
2613 return gen_normal_Store(node);
2617 * Transforms a Switch.
2619 * @return the created ia32 SwitchJmp node
2621 static ir_node *create_Switch(ir_node *node)
2623 ir_graph *irg = current_ir_graph;
2624 dbg_info *dbgi = get_irn_dbg_info(node);
2625 ir_node *block = be_transform_node(get_nodes_block(node));
2626 ir_node *sel = get_Cond_selector(node);
2627 ir_node *new_sel = be_transform_node(sel);
2628 int switch_min = INT_MAX;
2629 int switch_max = INT_MIN;
2630 long default_pn = get_Cond_defaultProj(node);
2632 const ir_edge_t *edge;
2634 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2636 /* determine the smallest switch case value */
2637 foreach_out_edge(node, edge) {
2638 ir_node *proj = get_edge_src_irn(edge);
2639 long pn = get_Proj_proj(proj);
2640 if(pn == default_pn)
2649 if((unsigned) (switch_max - switch_min) > 256000) {
2650 panic("Size of switch %+F bigger than 256000", node);
2653 if (switch_min != 0) {
2654 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2656 /* if smallest switch case is not 0 we need an additional sub */
2657 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2658 add_ia32_am_offs_int(new_sel, -switch_min);
2659 set_ia32_op_type(new_sel, ia32_AddrModeS);
2661 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2664 new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2665 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2671 * Transform a Cond node.
2673 static ir_node *gen_Cond(ir_node *node) {
2674 ir_node *block = get_nodes_block(node);
2675 ir_node *new_block = be_transform_node(block);
2676 ir_graph *irg = current_ir_graph;
2677 dbg_info *dbgi = get_irn_dbg_info(node);
2678 ir_node *sel = get_Cond_selector(node);
2679 ir_mode *sel_mode = get_irn_mode(sel);
2680 ir_node *flags = NULL;
2684 if (sel_mode != mode_b) {
2685 return create_Switch(node);
2688 /* we get flags from a Cmp */
2689 flags = get_flags_node(sel, &pnc);
2691 new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2692 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2698 * Transforms a CopyB node.
2700 * @return The transformed node.
2702 static ir_node *gen_CopyB(ir_node *node) {
2703 ir_node *block = be_transform_node(get_nodes_block(node));
2704 ir_node *src = get_CopyB_src(node);
2705 ir_node *new_src = be_transform_node(src);
2706 ir_node *dst = get_CopyB_dst(node);
2707 ir_node *new_dst = be_transform_node(dst);
2708 ir_node *mem = get_CopyB_mem(node);
2709 ir_node *new_mem = be_transform_node(mem);
2710 ir_node *res = NULL;
2711 ir_graph *irg = current_ir_graph;
2712 dbg_info *dbgi = get_irn_dbg_info(node);
2713 int size = get_type_size_bytes(get_CopyB_type(node));
2716 /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2717 /* then we need the size explicitly in ECX. */
2718 if (size >= 32 * 4) {
2719 rem = size & 0x3; /* size % 4 */
2722 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2723 add_irn_dep(res, get_irg_frame(irg));
2725 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2728 ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2731 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2734 SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2739 static ir_node *gen_be_Copy(ir_node *node)
2741 ir_node *new_node = be_duplicate_node(node);
2742 ir_mode *mode = get_irn_mode(new_node);
2744 if (ia32_mode_needs_gp_reg(mode)) {
2745 set_irn_mode(new_node, mode_Iu);
2751 static ir_node *create_Fucom(ir_node *node)
2753 ir_graph *irg = current_ir_graph;
2754 dbg_info *dbgi = get_irn_dbg_info(node);
2755 ir_node *block = get_nodes_block(node);
2756 ir_node *new_block = be_transform_node(block);
2757 ir_node *left = get_Cmp_left(node);
2758 ir_node *new_left = be_transform_node(left);
2759 ir_node *right = get_Cmp_right(node);
2763 if(ia32_cg_config.use_fucomi) {
2764 new_right = be_transform_node(right);
2765 new_node = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2767 set_ia32_commutative(new_node);
2768 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2770 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2771 new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2774 new_right = be_transform_node(right);
2775 new_node = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2779 set_ia32_commutative(new_node);
2781 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2783 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2784 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2790 static ir_node *create_Ucomi(ir_node *node)
2792 ir_graph *irg = current_ir_graph;
2793 dbg_info *dbgi = get_irn_dbg_info(node);
2794 ir_node *src_block = get_nodes_block(node);
2795 ir_node *new_block = be_transform_node(src_block);
2796 ir_node *left = get_Cmp_left(node);
2797 ir_node *right = get_Cmp_right(node);
2799 ia32_address_mode_t am;
2800 ia32_address_t *addr = &am.addr;
2802 match_arguments(&am, src_block, left, right, NULL,
2803 match_commutative | match_am);
2805 new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2806 addr->mem, am.new_op1, am.new_op2,
2808 set_am_attributes(new_node, &am);
2810 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2812 new_node = fix_mem_proj(new_node, &am);
2818 * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2819 * to fold an and into a test node
2821 static int can_fold_test_and(ir_node *node)
2823 const ir_edge_t *edge;
2825 /** we can only have eq and lg projs */
2826 foreach_out_edge(node, edge) {
2827 ir_node *proj = get_edge_src_irn(edge);
2828 pn_Cmp pnc = get_Proj_proj(proj);
2829 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2837 * Generate code for a Cmp.
2839 static ir_node *gen_Cmp(ir_node *node)
2841 ir_graph *irg = current_ir_graph;
2842 dbg_info *dbgi = get_irn_dbg_info(node);
2843 ir_node *block = get_nodes_block(node);
2844 ir_node *new_block = be_transform_node(block);
2845 ir_node *left = get_Cmp_left(node);
2846 ir_node *right = get_Cmp_right(node);
2847 ir_mode *cmp_mode = get_irn_mode(left);
2849 ia32_address_mode_t am;
2850 ia32_address_t *addr = &am.addr;
2853 if(mode_is_float(cmp_mode)) {
2854 if (ia32_cg_config.use_sse2) {
2855 return create_Ucomi(node);
2857 return create_Fucom(node);
2861 assert(ia32_mode_needs_gp_reg(cmp_mode));
2863 /* we prefer the Test instruction where possible except cases where
2864 * we can use SourceAM */
2865 cmp_unsigned = !mode_is_signed(cmp_mode);
2866 if (is_Const_0(right)) {
2868 get_irn_n_edges(left) == 1 &&
2869 can_fold_test_and(node)) {
2870 /* Test(and_left, and_right) */
2871 ir_node *and_left = get_And_left(left);
2872 ir_node *and_right = get_And_right(left);
2873 ir_mode *mode = get_irn_mode(and_left);
2875 match_arguments(&am, block, and_left, and_right, NULL,
2877 match_am | match_8bit_am | match_16bit_am |
2878 match_am_and_immediates | match_immediate |
2879 match_8bit | match_16bit);
2880 if (get_mode_size_bits(mode) == 8) {
2881 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2882 addr->index, addr->mem, am.new_op1,
2883 am.new_op2, am.ins_permuted,
2886 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2887 addr->index, addr->mem, am.new_op1,
2888 am.new_op2, am.ins_permuted, cmp_unsigned);
2891 match_arguments(&am, block, NULL, left, NULL,
2892 match_am | match_8bit_am | match_16bit_am |
2893 match_8bit | match_16bit);
2894 if (am.op_type == ia32_AddrModeS) {
2896 ir_node *imm_zero = try_create_Immediate(right, 0);
2897 if (get_mode_size_bits(cmp_mode) == 8) {
2898 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2899 addr->index, addr->mem, am.new_op2,
2900 imm_zero, am.ins_permuted,
2903 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2904 addr->index, addr->mem, am.new_op2,
2905 imm_zero, am.ins_permuted, cmp_unsigned);
2908 /* Test(left, left) */
2909 if (get_mode_size_bits(cmp_mode) == 8) {
2910 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2911 addr->index, addr->mem, am.new_op2,
2912 am.new_op2, am.ins_permuted,
2915 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2916 addr->index, addr->mem, am.new_op2,
2917 am.new_op2, am.ins_permuted,
2923 /* Cmp(left, right) */
2924 match_arguments(&am, block, left, right, NULL,
2925 match_commutative | match_am | match_8bit_am |
2926 match_16bit_am | match_am_and_immediates |
2927 match_immediate | match_8bit | match_16bit);
2928 if (get_mode_size_bits(cmp_mode) == 8) {
2929 new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2930 addr->index, addr->mem, am.new_op1,
2931 am.new_op2, am.ins_permuted,
2934 new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2935 addr->index, addr->mem, am.new_op1,
2936 am.new_op2, am.ins_permuted, cmp_unsigned);
2939 set_am_attributes(new_node, &am);
2940 assert(cmp_mode != NULL);
2941 set_ia32_ls_mode(new_node, cmp_mode);
2943 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2945 new_node = fix_mem_proj(new_node, &am);
2950 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2953 ir_graph *irg = current_ir_graph;
2954 dbg_info *dbgi = get_irn_dbg_info(node);
2955 ir_node *block = get_nodes_block(node);
2956 ir_node *new_block = be_transform_node(block);
2957 ir_node *val_true = get_Psi_val(node, 0);
2958 ir_node *val_false = get_Psi_default(node);
2960 match_flags_t match_flags;
2961 ia32_address_mode_t am;
2962 ia32_address_t *addr;
2964 assert(ia32_cg_config.use_cmov);
2965 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2969 match_flags = match_commutative | match_am | match_16bit_am |
2972 match_arguments(&am, block, val_false, val_true, flags, match_flags);
2974 new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2975 addr->mem, am.new_op1, am.new_op2, new_flags,
2976 am.ins_permuted, pnc);
2977 set_am_attributes(new_node, &am);
2979 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2981 new_node = fix_mem_proj(new_node, &am);
2987 * Creates a ia32 Setcc instruction.
2989 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2990 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2993 ir_graph *irg = current_ir_graph;
2994 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2995 ir_node *nomem = new_NoMem();
2996 ir_mode *mode = get_irn_mode(orig_node);
2999 new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
3000 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
3002 /* we might need to conv the result up */
3003 if (get_mode_size_bits(mode) > 8) {
3004 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
3005 nomem, new_node, mode_Bu);
3006 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
3013 * Create instruction for an unsigned Difference or Zero.
3015 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
3016 ir_graph *irg = current_ir_graph;
3017 ir_mode *mode = get_irn_mode(psi);
3018 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
3021 new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
3022 match_mode_neutral | match_am | match_immediate | match_two_users);
3024 block = get_nodes_block(new_node);
3026 if (is_Proj(new_node)) {
3027 sub = get_Proj_pred(new_node);
3028 assert(is_ia32_Sub(sub));
3031 set_irn_mode(sub, mode_T);
3032 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
3034 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3036 dbgi = get_irn_dbg_info(psi);
3037 noreg = ia32_new_NoReg_gp(env_cg);
3038 tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
3039 nomem = new_NoMem();
3040 sbb = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
3042 new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
3043 set_ia32_commutative(new_node);
3048 * Transforms a Psi node into CMov.
3050 * @return The transformed node.
3052 static ir_node *gen_Psi(ir_node *node)
3054 dbg_info *dbgi = get_irn_dbg_info(node);
3055 ir_node *block = get_nodes_block(node);
3056 ir_node *new_block = be_transform_node(block);
3057 ir_node *psi_true = get_Psi_val(node, 0);
3058 ir_node *psi_default = get_Psi_default(node);
3059 ir_node *cond = get_Psi_cond(node, 0);
3060 ir_mode *mode = get_irn_mode(node);
3063 assert(get_Psi_n_conds(node) == 1);
3064 assert(get_irn_mode(cond) == mode_b);
3066 /* Note: a Psi node uses a Load two times IFF it's used in the compare AND in the result */
3067 if (mode_is_float(mode)) {
3068 ir_node *cmp = get_Proj_pred(cond);
3069 ir_node *cmp_left = get_Cmp_left(cmp);
3070 ir_node *cmp_right = get_Cmp_right(cmp);
3071 pn_Cmp pnc = get_Proj_proj(cond);
3073 if (ia32_cg_config.use_sse2) {
3074 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3075 if (cmp_left == psi_true && cmp_right == psi_default) {
3076 /* psi(a <= b, a, b) => MIN */
3077 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3078 match_commutative | match_am | match_two_users);
3079 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3080 /* psi(a <= b, b, a) => MAX */
3081 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3082 match_commutative | match_am | match_two_users);
3084 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3085 if (cmp_left == psi_true && cmp_right == psi_default) {
3086 /* psi(a >= b, a, b) => MAX */
3087 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3088 match_commutative | match_am | match_two_users);
3089 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3090 /* psi(a >= b, b, a) => MIN */
3091 return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3092 match_commutative | match_am | match_two_users);
3096 panic("cannot transform floating point Psi");
3102 assert(ia32_mode_needs_gp_reg(mode));
3104 if (is_Proj(cond)) {
3105 ir_node *cmp = get_Proj_pred(cond);
3107 ir_node *cmp_left = get_Cmp_left(cmp);
3108 ir_node *cmp_right = get_Cmp_right(cmp);
3109 pn_Cmp pnc = get_Proj_proj(cond);
3111 /* check for unsigned Doz first */
3112 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3113 is_Const_0(psi_default) && is_Sub(psi_true) &&
3114 get_Sub_left(psi_true) == cmp_left && get_Sub_right(psi_true) == cmp_right) {
3115 /* Psi(a >=u b, a - b, 0) unsigned Doz */
3116 return create_Doz(node, cmp_left, cmp_right);
3117 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3118 is_Const_0(psi_true) && is_Sub(psi_default) &&
3119 get_Sub_left(psi_default) == cmp_left && get_Sub_right(psi_default) == cmp_right) {
3120 /* Psi(a <=u b, 0, a - b) unsigned Doz */
3121 return create_Doz(node, cmp_left, cmp_right);
3126 flags = get_flags_node(cond, &pnc);
3128 if (is_Const(psi_true) && is_Const(psi_default)) {
3129 /* both are const, good */
3130 if (is_Const_1(psi_true) && is_Const_0(psi_default)) {
3131 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3132 } else if (is_Const_0(psi_true) && is_Const_1(psi_default)) {
3133 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3135 /* Not that simple. */
3140 new_node = create_CMov(node, cond, flags, pnc);
3148 * Create a conversion from x87 state register to general purpose.
3150 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3151 ir_node *block = be_transform_node(get_nodes_block(node));
3152 ir_node *op = get_Conv_op(node);
3153 ir_node *new_op = be_transform_node(op);
3154 ia32_code_gen_t *cg = env_cg;
3155 ir_graph *irg = current_ir_graph;
3156 dbg_info *dbgi = get_irn_dbg_info(node);
3157 ir_node *noreg = ia32_new_NoReg_gp(cg);
3158 ir_mode *mode = get_irn_mode(node);
3159 ir_node *fist, *load, *mem;
3161 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3162 set_irn_pinned(fist, op_pin_state_floats);
3163 set_ia32_use_frame(fist);
3164 set_ia32_op_type(fist, ia32_AddrModeD);
3166 assert(get_mode_size_bits(mode) <= 32);
3167 /* exception we can only store signed 32 bit integers, so for unsigned
3168 we store a 64bit (signed) integer and load the lower bits */
3169 if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3170 set_ia32_ls_mode(fist, mode_Ls);
3172 set_ia32_ls_mode(fist, mode_Is);
3174 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3177 load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3179 set_irn_pinned(load, op_pin_state_floats);
3180 set_ia32_use_frame(load);
3181 set_ia32_op_type(load, ia32_AddrModeS);
3182 set_ia32_ls_mode(load, mode_Is);
3183 if(get_ia32_ls_mode(fist) == mode_Ls) {
3184 ia32_attr_t *attr = get_ia32_attr(load);
3185 attr->data.need_64bit_stackent = 1;
3187 ia32_attr_t *attr = get_ia32_attr(load);
3188 attr->data.need_32bit_stackent = 1;
3190 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3192 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3196 * Creates a x87 strict Conv by placing a Sore and a Load
3198 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3200 ir_node *block = get_nodes_block(node);
3201 ir_graph *irg = current_ir_graph;
3202 dbg_info *dbgi = get_irn_dbg_info(node);
3203 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3204 ir_node *nomem = new_NoMem();
3205 ir_node *frame = get_irg_frame(irg);
3206 ir_node *store, *load;
3209 store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3211 set_ia32_use_frame(store);
3212 set_ia32_op_type(store, ia32_AddrModeD);
3213 SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3215 load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3217 set_ia32_use_frame(load);
3218 set_ia32_op_type(load, ia32_AddrModeS);
3219 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3221 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3226 * Create a conversion from general purpose to x87 register
3228 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3229 ir_node *src_block = get_nodes_block(node);
3230 ir_node *block = be_transform_node(src_block);
3231 ir_graph *irg = current_ir_graph;
3232 dbg_info *dbgi = get_irn_dbg_info(node);
3233 ir_node *op = get_Conv_op(node);
3234 ir_node *new_op = NULL;
3238 ir_mode *store_mode;
3244 /* fild can use source AM if the operand is a signed 32bit integer */
3245 if (src_mode == mode_Is) {
3246 ia32_address_mode_t am;
3248 match_arguments(&am, src_block, NULL, op, NULL,
3249 match_am | match_try_am);
3250 if (am.op_type == ia32_AddrModeS) {
3251 ia32_address_t *addr = &am.addr;
3253 fild = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3254 addr->index, addr->mem);
3255 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3258 set_am_attributes(fild, &am);
3259 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3261 fix_mem_proj(fild, &am);
3266 if(new_op == NULL) {
3267 new_op = be_transform_node(op);
3270 noreg = ia32_new_NoReg_gp(env_cg);
3271 nomem = new_NoMem();
3272 mode = get_irn_mode(op);
3274 /* first convert to 32 bit signed if necessary */
3275 src_bits = get_mode_size_bits(src_mode);
3276 if (src_bits == 8) {
3277 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3279 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3281 } else if (src_bits < 32) {
3282 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3284 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3288 assert(get_mode_size_bits(mode) == 32);
3291 store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3294 set_ia32_use_frame(store);
3295 set_ia32_op_type(store, ia32_AddrModeD);
3296 set_ia32_ls_mode(store, mode_Iu);
3298 /* exception for 32bit unsigned, do a 64bit spill+load */
3299 if(!mode_is_signed(mode)) {
3302 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3304 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3305 get_irg_frame(irg), noreg, nomem,
3308 set_ia32_use_frame(zero_store);
3309 set_ia32_op_type(zero_store, ia32_AddrModeD);
3310 add_ia32_am_offs_int(zero_store, 4);
3311 set_ia32_ls_mode(zero_store, mode_Iu);
3316 store = new_rd_Sync(dbgi, irg, block, 2, in);
3317 store_mode = mode_Ls;
3319 store_mode = mode_Is;
3323 fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3325 set_ia32_use_frame(fild);
3326 set_ia32_op_type(fild, ia32_AddrModeS);
3327 set_ia32_ls_mode(fild, store_mode);
3329 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3335 * Create a conversion from one integer mode into another one
3337 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3338 dbg_info *dbgi, ir_node *block, ir_node *op,
3341 ir_graph *irg = current_ir_graph;
3342 int src_bits = get_mode_size_bits(src_mode);
3343 int tgt_bits = get_mode_size_bits(tgt_mode);
3344 ir_node *new_block = be_transform_node(block);
3346 ir_mode *smaller_mode;
3348 ia32_address_mode_t am;
3349 ia32_address_t *addr = &am.addr;
3352 if (src_bits < tgt_bits) {
3353 smaller_mode = src_mode;
3354 smaller_bits = src_bits;
3356 smaller_mode = tgt_mode;
3357 smaller_bits = tgt_bits;
3360 #ifdef DEBUG_libfirm
3362 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3367 match_arguments(&am, block, NULL, op, NULL,
3368 match_8bit | match_16bit |
3369 match_am | match_8bit_am | match_16bit_am);
3370 if (smaller_bits == 8) {
3371 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3372 addr->index, addr->mem, am.new_op2,
3375 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3376 addr->index, addr->mem, am.new_op2,
3379 set_am_attributes(new_node, &am);
3380 /* match_arguments assume that out-mode = in-mode, this isn't true here
3382 set_ia32_ls_mode(new_node, smaller_mode);
3383 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3384 new_node = fix_mem_proj(new_node, &am);
3389 * Transforms a Conv node.
3391 * @return The created ia32 Conv node
3393 static ir_node *gen_Conv(ir_node *node) {
3394 ir_node *block = get_nodes_block(node);
3395 ir_node *new_block = be_transform_node(block);
3396 ir_node *op = get_Conv_op(node);
3397 ir_node *new_op = NULL;
3398 ir_graph *irg = current_ir_graph;
3399 dbg_info *dbgi = get_irn_dbg_info(node);
3400 ir_mode *src_mode = get_irn_mode(op);
3401 ir_mode *tgt_mode = get_irn_mode(node);
3402 int src_bits = get_mode_size_bits(src_mode);
3403 int tgt_bits = get_mode_size_bits(tgt_mode);
3404 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3405 ir_node *nomem = new_rd_NoMem(irg);
3406 ir_node *res = NULL;
3408 if (src_mode == mode_b) {
3409 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3410 /* nothing to do, we already model bools as 0/1 ints */
3411 return be_transform_node(op);
3414 if (src_mode == tgt_mode) {
3415 if (get_Conv_strict(node)) {
3416 if (ia32_cg_config.use_sse2) {
3417 /* when we are in SSE mode, we can kill all strict no-op conversion */
3418 return be_transform_node(op);
3421 /* this should be optimized already, but who knows... */
3422 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3423 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3424 return be_transform_node(op);
3428 if (mode_is_float(src_mode)) {
3429 new_op = be_transform_node(op);
3430 /* we convert from float ... */
3431 if (mode_is_float(tgt_mode)) {
3432 if(src_mode == mode_E && tgt_mode == mode_D
3433 && !get_Conv_strict(node)) {
3434 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3439 if (ia32_cg_config.use_sse2) {
3440 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3441 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3443 set_ia32_ls_mode(res, tgt_mode);
3445 if(get_Conv_strict(node)) {
3446 res = gen_x87_strict_conv(tgt_mode, new_op);
3447 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3450 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3455 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3456 if (ia32_cg_config.use_sse2) {
3457 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3459 set_ia32_ls_mode(res, src_mode);
3461 return gen_x87_fp_to_gp(node);
3465 /* we convert from int ... */
3466 if (mode_is_float(tgt_mode)) {
3468 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3469 if (ia32_cg_config.use_sse2) {
3470 new_op = be_transform_node(op);
3471 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3473 set_ia32_ls_mode(res, tgt_mode);
3475 res = gen_x87_gp_to_fp(node, src_mode);
3476 if(get_Conv_strict(node)) {
3477 res = gen_x87_strict_conv(tgt_mode, res);
3478 SET_IA32_ORIG_NODE(get_Proj_pred(res),
3479 ia32_get_old_node_name(env_cg, node));
3483 } else if(tgt_mode == mode_b) {
3484 /* mode_b lowering already took care that we only have 0/1 values */
3485 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3486 src_mode, tgt_mode));
3487 return be_transform_node(op);
3490 if (src_bits == tgt_bits) {
3491 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3492 src_mode, tgt_mode));
3493 return be_transform_node(op);
3496 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3504 static bool check_immediate_constraint(long val, char immediate_constraint_type)
3506 switch (immediate_constraint_type) {
3511 return val >= 0 && val <= 32;
3513 return val >= 0 && val <= 63;
3515 return val >= -128 && val <= 127;
3517 return val == 0xff || val == 0xffff;
3519 return val >= 0 && val <= 3;
3521 return val >= 0 && val <= 255;
3523 return val >= 0 && val <= 127;
3527 panic("Invalid immediate constraint found");
3531 static ir_node *try_create_Immediate(ir_node *node,
3532 char immediate_constraint_type)
3535 tarval *offset = NULL;
3536 int offset_sign = 0;
3538 ir_entity *symconst_ent = NULL;
3539 int symconst_sign = 0;
3541 ir_node *cnst = NULL;
3542 ir_node *symconst = NULL;
3545 mode = get_irn_mode(node);
3546 if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3550 if(is_Minus(node)) {
3552 node = get_Minus_op(node);
3555 if(is_Const(node)) {
3558 offset_sign = minus;
3559 } else if(is_SymConst(node)) {
3562 symconst_sign = minus;
3563 } else if(is_Add(node)) {
3564 ir_node *left = get_Add_left(node);
3565 ir_node *right = get_Add_right(node);
3566 if(is_Const(left) && is_SymConst(right)) {
3569 symconst_sign = minus;
3570 offset_sign = minus;
3571 } else if(is_SymConst(left) && is_Const(right)) {
3574 symconst_sign = minus;
3575 offset_sign = minus;
3577 } else if(is_Sub(node)) {
3578 ir_node *left = get_Sub_left(node);
3579 ir_node *right = get_Sub_right(node);
3580 if(is_Const(left) && is_SymConst(right)) {
3583 symconst_sign = !minus;
3584 offset_sign = minus;
3585 } else if(is_SymConst(left) && is_Const(right)) {
3588 symconst_sign = minus;
3589 offset_sign = !minus;
3596 offset = get_Const_tarval(cnst);
3597 if(tarval_is_long(offset)) {
3598 val = get_tarval_long(offset);
3600 ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3605 if(!check_immediate_constraint(val, immediate_constraint_type))
3608 if(symconst != NULL) {
3609 if(immediate_constraint_type != 0) {
3610 /* we need full 32bits for symconsts */
3614 /* unfortunately the assembler/linker doesn't support -symconst */
3618 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3620 symconst_ent = get_SymConst_entity(symconst);
3622 if(cnst == NULL && symconst == NULL)
3625 if(offset_sign && offset != NULL) {
3626 offset = tarval_neg(offset);
3629 new_node = create_Immediate(symconst_ent, symconst_sign, val);
3634 static ir_node *create_immediate_or_transform(ir_node *node,
3635 char immediate_constraint_type)
3637 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3638 if (new_node == NULL) {
3639 new_node = be_transform_node(node);
3646 void parse_asm_constraints(constraint_t *constraint, const char *c,
3649 asm_constraint_flags_t flags = 0;
3650 char immediate_type = '\0';
3651 unsigned limited = 0;
3652 const arch_register_class_t *cls = NULL;
3653 bool memory_possible = false;
3654 bool all_registers_allowed = false;
3658 memset(constraint, 0, sizeof(constraint[0]));
3659 constraint->same_as = -1;
3662 /* a memory constraint: no need to do anything in backend about it
3663 * (the dependencies are already respected by the memory edge of
3668 /* TODO: improve error messages with node and source info. (As users can
3669 * easily hit these) */
3678 flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE
3679 | ASM_CONSTRAINT_FLAG_MODIFIER_NO_READ;
3683 flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE
3684 | ASM_CONSTRAINT_FLAG_MODIFIER_READ;
3691 while(*c != 0 && *c != ',')
3696 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3697 cls = &ia32_reg_classes[CLASS_ia32_gp];
3698 limited |= 1 << REG_EAX;
3701 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3702 cls = &ia32_reg_classes[CLASS_ia32_gp];
3703 limited |= 1 << REG_EBX;
3706 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3707 cls = &ia32_reg_classes[CLASS_ia32_gp];
3708 limited |= 1 << REG_ECX;
3711 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3712 cls = &ia32_reg_classes[CLASS_ia32_gp];
3713 limited |= 1 << REG_EDX;
3716 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3717 cls = &ia32_reg_classes[CLASS_ia32_gp];
3718 limited |= 1 << REG_EDI;
3721 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3722 cls = &ia32_reg_classes[CLASS_ia32_gp];
3723 limited |= 1 << REG_ESI;
3727 /* q means lower part of the regs only, this makes no
3728 * difference to Q for us (we only assign whole registers) */
3729 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3730 cls = &ia32_reg_classes[CLASS_ia32_gp];
3731 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3735 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3736 cls = &ia32_reg_classes[CLASS_ia32_gp];
3737 limited |= 1 << REG_EAX | 1 << REG_EDX;
3740 assert(cls == NULL || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3741 cls = &ia32_reg_classes[CLASS_ia32_gp];
3742 limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3743 1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3750 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3751 panic("multiple register classes not supported");
3752 cls = &ia32_reg_classes[CLASS_ia32_gp];
3753 all_registers_allowed = true;
3759 /* TODO: mark values so the x87 simulator knows about t and u */
3760 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_vfp])
3761 panic("multiple register classes not supported");
3762 cls = &ia32_reg_classes[CLASS_ia32_vfp];
3763 all_registers_allowed = true;
3768 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_xmm])
3769 panic("multiple register classes not supproted");
3770 cls = &ia32_reg_classes[CLASS_ia32_xmm];
3771 all_registers_allowed = true;
3781 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3782 panic("multiple register classes not supported");
3783 if (immediate_type != '\0')
3784 panic("multiple immediate types not supported");
3785 cls = &ia32_reg_classes[CLASS_ia32_gp];
3786 immediate_type = *c;
3790 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3791 panic("multiple register classes not supported");
3792 if (immediate_type != '\0')
3793 panic("multiple immediate types not supported");
3794 cls = &ia32_reg_classes[CLASS_ia32_gp];
3795 immediate_type = 'i';
3800 if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_gp])
3801 panic("multiple register classes not supported");
3802 if (immediate_type != '\0')
3803 panic("multiple immediate types not supported");
3804 immediate_type = 'i';
3805 cls = &ia32_reg_classes[CLASS_ia32_gp];
3806 all_registers_allowed = true;
3807 memory_possible = true;
3821 panic("can only specify same constraint on input");
3823 sscanf(c, "%d%n", &same_as, &p);
3833 /* memory constraint no need to do anything in backend about it
3834 * (the dependencies are already respected by the memory edge of
3836 memory_possible = true;
3839 case 'E': /* no float consts yet */
3840 case 'F': /* no float consts yet */
3841 case 's': /* makes no sense on x86 */
3842 case '<': /* no autodecrement on x86 */
3843 case '>': /* no autoincrement on x86 */
3844 case 'C': /* sse constant not supported yet */
3845 case 'G': /* 80387 constant not supported yet */
3846 case 'y': /* we don't support mmx registers yet */
3847 case 'Z': /* not available in 32 bit mode */
3848 case 'e': /* not available in 32 bit mode */
3849 panic("unsupported asm constraint '%c' found in (%+F)",
3850 *c, current_ir_graph);
3853 panic("unknown asm constraint '%c' found in (%+F)", *c,
3862 panic("same as and register constraint not supported");
3863 if (immediate_type != '\0')
3864 panic("same as and immediate constraint not supported");
3867 if (cls == NULL && same_as < 0) {
3868 if (!memory_possible)
3869 panic("no constraint specified for assembler input");
3872 constraint->same_as = same_as;
3873 constraint->cls = cls;
3874 constraint->allowed_registers = limited;
3875 constraint->all_registers_allowed = all_registers_allowed;
3876 constraint->memory_possible = memory_possible;
3877 constraint->immediate_type = immediate_type;
3880 const arch_register_req_t *make_register_req(const constraint_t *constraint,
3881 int n_outs, const arch_register_req_t **out_reqs, int pos)
3883 struct obstack *obst = get_irg_obstack(current_ir_graph);
3884 int same_as = constraint->same_as;
3885 arch_register_req_t *req;
3888 const arch_register_req_t *other_constr;
3890 if (same_as >= n_outs)
3891 panic("invalid output number in same_as constraint");
3893 other_constr = out_reqs[same_as];
3895 req = obstack_alloc(obst, sizeof(req[0]));
3896 req->cls = other_constr->cls;
3897 req->type = arch_register_req_type_should_be_same;
3898 req->limited = NULL;
3899 req->other_same = 1U << pos;
3900 req->other_different = 0;
3902 /* switch constraints. This is because in firm we have same_as
3903 * constraints on the output constraints while in the gcc asm syntax
3904 * they are specified on the input constraints */
3905 out_reqs[same_as] = req;
3906 return other_constr;
3909 /* pure memory ops */
3910 if (constraint->cls == NULL) {
3911 return &no_register_req;
3914 if (constraint->allowed_registers != 0
3915 && !constraint->all_registers_allowed) {
3916 unsigned *limited_ptr;
3918 req = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3919 memset(req, 0, sizeof(req[0]));
3920 limited_ptr = (unsigned*) (req+1);
3922 req->type = arch_register_req_type_limited;
3923 *limited_ptr = constraint->allowed_registers;
3924 req->limited = limited_ptr;
3926 req = obstack_alloc(obst, sizeof(req[0]));
3927 memset(req, 0, sizeof(req[0]));
3928 req->type = arch_register_req_type_normal;
3930 req->cls = constraint->cls;
3935 const arch_register_t *ia32_get_clobber_register(const char *clobber)
3937 const arch_register_t *reg = NULL;
3940 const arch_register_class_t *cls;
3942 /* TODO: construct a hashmap instead of doing linear search for clobber
3944 for(c = 0; c < N_CLASSES; ++c) {
3945 cls = & ia32_reg_classes[c];
3946 for(r = 0; r < cls->n_regs; ++r) {
3947 const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3948 if(strcmp(temp_reg->name, clobber) == 0
3949 || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3961 const arch_register_req_t *parse_clobber(const char *clobber)
3963 struct obstack *obst = get_irg_obstack(current_ir_graph);
3964 const arch_register_t *reg = ia32_get_clobber_register(clobber);
3965 arch_register_req_t *req;
3969 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3972 assert(reg->index < 32);
3974 limited = obstack_alloc(obst, sizeof(limited[0]));
3975 *limited = 1 << reg->index;
3977 req = obstack_alloc(obst, sizeof(req[0]));
3978 memset(req, 0, sizeof(req[0]));
3979 req->type = arch_register_req_type_limited;
3980 req->cls = arch_register_get_class(reg);
3981 req->limited = limited;
3987 * generates code for a ASM node
3989 static ir_node *gen_ASM(ir_node *node)
3991 ir_graph *irg = current_ir_graph;
3992 ir_node *block = get_nodes_block(node);
3993 ir_node *new_block = be_transform_node(block);
3994 dbg_info *dbgi = get_irn_dbg_info(node);
4000 int n_out_constraints;
4002 const arch_register_req_t **out_reg_reqs;
4003 const arch_register_req_t **in_reg_reqs;
4004 ia32_asm_reg_t *register_map;
4005 unsigned reg_map_size = 0;
4006 struct obstack *obst;
4007 const ir_asm_constraint *in_constraints;
4008 const ir_asm_constraint *out_constraints;
4010 bool clobbers_flags = false;
4012 /* workaround for lots of buggy code out there as most people think volatile
4013 * asm is enough for everything and forget the flags (linux kernel, etc.)
4015 if (get_irn_pinned(node) == op_pin_state_pinned) {
4016 clobbers_flags = true;
4019 arity = get_irn_arity(node);
4020 in = alloca(arity * sizeof(in[0]));
4021 memset(in, 0, arity * sizeof(in[0]));
4023 clobbers = get_ASM_clobbers(node);
4025 for(i = 0; i < get_ASM_n_clobbers(node); ++i) {
4026 const char *c = get_id_str(clobbers[i]);
4027 if (strcmp(c, "memory") == 0)
4029 if (strcmp(c, "cc") == 0) {
4030 clobbers_flags = true;
4035 n_out_constraints = get_ASM_n_output_constraints(node);
4036 out_arity = n_out_constraints + n_clobbers;
4038 in_constraints = get_ASM_input_constraints(node);
4039 out_constraints = get_ASM_output_constraints(node);
4041 /* determine size of register_map */
4042 for(out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
4043 const ir_asm_constraint *constraint = &out_constraints[out_idx];
4044 if (constraint->pos > reg_map_size)
4045 reg_map_size = constraint->pos;
4047 for(i = 0; i < arity; ++i) {
4048 const ir_asm_constraint *constraint = &in_constraints[i];
4049 if(constraint->pos > reg_map_size)
4050 reg_map_size = constraint->pos;
4054 obst = get_irg_obstack(irg);
4055 register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
4056 memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
4058 /* construct output constraints */
4059 out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
4061 for(out_idx = 0; out_idx < n_out_constraints; ++out_idx) {
4062 const ir_asm_constraint *constraint = &out_constraints[out_idx];
4063 const char *c = get_id_str(constraint->constraint);
4064 unsigned pos = constraint->pos;
4065 constraint_t parsed_constraint;
4066 const arch_register_req_t *req;
4068 parse_asm_constraints(&parsed_constraint, c, true);
4069 req = make_register_req(&parsed_constraint, n_out_constraints,
4070 out_reg_reqs, out_idx);
4071 out_reg_reqs[out_idx] = req;
4073 register_map[pos].use_input = false;
4074 register_map[pos].valid = true;
4075 register_map[pos].memory = false;
4076 register_map[pos].inout_pos = out_idx;
4077 register_map[pos].mode = constraint->mode;
4080 /* inputs + input constraints */
4081 in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
4082 for(i = 0; i < arity; ++i) {
4083 ir_node *pred = get_irn_n(node, i);
4084 const ir_asm_constraint *constraint = &in_constraints[i];
4085 ident *constr_id = constraint->constraint;
4086 const char *c = get_id_str(constr_id);
4087 unsigned pos = constraint->pos;
4088 bool is_memory_op = false;
4089 ir_node *input = NULL;
4090 constraint_t parsed_constraint;
4091 const arch_register_req_t *req;
4093 parse_asm_constraints(&parsed_constraint, c, false);
4094 req = make_register_req(&parsed_constraint, n_out_constraints,
4096 in_reg_reqs[i] = req;
4098 if (parsed_constraint.immediate_type != '\0') {
4099 char imm_type = parsed_constraint.immediate_type;
4100 input = try_create_Immediate(pred, imm_type);
4103 if (input == NULL) {
4104 ir_node *pred = get_irn_n(node, i);
4105 input = be_transform_node(pred);
4107 if (parsed_constraint.cls == NULL
4108 && parsed_constraint.same_as < 0) {
4109 is_memory_op = true;
4110 } else if(parsed_constraint.memory_possible) {
4111 /* TODO: match Load or Load/Store if memory possible is set */
4116 register_map[pos].use_input = true;
4117 register_map[pos].valid = true;
4118 register_map[pos].memory = is_memory_op;
4119 register_map[pos].inout_pos = i;
4120 register_map[pos].mode = constraint->mode;
4123 /* parse clobbers */
4124 for(i = 0; i < get_ASM_n_clobbers(node); ++i) {
4125 const char *c = get_id_str(clobbers[i]);
4126 const arch_register_req_t *req;
4128 if (strcmp(c, "memory") == 0 || strcmp(c, "cc") == 0)
4131 req = parse_clobber(c);
4132 out_reg_reqs[out_idx] = req;
4136 new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
4137 get_ASM_text(node), register_map);
4139 set_ia32_out_req_all(new_node, out_reg_reqs);
4140 set_ia32_in_req_all(new_node, in_reg_reqs);
4142 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4148 * Transforms a FrameAddr into an ia32 Add.
4150 static ir_node *gen_be_FrameAddr(ir_node *node) {
4151 ir_node *block = be_transform_node(get_nodes_block(node));
4152 ir_node *op = be_get_FrameAddr_frame(node);
4153 ir_node *new_op = be_transform_node(op);
4154 ir_graph *irg = current_ir_graph;
4155 dbg_info *dbgi = get_irn_dbg_info(node);
4156 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4159 new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
4160 set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
4161 set_ia32_use_frame(new_node);
4163 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4169 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
4171 static ir_node *gen_be_Return(ir_node *node) {
4172 ir_graph *irg = current_ir_graph;
4173 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
4174 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
4175 ir_entity *ent = get_irg_entity(irg);
4176 ir_type *tp = get_entity_type(ent);
4181 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
4182 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
4185 int pn_ret_val, pn_ret_mem, arity, i;
4187 assert(ret_val != NULL);
4188 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4189 return be_duplicate_node(node);
4192 res_type = get_method_res_type(tp, 0);
4194 if (! is_Primitive_type(res_type)) {
4195 return be_duplicate_node(node);
4198 mode = get_type_mode(res_type);
4199 if (! mode_is_float(mode)) {
4200 return be_duplicate_node(node);
4203 assert(get_method_n_ress(tp) == 1);
4205 pn_ret_val = get_Proj_proj(ret_val);
4206 pn_ret_mem = get_Proj_proj(ret_mem);
4208 /* get the Barrier */
4209 barrier = get_Proj_pred(ret_val);
4211 /* get result input of the Barrier */
4212 ret_val = get_irn_n(barrier, pn_ret_val);
4213 new_ret_val = be_transform_node(ret_val);
4215 /* get memory input of the Barrier */
4216 ret_mem = get_irn_n(barrier, pn_ret_mem);
4217 new_ret_mem = be_transform_node(ret_mem);
4219 frame = get_irg_frame(irg);
4221 dbgi = get_irn_dbg_info(barrier);
4222 block = be_transform_node(get_nodes_block(barrier));
4224 noreg = ia32_new_NoReg_gp(env_cg);
4226 /* store xmm0 onto stack */
4227 sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
4228 new_ret_mem, new_ret_val);
4229 set_ia32_ls_mode(sse_store, mode);
4230 set_ia32_op_type(sse_store, ia32_AddrModeD);
4231 set_ia32_use_frame(sse_store);
4233 /* load into x87 register */
4234 fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
4235 set_ia32_op_type(fld, ia32_AddrModeS);
4236 set_ia32_use_frame(fld);
4238 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
4239 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
4241 /* create a new barrier */
4242 arity = get_irn_arity(barrier);
4243 in = alloca(arity * sizeof(in[0]));
4244 for (i = 0; i < arity; ++i) {
4247 if (i == pn_ret_val) {
4249 } else if (i == pn_ret_mem) {
4252 ir_node *in = get_irn_n(barrier, i);
4253 new_in = be_transform_node(in);
4258 new_barrier = new_ir_node(dbgi, irg, block,
4259 get_irn_op(barrier), get_irn_mode(barrier),
4261 copy_node_attr(barrier, new_barrier);
4262 be_duplicate_deps(barrier, new_barrier);
4263 be_set_transformed_node(barrier, new_barrier);
4264 mark_irn_visited(barrier);
4266 /* transform normally */
4267 return be_duplicate_node(node);
4271 * Transform a be_AddSP into an ia32_SubSP.
4273 static ir_node *gen_be_AddSP(ir_node *node)
4275 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4276 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4278 return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
4282 * Transform a be_SubSP into an ia32_AddSP
4284 static ir_node *gen_be_SubSP(ir_node *node)
4286 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4287 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4289 return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
4293 * This function just sets the register for the Unknown node
4294 * as this is not done during register allocation because Unknown
4295 * is an "ignore" node.
4297 static ir_node *gen_Unknown(ir_node *node) {
4298 ir_mode *mode = get_irn_mode(node);
4300 if (mode_is_float(mode)) {
4301 if (ia32_cg_config.use_sse2) {
4302 return ia32_new_Unknown_xmm(env_cg);
4304 /* Unknown nodes are buggy in x87 simulator, use zero for now... */
4305 ir_graph *irg = current_ir_graph;
4306 dbg_info *dbgi = get_irn_dbg_info(node);
4307 ir_node *block = get_irg_start_block(irg);
4308 ir_node *ret = new_rd_ia32_vfldz(dbgi, irg, block);
4310 /* Const Nodes before the initial IncSP are a bad idea, because
4311 * they could be spilled and we have no SP ready at that point yet.
4312 * So add a dependency to the initial frame pointer calculation to
4313 * avoid that situation.
4315 add_irn_dep(ret, get_irg_frame(irg));
4318 } else if (ia32_mode_needs_gp_reg(mode)) {
4319 return ia32_new_Unknown_gp(env_cg);
4321 panic("unsupported Unknown-Mode");
4327 * Change some phi modes
4329 static ir_node *gen_Phi(ir_node *node) {
4330 ir_node *block = be_transform_node(get_nodes_block(node));
4331 ir_graph *irg = current_ir_graph;
4332 dbg_info *dbgi = get_irn_dbg_info(node);
4333 ir_mode *mode = get_irn_mode(node);
4336 if(ia32_mode_needs_gp_reg(mode)) {
4337 /* we shouldn't have any 64bit stuff around anymore */
4338 assert(get_mode_size_bits(mode) <= 32);
4339 /* all integer operations are on 32bit registers now */
4341 } else if(mode_is_float(mode)) {
4342 if (ia32_cg_config.use_sse2) {
4349 /* phi nodes allow loops, so we use the old arguments for now
4350 * and fix this later */
4351 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4352 get_irn_in(node) + 1);
4353 copy_node_attr(node, phi);
4354 be_duplicate_deps(node, phi);
4356 be_set_transformed_node(node, phi);
4357 be_enqueue_preds(node);
4365 static ir_node *gen_IJmp(ir_node *node)
4367 ir_node *block = get_nodes_block(node);
4368 ir_node *new_block = be_transform_node(block);
4369 dbg_info *dbgi = get_irn_dbg_info(node);
4370 ir_node *op = get_IJmp_target(node);
4372 ia32_address_mode_t am;
4373 ia32_address_t *addr = &am.addr;
4375 assert(get_irn_mode(op) == mode_P);
4377 match_arguments(&am, block, NULL, op, NULL,
4378 match_am | match_8bit_am | match_16bit_am |
4379 match_immediate | match_8bit | match_16bit);
4381 new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
4382 addr->base, addr->index, addr->mem,
4384 set_am_attributes(new_node, &am);
4385 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4387 new_node = fix_mem_proj(new_node, &am);
4393 * Transform a Bound node.
4395 static ir_node *gen_Bound(ir_node *node)
4398 ir_node *lower = get_Bound_lower(node);
4399 dbg_info *dbgi = get_irn_dbg_info(node);
4401 if (is_Const_0(lower)) {
4402 /* typical case for Java */
4403 ir_node *sub, *res, *flags, *block;
4404 ir_graph *irg = current_ir_graph;
4406 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
4407 new_rd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
4409 block = get_nodes_block(res);
4410 if (! is_Proj(res)) {
4412 set_irn_mode(sub, mode_T);
4413 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
4415 sub = get_Proj_pred(res);
4417 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
4418 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
4419 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4421 panic("generic Bound not supported in ia32 Backend");
4427 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4430 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4431 ir_node *val, ir_node *mem);
4434 * Transforms a lowered Load into a "real" one.
4436 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4438 ir_node *block = be_transform_node(get_nodes_block(node));
4439 ir_node *ptr = get_irn_n(node, 0);
4440 ir_node *new_ptr = be_transform_node(ptr);
4441 ir_node *mem = get_irn_n(node, 1);
4442 ir_node *new_mem = be_transform_node(mem);
4443 ir_graph *irg = current_ir_graph;
4444 dbg_info *dbgi = get_irn_dbg_info(node);
4445 ir_mode *mode = get_ia32_ls_mode(node);
4446 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4449 new_op = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4451 set_ia32_op_type(new_op, ia32_AddrModeS);
4452 set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4453 set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4454 set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4455 if (is_ia32_am_sc_sign(node))
4456 set_ia32_am_sc_sign(new_op);
4457 set_ia32_ls_mode(new_op, mode);
4458 if (is_ia32_use_frame(node)) {
4459 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4460 set_ia32_use_frame(new_op);
4463 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4469 * Transforms a lowered Store into a "real" one.
4471 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4473 ir_node *block = be_transform_node(get_nodes_block(node));
4474 ir_node *ptr = get_irn_n(node, 0);
4475 ir_node *new_ptr = be_transform_node(ptr);
4476 ir_node *val = get_irn_n(node, 1);
4477 ir_node *new_val = be_transform_node(val);
4478 ir_node *mem = get_irn_n(node, 2);
4479 ir_node *new_mem = be_transform_node(mem);
4480 ir_graph *irg = current_ir_graph;
4481 dbg_info *dbgi = get_irn_dbg_info(node);
4482 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4483 ir_mode *mode = get_ia32_ls_mode(node);
4487 new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4489 am_offs = get_ia32_am_offs_int(node);
4490 add_ia32_am_offs_int(new_op, am_offs);
4492 set_ia32_op_type(new_op, ia32_AddrModeD);
4493 set_ia32_ls_mode(new_op, mode);
4494 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4495 set_ia32_use_frame(new_op);
4497 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4502 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4504 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4505 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4507 return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4508 match_immediate | match_mode_neutral);
4511 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4513 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4514 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4515 return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4519 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4521 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4522 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4523 return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4527 static ir_node *gen_ia32_l_Add(ir_node *node) {
4528 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4529 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4530 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4531 match_commutative | match_am | match_immediate |
4532 match_mode_neutral);
4534 if(is_Proj(lowered)) {
4535 lowered = get_Proj_pred(lowered);
4537 assert(is_ia32_Add(lowered));
4538 set_irn_mode(lowered, mode_T);
4544 static ir_node *gen_ia32_l_Adc(ir_node *node)
4546 return gen_binop_flags(node, new_rd_ia32_Adc,
4547 match_commutative | match_am | match_immediate |
4548 match_mode_neutral);
4552 * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4554 * @param node The node to transform
4555 * @return the created ia32 vfild node
4557 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4558 return gen_lowered_Load(node, new_rd_ia32_vfild);
4562 * Transforms an ia32_l_Load into a "real" ia32_Load node
4564 * @param node The node to transform
4565 * @return the created ia32 Load node
4567 static ir_node *gen_ia32_l_Load(ir_node *node) {
4568 return gen_lowered_Load(node, new_rd_ia32_Load);
4572 * Transforms an ia32_l_Store into a "real" ia32_Store node
4574 * @param node The node to transform
4575 * @return the created ia32 Store node
4577 static ir_node *gen_ia32_l_Store(ir_node *node) {
4578 return gen_lowered_Store(node, new_rd_ia32_Store);
4582 * Transforms a l_vfist into a "real" vfist node.
4584 * @param node The node to transform
4585 * @return the created ia32 vfist node
4587 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4588 ir_node *block = be_transform_node(get_nodes_block(node));
4589 ir_node *ptr = get_irn_n(node, 0);
4590 ir_node *new_ptr = be_transform_node(ptr);
4591 ir_node *val = get_irn_n(node, 1);
4592 ir_node *new_val = be_transform_node(val);
4593 ir_node *mem = get_irn_n(node, 2);
4594 ir_node *new_mem = be_transform_node(mem);
4595 ir_graph *irg = current_ir_graph;
4596 dbg_info *dbgi = get_irn_dbg_info(node);
4597 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4598 ir_mode *mode = get_ia32_ls_mode(node);
4599 ir_node *memres, *fist;
4602 memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
4603 am_offs = get_ia32_am_offs_int(node);
4604 add_ia32_am_offs_int(fist, am_offs);
4606 set_ia32_op_type(fist, ia32_AddrModeD);
4607 set_ia32_ls_mode(fist, mode);
4608 set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
4609 set_ia32_use_frame(fist);
4611 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4617 * Transforms a l_MulS into a "real" MulS node.
4619 * @return the created ia32 Mul node
4621 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4622 ir_node *left = get_binop_left(node);
4623 ir_node *right = get_binop_right(node);
4625 return gen_binop(node, left, right, new_rd_ia32_Mul,
4626 match_commutative | match_am | match_mode_neutral);
4630 * Transforms a l_IMulS into a "real" IMul1OPS node.
4632 * @return the created ia32 IMul1OP node
4634 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4635 ir_node *left = get_binop_left(node);
4636 ir_node *right = get_binop_right(node);
4638 return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4639 match_commutative | match_am | match_mode_neutral);
4642 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4643 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4644 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4645 ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4646 match_am | match_immediate | match_mode_neutral);
4648 if(is_Proj(lowered)) {
4649 lowered = get_Proj_pred(lowered);
4651 assert(is_ia32_Sub(lowered));
4652 set_irn_mode(lowered, mode_T);
4658 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4659 return gen_binop_flags(node, new_rd_ia32_Sbb,
4660 match_am | match_immediate | match_mode_neutral);
4664 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4665 * op1 - target to be shifted
4666 * op2 - contains bits to be shifted into target
4668 * Only op3 can be an immediate.
4670 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4671 ir_node *low, ir_node *count)
4673 ir_node *block = get_nodes_block(node);
4674 ir_node *new_block = be_transform_node(block);
4675 ir_graph *irg = current_ir_graph;
4676 dbg_info *dbgi = get_irn_dbg_info(node);
4677 ir_node *new_high = be_transform_node(high);
4678 ir_node *new_low = be_transform_node(low);
4682 /* the shift amount can be any mode that is bigger than 5 bits, since all
4683 * other bits are ignored anyway */
4684 while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4685 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4686 count = get_Conv_op(count);
4688 new_count = create_immediate_or_transform(count, 0);
4690 if (is_ia32_l_ShlD(node)) {
4691 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4694 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4697 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4702 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4704 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4705 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4706 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4707 return gen_lowered_64bit_shifts(node, high, low, count);
4710 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4712 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4713 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4714 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4715 return gen_lowered_64bit_shifts(node, high, low, count);
4718 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4719 ir_node *src_block = get_nodes_block(node);
4720 ir_node *block = be_transform_node(src_block);
4721 ir_graph *irg = current_ir_graph;
4722 dbg_info *dbgi = get_irn_dbg_info(node);
4723 ir_node *frame = get_irg_frame(irg);
4724 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4725 ir_node *nomem = new_NoMem();
4726 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4727 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4728 ir_node *new_val_low = be_transform_node(val_low);
4729 ir_node *new_val_high = be_transform_node(val_high);
4734 ir_node *store_high;
4736 if(!mode_is_signed(get_irn_mode(val_high))) {
4737 panic("unsigned long long -> float not supported yet (%+F)", node);
4741 store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4743 store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4745 SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4746 SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4748 set_ia32_use_frame(store_low);
4749 set_ia32_use_frame(store_high);
4750 set_ia32_op_type(store_low, ia32_AddrModeD);
4751 set_ia32_op_type(store_high, ia32_AddrModeD);
4752 set_ia32_ls_mode(store_low, mode_Iu);
4753 set_ia32_ls_mode(store_high, mode_Is);
4754 add_ia32_am_offs_int(store_high, 4);
4758 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4761 fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4763 set_ia32_use_frame(fild);
4764 set_ia32_op_type(fild, ia32_AddrModeS);
4765 set_ia32_ls_mode(fild, mode_Ls);
4767 SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4769 return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4772 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4773 ir_node *src_block = get_nodes_block(node);
4774 ir_node *block = be_transform_node(src_block);
4775 ir_graph *irg = current_ir_graph;
4776 dbg_info *dbgi = get_irn_dbg_info(node);
4777 ir_node *frame = get_irg_frame(irg);
4778 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4779 ir_node *nomem = new_NoMem();
4780 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4781 ir_node *new_val = be_transform_node(val);
4782 ir_node *fist, *mem;
4784 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4785 SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4786 set_ia32_use_frame(fist);
4787 set_ia32_op_type(fist, ia32_AddrModeD);
4788 set_ia32_ls_mode(fist, mode_Ls);
4794 * the BAD transformer.
4796 static ir_node *bad_transform(ir_node *node) {
4797 panic("No transform function for %+F available.\n", node);
4801 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4802 ir_graph *irg = current_ir_graph;
4803 ir_node *block = be_transform_node(get_nodes_block(node));
4804 ir_node *pred = get_Proj_pred(node);
4805 ir_node *new_pred = be_transform_node(pred);
4806 ir_node *frame = get_irg_frame(irg);
4807 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4808 dbg_info *dbgi = get_irn_dbg_info(node);
4809 long pn = get_Proj_proj(node);
4814 load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4815 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4816 set_ia32_use_frame(load);
4817 set_ia32_op_type(load, ia32_AddrModeS);
4818 set_ia32_ls_mode(load, mode_Iu);
4819 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4820 * 32 bit from it with this particular load */
4821 attr = get_ia32_attr(load);
4822 attr->data.need_64bit_stackent = 1;
4824 if (pn == pn_ia32_l_FloattoLL_res_high) {
4825 add_ia32_am_offs_int(load, 4);
4827 assert(pn == pn_ia32_l_FloattoLL_res_low);
4830 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4836 * Transform the Projs of an AddSP.
4838 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4839 ir_node *block = be_transform_node(get_nodes_block(node));
4840 ir_node *pred = get_Proj_pred(node);
4841 ir_node *new_pred = be_transform_node(pred);
4842 ir_graph *irg = current_ir_graph;
4843 dbg_info *dbgi = get_irn_dbg_info(node);
4844 long proj = get_Proj_proj(node);
4846 if (proj == pn_be_AddSP_sp) {
4847 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4848 pn_ia32_SubSP_stack);
4849 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4851 } else if(proj == pn_be_AddSP_res) {
4852 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4853 pn_ia32_SubSP_addr);
4854 } else if (proj == pn_be_AddSP_M) {
4855 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4859 return new_rd_Unknown(irg, get_irn_mode(node));
4863 * Transform the Projs of a SubSP.
4865 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4866 ir_node *block = be_transform_node(get_nodes_block(node));
4867 ir_node *pred = get_Proj_pred(node);
4868 ir_node *new_pred = be_transform_node(pred);
4869 ir_graph *irg = current_ir_graph;
4870 dbg_info *dbgi = get_irn_dbg_info(node);
4871 long proj = get_Proj_proj(node);
4873 if (proj == pn_be_SubSP_sp) {
4874 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4875 pn_ia32_AddSP_stack);
4876 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4878 } else if (proj == pn_be_SubSP_M) {
4879 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4883 return new_rd_Unknown(irg, get_irn_mode(node));
4887 * Transform and renumber the Projs from a Load.
4889 static ir_node *gen_Proj_Load(ir_node *node) {
4891 ir_node *block = be_transform_node(get_nodes_block(node));
4892 ir_node *pred = get_Proj_pred(node);
4893 ir_graph *irg = current_ir_graph;
4894 dbg_info *dbgi = get_irn_dbg_info(node);
4895 long proj = get_Proj_proj(node);
4897 /* loads might be part of source address mode matches, so we don't
4898 * transform the ProjMs yet (with the exception of loads whose result is
4901 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4904 /* this is needed, because sometimes we have loops that are only
4905 reachable through the ProjM */
4906 be_enqueue_preds(node);
4907 /* do it in 2 steps, to silence firm verifier */
4908 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4909 set_Proj_proj(res, pn_ia32_mem);
4913 /* renumber the proj */
4914 new_pred = be_transform_node(pred);
4915 if (is_ia32_Load(new_pred)) {
4918 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4920 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4921 case pn_Load_X_regular:
4922 return new_rd_Jmp(dbgi, irg, block);
4923 case pn_Load_X_except:
4924 /* This Load might raise an exception. Mark it. */
4925 set_ia32_exc_label(new_pred, 1);
4926 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4930 } else if (is_ia32_Conv_I2I(new_pred) ||
4931 is_ia32_Conv_I2I8Bit(new_pred)) {
4932 set_irn_mode(new_pred, mode_T);
4933 if (proj == pn_Load_res) {
4934 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4935 } else if (proj == pn_Load_M) {
4936 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4938 } else if (is_ia32_xLoad(new_pred)) {
4941 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4943 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4944 case pn_Load_X_regular:
4945 return new_rd_Jmp(dbgi, irg, block);
4946 case pn_Load_X_except:
4947 /* This Load might raise an exception. Mark it. */
4948 set_ia32_exc_label(new_pred, 1);
4949 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4953 } else if (is_ia32_vfld(new_pred)) {
4956 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4958 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4959 case pn_Load_X_regular:
4960 return new_rd_Jmp(dbgi, irg, block);
4961 case pn_Load_X_except:
4962 /* This Load might raise an exception. Mark it. */
4963 set_ia32_exc_label(new_pred, 1);
4964 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4969 /* can happen for ProJMs when source address mode happened for the
4972 /* however it should not be the result proj, as that would mean the
4973 load had multiple users and should not have been used for
4975 if (proj != pn_Load_M) {
4976 panic("internal error: transformed node not a Load");
4978 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4982 return new_rd_Unknown(irg, get_irn_mode(node));
4986 * Transform and renumber the Projs from a DivMod like instruction.
4988 static ir_node *gen_Proj_DivMod(ir_node *node) {
4989 ir_node *block = be_transform_node(get_nodes_block(node));
4990 ir_node *pred = get_Proj_pred(node);
4991 ir_node *new_pred = be_transform_node(pred);
4992 ir_graph *irg = current_ir_graph;
4993 dbg_info *dbgi = get_irn_dbg_info(node);
4994 ir_mode *mode = get_irn_mode(node);
4995 long proj = get_Proj_proj(node);
4997 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4999 switch (get_irn_opcode(pred)) {
5003 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
5005 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
5006 case pn_Div_X_regular:
5007 return new_rd_Jmp(dbgi, irg, block);
5008 case pn_Div_X_except:
5009 set_ia32_exc_label(new_pred, 1);
5010 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
5018 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
5020 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
5021 case pn_Mod_X_except:
5022 set_ia32_exc_label(new_pred, 1);
5023 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
5031 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
5032 case pn_DivMod_res_div:
5033 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
5034 case pn_DivMod_res_mod:
5035 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
5036 case pn_DivMod_X_regular:
5037 return new_rd_Jmp(dbgi, irg, block);
5038 case pn_DivMod_X_except:
5039 set_ia32_exc_label(new_pred, 1);
5040 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
5050 return new_rd_Unknown(irg, mode);
5054 * Transform and renumber the Projs from a CopyB.
5056 static ir_node *gen_Proj_CopyB(ir_node *node) {
5057 ir_node *block = be_transform_node(get_nodes_block(node));
5058 ir_node *pred = get_Proj_pred(node);
5059 ir_node *new_pred = be_transform_node(pred);
5060 ir_graph *irg = current_ir_graph;
5061 dbg_info *dbgi = get_irn_dbg_info(node);
5062 ir_mode *mode = get_irn_mode(node);
5063 long proj = get_Proj_proj(node);
5066 case pn_CopyB_M_regular:
5067 if (is_ia32_CopyB_i(new_pred)) {
5068 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
5069 } else if (is_ia32_CopyB(new_pred)) {
5070 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
5078 return new_rd_Unknown(irg, mode);
5082 * Transform and renumber the Projs from a Quot.
5084 static ir_node *gen_Proj_Quot(ir_node *node) {
5085 ir_node *block = be_transform_node(get_nodes_block(node));
5086 ir_node *pred = get_Proj_pred(node);
5087 ir_node *new_pred = be_transform_node(pred);
5088 ir_graph *irg = current_ir_graph;
5089 dbg_info *dbgi = get_irn_dbg_info(node);
5090 ir_mode *mode = get_irn_mode(node);
5091 long proj = get_Proj_proj(node);
5095 if (is_ia32_xDiv(new_pred)) {
5096 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
5097 } else if (is_ia32_vfdiv(new_pred)) {
5098 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
5102 if (is_ia32_xDiv(new_pred)) {
5103 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
5104 } else if (is_ia32_vfdiv(new_pred)) {
5105 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
5108 case pn_Quot_X_regular:
5109 case pn_Quot_X_except:
5115 return new_rd_Unknown(irg, mode);
5119 * Transform the Thread Local Storage Proj.
5121 static ir_node *gen_Proj_tls(ir_node *node) {
5122 ir_node *block = be_transform_node(get_nodes_block(node));
5123 ir_graph *irg = current_ir_graph;
5124 dbg_info *dbgi = NULL;
5125 ir_node *res = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
5130 static ir_node *gen_be_Call(ir_node *node) {
5131 ir_node *res = be_duplicate_node(node);
5132 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5137 static ir_node *gen_be_IncSP(ir_node *node) {
5138 ir_node *res = be_duplicate_node(node);
5139 be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5145 * Transform the Projs from a be_Call.
5147 static ir_node *gen_Proj_be_Call(ir_node *node) {
5148 ir_node *block = be_transform_node(get_nodes_block(node));
5149 ir_node *call = get_Proj_pred(node);
5150 ir_node *new_call = be_transform_node(call);
5151 ir_graph *irg = current_ir_graph;
5152 dbg_info *dbgi = get_irn_dbg_info(node);
5153 ir_type *method_type = be_Call_get_type(call);
5154 int n_res = get_method_n_ress(method_type);
5155 long proj = get_Proj_proj(node);
5156 ir_mode *mode = get_irn_mode(node);
5158 const arch_register_class_t *cls;
5160 /* The following is kinda tricky: If we're using SSE, then we have to
5161 * move the result value of the call in floating point registers to an
5162 * xmm register, we therefore construct a GetST0 -> xLoad sequence
5163 * after the call, we have to make sure to correctly make the
5164 * MemProj and the result Proj use these 2 nodes
5166 if (proj == pn_be_Call_M_regular) {
5167 // get new node for result, are we doing the sse load/store hack?
5168 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5169 ir_node *call_res_new;
5170 ir_node *call_res_pred = NULL;
5172 if (call_res != NULL) {
5173 call_res_new = be_transform_node(call_res);
5174 call_res_pred = get_Proj_pred(call_res_new);
5177 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
5178 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5179 pn_be_Call_M_regular);
5181 assert(is_ia32_xLoad(call_res_pred));
5182 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5186 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5187 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5189 ir_node *frame = get_irg_frame(irg);
5190 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
5192 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5195 /* in case there is no memory output: create one to serialize the copy
5197 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5198 pn_be_Call_M_regular);
5199 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5200 pn_be_Call_first_res);
5202 /* store st(0) onto stack */
5203 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
5205 set_ia32_op_type(fstp, ia32_AddrModeD);
5206 set_ia32_use_frame(fstp);
5208 /* load into SSE register */
5209 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5211 set_ia32_op_type(sse_load, ia32_AddrModeS);
5212 set_ia32_use_frame(sse_load);
5214 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5220 /* transform call modes */
5221 if (mode_is_data(mode)) {
5222 cls = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5226 return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5230 * Transform the Projs from a Cmp.
5232 static ir_node *gen_Proj_Cmp(ir_node *node)
5234 /* this probably means not all mode_b nodes were lowered... */
5235 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5240 * Transform the Projs from a Bound.
5242 static ir_node *gen_Proj_Bound(ir_node *node)
5244 ir_node *new_node, *block;
5245 ir_node *pred = get_Proj_pred(node);
5247 switch (get_Proj_proj(node)) {
5249 return be_transform_node(get_Bound_mem(pred));
5250 case pn_Bound_X_regular:
5251 new_node = be_transform_node(pred);
5252 block = get_nodes_block(new_node);
5253 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
5254 case pn_Bound_X_except:
5255 new_node = be_transform_node(pred);
5256 block = get_nodes_block(new_node);
5257 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
5259 return be_transform_node(get_Bound_index(pred));
5261 panic("unsupported Proj from Bound");
5265 static ir_node *gen_Proj_ASM(ir_node *node)
5271 if (get_irn_mode(node) != mode_M)
5272 return be_duplicate_node(node);
5274 pred = get_Proj_pred(node);
5275 new_pred = be_transform_node(pred);
5276 block = get_nodes_block(new_pred);
5277 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
5278 get_ia32_n_res(new_pred) + 1);
5282 * Transform and potentially renumber Proj nodes.
5284 static ir_node *gen_Proj(ir_node *node) {
5285 ir_node *pred = get_Proj_pred(node);
5288 switch (get_irn_opcode(pred)) {
5290 proj = get_Proj_proj(node);
5291 if (proj == pn_Store_M) {
5292 return be_transform_node(pred);
5295 return new_r_Bad(current_ir_graph);
5298 return gen_Proj_Load(node);
5300 return gen_Proj_ASM(node);
5304 return gen_Proj_DivMod(node);
5306 return gen_Proj_CopyB(node);
5308 return gen_Proj_Quot(node);
5310 return gen_Proj_be_SubSP(node);
5312 return gen_Proj_be_AddSP(node);
5314 return gen_Proj_be_Call(node);
5316 return gen_Proj_Cmp(node);
5318 return gen_Proj_Bound(node);
5320 proj = get_Proj_proj(node);
5321 if (proj == pn_Start_X_initial_exec) {
5322 ir_node *block = get_nodes_block(pred);
5323 dbg_info *dbgi = get_irn_dbg_info(node);
5326 /* we exchange the ProjX with a jump */
5327 block = be_transform_node(block);
5328 jump = new_rd_Jmp(dbgi, current_ir_graph, block);
5331 if (node == be_get_old_anchor(anchor_tls)) {
5332 return gen_Proj_tls(node);
5337 if (is_ia32_l_FloattoLL(pred)) {
5338 return gen_Proj_l_FloattoLL(node);
5340 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5344 ir_mode *mode = get_irn_mode(node);
5345 if (ia32_mode_needs_gp_reg(mode)) {
5346 ir_node *new_pred = be_transform_node(pred);
5347 ir_node *block = be_transform_node(get_nodes_block(node));
5348 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5349 mode_Iu, get_Proj_proj(node));
5350 #ifdef DEBUG_libfirm
5351 new_proj->node_nr = node->node_nr;
5357 return be_duplicate_node(node);
5361 * Enters all transform functions into the generic pointer
5363 static void register_transformers(void)
5367 /* first clear the generic function pointer for all ops */
5368 clear_irp_opcodes_generic_func();
5370 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5371 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5410 /* transform ops from intrinsic lowering */
5426 GEN(ia32_l_LLtoFloat);
5427 GEN(ia32_l_FloattoLL);
5433 /* we should never see these nodes */
5448 /* handle generic backend nodes */
5457 op_Mulh = get_op_Mulh();
5466 * Pre-transform all unknown and noreg nodes.
5468 static void ia32_pretransform_node(void *arch_cg) {
5469 ia32_code_gen_t *cg = arch_cg;
5471 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5472 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5473 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5474 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5475 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5476 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5481 * Walker, checks if all ia32 nodes producing more than one result have
5482 * its Projs, otherwise creates new Projs and keep them using a be_Keep node.
5484 static void add_missing_keep_walker(ir_node *node, void *data)
5487 unsigned found_projs = 0;
5488 const ir_edge_t *edge;
5489 ir_mode *mode = get_irn_mode(node);
5494 if(!is_ia32_irn(node))
5497 n_outs = get_ia32_n_res(node);
5500 if(is_ia32_SwitchJmp(node))
5503 assert(n_outs < (int) sizeof(unsigned) * 8);
5504 foreach_out_edge(node, edge) {
5505 ir_node *proj = get_edge_src_irn(edge);
5506 int pn = get_Proj_proj(proj);
5508 if (get_irn_mode(proj) == mode_M)
5511 assert(pn < n_outs);
5512 found_projs |= 1 << pn;
5516 /* are keeps missing? */
5518 for(i = 0; i < n_outs; ++i) {
5521 const arch_register_req_t *req;
5522 const arch_register_class_t *cls;
5524 if(found_projs & (1 << i)) {
5528 req = get_ia32_out_req(node, i);
5533 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
5537 block = get_nodes_block(node);
5538 in[0] = new_r_Proj(current_ir_graph, block, node,
5539 arch_register_class_mode(cls), i);
5540 if(last_keep != NULL) {
5541 be_Keep_add_node(last_keep, cls, in[0]);
5543 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
5544 if(sched_is_scheduled(node)) {
5545 sched_add_after(node, last_keep);
5552 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5555 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5557 ir_graph *irg = be_get_birg_irg(cg->birg);
5558 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5561 /* do the transformation */
5562 void ia32_transform_graph(ia32_code_gen_t *cg) {
5564 ir_graph *irg = cg->irg;
5566 register_transformers();
5568 initial_fpcw = NULL;
5570 BE_TIMER_PUSH(t_heights);
5571 heights = heights_new(irg);
5572 BE_TIMER_POP(t_heights);
5573 ia32_calculate_non_address_mode_nodes(cg->birg);
5575 /* the transform phase is not safe for CSE (yet) because several nodes get
5576 * attributes set after their creation */
5577 cse_last = get_opt_cse();
5580 be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5582 set_opt_cse(cse_last);
5584 ia32_free_non_address_mode_nodes();
5585 heights_free(heights);
5589 void ia32_init_transform(void)
5591 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");