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
34 #include "irgraph_t.h"
39 #include "iredges_t.h"
51 #include "../benode_t.h"
52 #include "../besched.h"
54 #include "../beutil.h"
55 #include "../beirg_t.h"
56 #include "../betranshlp.h"
59 #include "bearch_ia32_t.h"
60 #include "ia32_common_transform.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"
78 #define ULL_BIAS "18446744073709551616"
80 #define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
81 #define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
82 #define ENT_SFP_ABS ".LC_ia32_sfp_abs"
83 #define ENT_DFP_ABS ".LC_ia32_dfp_abs"
84 #define ENT_ULL_BIAS ".LC_ia32_ull_bias"
86 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
87 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
89 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
91 static ir_node *initial_fpcw = NULL;
93 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
94 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
97 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
98 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
101 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
102 ir_node *op1, ir_node *op2);
104 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
105 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
107 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
108 ir_node *base, ir_node *index, ir_node *mem);
110 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
111 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
114 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
116 static ir_node *create_immediate_or_transform(ir_node *node,
117 char immediate_constraint_type);
119 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
120 dbg_info *dbgi, ir_node *block,
121 ir_node *op, ir_node *orig_node);
123 /* its enough to have those once */
124 static ir_node *nomem, *noreg_GP;
126 /** Return non-zero is a node represents the 0 constant. */
127 static bool is_Const_0(ir_node *node)
129 return is_Const(node) && is_Const_null(node);
132 /** Return non-zero is a node represents the 1 constant. */
133 static bool is_Const_1(ir_node *node)
135 return is_Const(node) && is_Const_one(node);
138 /** Return non-zero is a node represents the -1 constant. */
139 static bool is_Const_Minus_1(ir_node *node)
141 return is_Const(node) && is_Const_all_one(node);
145 * returns true if constant can be created with a simple float command
147 static bool is_simple_x87_Const(ir_node *node)
149 tarval *tv = get_Const_tarval(node);
150 if (tarval_is_null(tv) || tarval_is_one(tv))
153 /* TODO: match all the other float constants */
158 * returns true if constant can be created with a simple float command
160 static bool is_simple_sse_Const(ir_node *node)
162 tarval *tv = get_Const_tarval(node);
163 ir_mode *mode = get_tarval_mode(tv);
168 if (tarval_is_null(tv) || tarval_is_one(tv))
171 if (mode == mode_D) {
172 unsigned val = get_tarval_sub_bits(tv, 0) |
173 (get_tarval_sub_bits(tv, 1) << 8) |
174 (get_tarval_sub_bits(tv, 2) << 16) |
175 (get_tarval_sub_bits(tv, 3) << 24);
177 /* lower 32bit are zero, really a 32bit constant */
181 /* TODO: match all the other float constants */
186 * Transforms a Const.
188 static ir_node *gen_Const(ir_node *node)
190 ir_node *old_block = get_nodes_block(node);
191 ir_node *block = be_transform_node(old_block);
192 dbg_info *dbgi = get_irn_dbg_info(node);
193 ir_mode *mode = get_irn_mode(node);
195 assert(is_Const(node));
197 if (mode_is_float(mode)) {
202 if (ia32_cg_config.use_sse2) {
203 tarval *tv = get_Const_tarval(node);
204 if (tarval_is_null(tv)) {
205 load = new_bd_ia32_xZero(dbgi, block);
206 set_ia32_ls_mode(load, mode);
208 } else if (tarval_is_one(tv)) {
209 int cnst = mode == mode_F ? 26 : 55;
210 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
211 ir_node *imm2 = create_Immediate(NULL, 0, 2);
212 ir_node *pslld, *psrld;
214 load = new_bd_ia32_xAllOnes(dbgi, block);
215 set_ia32_ls_mode(load, mode);
216 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
217 set_ia32_ls_mode(pslld, mode);
218 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
219 set_ia32_ls_mode(psrld, mode);
221 } else if (mode == mode_F) {
222 /* we can place any 32bit constant by using a movd gp, sse */
223 unsigned val = get_tarval_sub_bits(tv, 0) |
224 (get_tarval_sub_bits(tv, 1) << 8) |
225 (get_tarval_sub_bits(tv, 2) << 16) |
226 (get_tarval_sub_bits(tv, 3) << 24);
227 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
228 load = new_bd_ia32_xMovd(dbgi, block, cnst);
229 set_ia32_ls_mode(load, mode);
232 if (mode == mode_D) {
233 unsigned val = get_tarval_sub_bits(tv, 0) |
234 (get_tarval_sub_bits(tv, 1) << 8) |
235 (get_tarval_sub_bits(tv, 2) << 16) |
236 (get_tarval_sub_bits(tv, 3) << 24);
238 ir_node *imm32 = create_Immediate(NULL, 0, 32);
239 ir_node *cnst, *psllq;
241 /* fine, lower 32bit are zero, produce 32bit value */
242 val = get_tarval_sub_bits(tv, 4) |
243 (get_tarval_sub_bits(tv, 5) << 8) |
244 (get_tarval_sub_bits(tv, 6) << 16) |
245 (get_tarval_sub_bits(tv, 7) << 24);
246 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
247 load = new_bd_ia32_xMovd(dbgi, block, cnst);
248 set_ia32_ls_mode(load, mode);
249 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
250 set_ia32_ls_mode(psllq, mode);
255 floatent = create_float_const_entity(node);
257 load = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode);
258 set_ia32_op_type(load, ia32_AddrModeS);
259 set_ia32_am_sc(load, floatent);
260 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
261 res = new_r_Proj(current_ir_graph, block, load, mode_xmm, pn_ia32_xLoad_res);
264 if (is_Const_null(node)) {
265 load = new_bd_ia32_vfldz(dbgi, block);
267 set_ia32_ls_mode(load, mode);
268 } else if (is_Const_one(node)) {
269 load = new_bd_ia32_vfld1(dbgi, block);
271 set_ia32_ls_mode(load, mode);
275 floatent = create_float_const_entity(node);
276 /* create_float_const_ent is smart and sometimes creates
278 ls_mode = get_type_mode(get_entity_type(floatent));
280 load = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem,
282 set_ia32_op_type(load, ia32_AddrModeS);
283 set_ia32_am_sc(load, floatent);
284 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
285 res = new_r_Proj(current_ir_graph, block, load, mode_vfp, pn_ia32_vfld_res);
289 SET_IA32_ORIG_NODE(load, node);
291 be_dep_on_frame(load);
293 } else { /* non-float mode */
295 tarval *tv = get_Const_tarval(node);
298 tv = tarval_convert_to(tv, mode_Iu);
300 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
302 panic("couldn't convert constant tarval (%+F)", node);
304 val = get_tarval_long(tv);
306 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
307 SET_IA32_ORIG_NODE(cnst, node);
309 be_dep_on_frame(cnst);
315 * Transforms a SymConst.
317 static ir_node *gen_SymConst(ir_node *node)
319 ir_node *old_block = get_nodes_block(node);
320 ir_node *block = be_transform_node(old_block);
321 dbg_info *dbgi = get_irn_dbg_info(node);
322 ir_mode *mode = get_irn_mode(node);
325 if (mode_is_float(mode)) {
326 if (ia32_cg_config.use_sse2)
327 cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
329 cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
330 set_ia32_am_sc(cnst, get_SymConst_entity(node));
331 set_ia32_use_frame(cnst);
335 if (get_SymConst_kind(node) != symconst_addr_ent) {
336 panic("backend only support symconst_addr_ent (at %+F)", node);
338 entity = get_SymConst_entity(node);
339 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0);
342 SET_IA32_ORIG_NODE(cnst, node);
344 be_dep_on_frame(cnst);
349 * Create a float type for the given mode and cache it.
351 * @param mode the mode for the float type (might be integer mode for SSE2 types)
352 * @param align alignment
354 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align) {
360 if (mode == mode_Iu) {
361 static ir_type *int_Iu[16] = {NULL, };
363 if (int_Iu[align] == NULL) {
364 snprintf(buf, sizeof(buf), "int_Iu_%u", align);
365 int_Iu[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
366 /* set the specified alignment */
367 set_type_alignment_bytes(tp, align);
369 return int_Iu[align];
370 } else if (mode == mode_Lu) {
371 static ir_type *int_Lu[16] = {NULL, };
373 if (int_Lu[align] == NULL) {
374 snprintf(buf, sizeof(buf), "int_Lu_%u", align);
375 int_Lu[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
376 /* set the specified alignment */
377 set_type_alignment_bytes(tp, align);
379 return int_Lu[align];
380 } else if (mode == mode_F) {
381 static ir_type *float_F[16] = {NULL, };
383 if (float_F[align] == NULL) {
384 snprintf(buf, sizeof(buf), "float_F_%u", align);
385 float_F[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
386 /* set the specified alignment */
387 set_type_alignment_bytes(tp, align);
389 return float_F[align];
390 } else if (mode == mode_D) {
391 static ir_type *float_D[16] = {NULL, };
393 if (float_D[align] == NULL) {
394 snprintf(buf, sizeof(buf), "float_D_%u", align);
395 float_D[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
396 /* set the specified alignment */
397 set_type_alignment_bytes(tp, align);
399 return float_D[align];
401 static ir_type *float_E[16] = {NULL, };
403 if (float_E[align] == NULL) {
404 snprintf(buf, sizeof(buf), "float_E_%u", align);
405 float_E[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
406 /* set the specified alignment */
407 set_type_alignment_bytes(tp, align);
409 return float_E[align];
414 * Create a float[2] array type for the given atomic type.
416 * @param tp the atomic type
418 static ir_type *ia32_create_float_array(ir_type *tp) {
420 ir_mode *mode = get_type_mode(tp);
421 unsigned align = get_type_alignment_bytes(tp);
426 if (mode == mode_F) {
427 static ir_type *float_F[16] = {NULL, };
429 if (float_F[align] != NULL)
430 return float_F[align];
431 snprintf(buf, sizeof(buf), "arr_float_F_%u", align);
432 arr = float_F[align] = new_type_array(new_id_from_str(buf), 1, tp);
433 } else if (mode == mode_D) {
434 static ir_type *float_D[16] = {NULL, };
436 if (float_D[align] != NULL)
437 return float_D[align];
438 snprintf(buf, sizeof(buf), "arr_float_D_%u", align);
439 arr = float_D[align] = new_type_array(new_id_from_str(buf), 1, tp);
441 static ir_type *float_E[16] = {NULL, };
443 if (float_E[align] != NULL)
444 return float_E[align];
445 snprintf(buf, sizeof(buf), "arr_float_E_%u", align);
446 arr = float_E[align] = new_type_array(new_id_from_str(buf), 1, tp);
448 set_type_alignment_bytes(arr, align);
449 set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
450 set_type_state(arr, layout_fixed);
454 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
455 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
457 static const struct {
458 const char *ent_name;
459 const char *cnst_str;
462 } names [ia32_known_const_max] = {
463 { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
464 { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
465 { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
466 { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
467 { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
469 static ir_entity *ent_cache[ia32_known_const_max];
471 const char *ent_name, *cnst_str;
477 ent_name = names[kct].ent_name;
478 if (! ent_cache[kct]) {
479 cnst_str = names[kct].cnst_str;
481 switch (names[kct].mode) {
482 case 0: mode = mode_Iu; break;
483 case 1: mode = mode_Lu; break;
484 default: mode = mode_F; break;
486 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
487 tp = ia32_create_float_type(mode, names[kct].align);
489 if (kct == ia32_ULLBIAS)
490 tp = ia32_create_float_array(tp);
491 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
493 set_entity_ld_ident(ent, get_entity_ident(ent));
494 set_entity_visibility(ent, visibility_local);
495 set_entity_variability(ent, variability_constant);
496 set_entity_allocation(ent, allocation_static);
498 if (kct == ia32_ULLBIAS) {
499 ir_initializer_t *initializer = create_initializer_compound(2);
501 set_initializer_compound_value(initializer, 0,
502 create_initializer_tarval(get_tarval_null(mode)));
503 set_initializer_compound_value(initializer, 1,
504 create_initializer_tarval(tv));
506 set_entity_initializer(ent, initializer);
508 set_entity_initializer(ent, create_initializer_tarval(tv));
511 /* cache the entry */
512 ent_cache[kct] = ent;
515 return ent_cache[kct];
519 * return true if the node is a Proj(Load) and could be used in source address
520 * mode for another node. Will return only true if the @p other node is not
521 * dependent on the memory of the Load (for binary operations use the other
522 * input here, for unary operations use NULL).
524 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
525 ir_node *other, ir_node *other2, match_flags_t flags)
530 /* float constants are always available */
531 if (is_Const(node)) {
532 ir_mode *mode = get_irn_mode(node);
533 if (mode_is_float(mode)) {
534 if (ia32_cg_config.use_sse2) {
535 if (is_simple_sse_Const(node))
538 if (is_simple_x87_Const(node))
541 if (get_irn_n_edges(node) > 1)
549 load = get_Proj_pred(node);
550 pn = get_Proj_proj(node);
551 if (!is_Load(load) || pn != pn_Load_res)
553 if (get_nodes_block(load) != block)
555 /* we only use address mode if we're the only user of the load */
556 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
558 /* in some edge cases with address mode we might reach the load normally
559 * and through some AM sequence, if it is already materialized then we
560 * can't create an AM node from it */
561 if (be_is_transformed(node))
564 /* don't do AM if other node inputs depend on the load (via mem-proj) */
565 if (other != NULL && prevents_AM(block, load, other))
568 if (other2 != NULL && prevents_AM(block, load, other2))
574 typedef struct ia32_address_mode_t ia32_address_mode_t;
575 struct ia32_address_mode_t {
580 ia32_op_type_t op_type;
584 unsigned commutative : 1;
585 unsigned ins_permuted : 1;
588 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
590 /* construct load address */
591 memset(addr, 0, sizeof(addr[0]));
592 ia32_create_address_mode(addr, ptr, 0);
594 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
595 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
596 addr->mem = be_transform_node(mem);
599 static void build_address(ia32_address_mode_t *am, ir_node *node,
600 ia32_create_am_flags_t flags)
602 ia32_address_t *addr = &am->addr;
608 if (is_Const(node)) {
609 ir_entity *entity = create_float_const_entity(node);
610 addr->base = noreg_GP;
611 addr->index = noreg_GP;
613 addr->symconst_ent = entity;
615 am->ls_mode = get_type_mode(get_entity_type(entity));
616 am->pinned = op_pin_state_floats;
620 load = get_Proj_pred(node);
621 ptr = get_Load_ptr(load);
622 mem = get_Load_mem(load);
623 new_mem = be_transform_node(mem);
624 am->pinned = get_irn_pinned(load);
625 am->ls_mode = get_Load_mode(load);
626 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
629 /* construct load address */
630 ia32_create_address_mode(addr, ptr, flags);
632 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
633 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
637 static void set_address(ir_node *node, const ia32_address_t *addr)
639 set_ia32_am_scale(node, addr->scale);
640 set_ia32_am_sc(node, addr->symconst_ent);
641 set_ia32_am_offs_int(node, addr->offset);
642 if (addr->symconst_sign)
643 set_ia32_am_sc_sign(node);
645 set_ia32_use_frame(node);
646 set_ia32_frame_ent(node, addr->frame_entity);
650 * Apply attributes of a given address mode to a node.
652 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
654 set_address(node, &am->addr);
656 set_ia32_op_type(node, am->op_type);
657 set_ia32_ls_mode(node, am->ls_mode);
658 if (am->pinned == op_pin_state_pinned) {
659 /* beware: some nodes are already pinned and did not allow to change the state */
660 if (get_irn_pinned(node) != op_pin_state_pinned)
661 set_irn_pinned(node, op_pin_state_pinned);
664 set_ia32_commutative(node);
668 * Check, if a given node is a Down-Conv, ie. a integer Conv
669 * from a mode with a mode with more bits to a mode with lesser bits.
670 * Moreover, we return only true if the node has not more than 1 user.
672 * @param node the node
673 * @return non-zero if node is a Down-Conv
675 static int is_downconv(const ir_node *node)
683 /* we only want to skip the conv when we're the only user
684 * (not optimal but for now...)
686 if (get_irn_n_edges(node) > 1)
689 src_mode = get_irn_mode(get_Conv_op(node));
690 dest_mode = get_irn_mode(node);
692 ia32_mode_needs_gp_reg(src_mode) &&
693 ia32_mode_needs_gp_reg(dest_mode) &&
694 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
697 /* Skip all Down-Conv's on a given node and return the resulting node. */
698 ir_node *ia32_skip_downconv(ir_node *node)
700 while (is_downconv(node))
701 node = get_Conv_op(node);
706 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
708 ir_mode *mode = get_irn_mode(node);
713 if (mode_is_signed(mode)) {
718 block = get_nodes_block(node);
719 dbgi = get_irn_dbg_info(node);
721 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
725 * matches operands of a node into ia32 addressing/operand modes. This covers
726 * usage of source address mode, immediates, operations with non 32-bit modes,
728 * The resulting data is filled into the @p am struct. block is the block
729 * of the node whose arguments are matched. op1, op2 are the first and second
730 * input that are matched (op1 may be NULL). other_op is another unrelated
731 * input that is not matched! but which is needed sometimes to check if AM
732 * for op1/op2 is legal.
733 * @p flags describes the supported modes of the operation in detail.
735 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
736 ir_node *op1, ir_node *op2, ir_node *other_op,
739 ia32_address_t *addr = &am->addr;
740 ir_mode *mode = get_irn_mode(op2);
741 int mode_bits = get_mode_size_bits(mode);
742 ir_node *new_op1, *new_op2;
744 unsigned commutative;
745 int use_am_and_immediates;
748 memset(am, 0, sizeof(am[0]));
750 commutative = (flags & match_commutative) != 0;
751 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
752 use_am = (flags & match_am) != 0;
753 use_immediate = (flags & match_immediate) != 0;
754 assert(!use_am_and_immediates || use_immediate);
757 assert(!commutative || op1 != NULL);
758 assert(use_am || !(flags & match_8bit_am));
759 assert(use_am || !(flags & match_16bit_am));
761 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
762 (mode_bits == 16 && !(flags & match_16bit_am))) {
766 /* we can simply skip downconvs for mode neutral nodes: the upper bits
767 * can be random for these operations */
768 if (flags & match_mode_neutral) {
769 op2 = ia32_skip_downconv(op2);
771 op1 = ia32_skip_downconv(op1);
775 /* match immediates. firm nodes are normalized: constants are always on the
778 if (!(flags & match_try_am) && use_immediate) {
779 new_op2 = try_create_Immediate(op2, 0);
782 if (new_op2 == NULL &&
783 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
784 build_address(am, op2, 0);
785 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
786 if (mode_is_float(mode)) {
787 new_op2 = ia32_new_NoReg_vfp(env_cg);
791 am->op_type = ia32_AddrModeS;
792 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
794 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
796 build_address(am, op1, 0);
798 if (mode_is_float(mode)) {
799 noreg = ia32_new_NoReg_vfp(env_cg);
804 if (new_op2 != NULL) {
807 new_op1 = be_transform_node(op2);
809 am->ins_permuted = 1;
811 am->op_type = ia32_AddrModeS;
813 am->op_type = ia32_Normal;
815 if (flags & match_try_am) {
821 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
823 new_op2 = be_transform_node(op2);
825 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
827 if (addr->base == NULL)
828 addr->base = noreg_GP;
829 if (addr->index == NULL)
830 addr->index = noreg_GP;
831 if (addr->mem == NULL)
834 am->new_op1 = new_op1;
835 am->new_op2 = new_op2;
836 am->commutative = commutative;
839 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
844 if (am->mem_proj == NULL)
847 /* we have to create a mode_T so the old MemProj can attach to us */
848 mode = get_irn_mode(node);
849 load = get_Proj_pred(am->mem_proj);
851 be_set_transformed_node(load, node);
853 if (mode != mode_T) {
854 set_irn_mode(node, mode_T);
855 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
862 * Construct a standard binary operation, set AM and immediate if required.
864 * @param node The original node for which the binop is created
865 * @param op1 The first operand
866 * @param op2 The second operand
867 * @param func The node constructor function
868 * @return The constructed ia32 node.
870 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
871 construct_binop_func *func, match_flags_t flags)
874 ir_node *block, *new_block, *new_node;
875 ia32_address_mode_t am;
876 ia32_address_t *addr = &am.addr;
878 block = get_nodes_block(node);
879 match_arguments(&am, block, op1, op2, NULL, flags);
881 dbgi = get_irn_dbg_info(node);
882 new_block = be_transform_node(block);
883 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
884 am.new_op1, am.new_op2);
885 set_am_attributes(new_node, &am);
886 /* we can't use source address mode anymore when using immediates */
887 if (!(flags & match_am_and_immediates) &&
888 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
889 set_ia32_am_support(new_node, ia32_am_none);
890 SET_IA32_ORIG_NODE(new_node, node);
892 new_node = fix_mem_proj(new_node, &am);
899 n_ia32_l_binop_right,
900 n_ia32_l_binop_eflags
902 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
903 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
904 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
905 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
906 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
907 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
910 * Construct a binary operation which also consumes the eflags.
912 * @param node The node to transform
913 * @param func The node constructor function
914 * @param flags The match flags
915 * @return The constructor ia32 node
917 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
920 ir_node *src_block = get_nodes_block(node);
921 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
922 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
923 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
925 ir_node *block, *new_node, *new_eflags;
926 ia32_address_mode_t am;
927 ia32_address_t *addr = &am.addr;
929 match_arguments(&am, src_block, op1, op2, eflags, flags);
931 dbgi = get_irn_dbg_info(node);
932 block = be_transform_node(src_block);
933 new_eflags = be_transform_node(eflags);
934 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
935 am.new_op1, am.new_op2, new_eflags);
936 set_am_attributes(new_node, &am);
937 /* we can't use source address mode anymore when using immediates */
938 if (!(flags & match_am_and_immediates) &&
939 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
940 set_ia32_am_support(new_node, ia32_am_none);
941 SET_IA32_ORIG_NODE(new_node, node);
943 new_node = fix_mem_proj(new_node, &am);
948 static ir_node *get_fpcw(void)
951 if (initial_fpcw != NULL)
954 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
955 &ia32_fp_cw_regs[REG_FPCW]);
956 initial_fpcw = be_transform_node(fpcw);
962 * Construct a standard binary operation, set AM and immediate if required.
964 * @param op1 The first operand
965 * @param op2 The second operand
966 * @param func The node constructor function
967 * @return The constructed ia32 node.
969 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
970 construct_binop_float_func *func)
972 ir_mode *mode = get_irn_mode(node);
974 ir_node *block, *new_block, *new_node;
975 ia32_address_mode_t am;
976 ia32_address_t *addr = &am.addr;
977 ia32_x87_attr_t *attr;
978 /* All operations are considered commutative, because there are reverse
980 match_flags_t flags = match_commutative;
982 /* cannot use address mode with long double on x87 */
983 if (get_mode_size_bits(mode) <= 64)
986 block = get_nodes_block(node);
987 match_arguments(&am, block, op1, op2, NULL, flags);
989 dbgi = get_irn_dbg_info(node);
990 new_block = be_transform_node(block);
991 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
992 am.new_op1, am.new_op2, get_fpcw());
993 set_am_attributes(new_node, &am);
995 attr = get_ia32_x87_attr(new_node);
996 attr->attr.data.ins_permuted = am.ins_permuted;
998 SET_IA32_ORIG_NODE(new_node, node);
1000 new_node = fix_mem_proj(new_node, &am);
1006 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1008 * @param op1 The first operand
1009 * @param op2 The second operand
1010 * @param func The node constructor function
1011 * @return The constructed ia32 node.
1013 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1014 construct_shift_func *func,
1015 match_flags_t flags)
1018 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1020 assert(! mode_is_float(get_irn_mode(node)));
1021 assert(flags & match_immediate);
1022 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1024 if (flags & match_mode_neutral) {
1025 op1 = ia32_skip_downconv(op1);
1026 new_op1 = be_transform_node(op1);
1027 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1028 new_op1 = create_upconv(op1, node);
1030 new_op1 = be_transform_node(op1);
1033 /* the shift amount can be any mode that is bigger than 5 bits, since all
1034 * other bits are ignored anyway */
1035 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1036 ir_node *const op = get_Conv_op(op2);
1037 if (mode_is_float(get_irn_mode(op)))
1040 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1042 new_op2 = create_immediate_or_transform(op2, 0);
1044 dbgi = get_irn_dbg_info(node);
1045 block = get_nodes_block(node);
1046 new_block = be_transform_node(block);
1047 new_node = func(dbgi, new_block, new_op1, new_op2);
1048 SET_IA32_ORIG_NODE(new_node, node);
1050 /* lowered shift instruction may have a dependency operand, handle it here */
1051 if (get_irn_arity(node) == 3) {
1052 /* we have a dependency */
1053 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1054 add_irn_dep(new_node, new_dep);
1062 * Construct a standard unary operation, set AM and immediate if required.
1064 * @param op The operand
1065 * @param func The node constructor function
1066 * @return The constructed ia32 node.
1068 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1069 match_flags_t flags)
1072 ir_node *block, *new_block, *new_op, *new_node;
1074 assert(flags == 0 || flags == match_mode_neutral);
1075 if (flags & match_mode_neutral) {
1076 op = ia32_skip_downconv(op);
1079 new_op = be_transform_node(op);
1080 dbgi = get_irn_dbg_info(node);
1081 block = get_nodes_block(node);
1082 new_block = be_transform_node(block);
1083 new_node = func(dbgi, new_block, new_op);
1085 SET_IA32_ORIG_NODE(new_node, node);
1090 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1091 ia32_address_t *addr)
1093 ir_node *base, *index, *res;
1099 base = be_transform_node(base);
1102 index = addr->index;
1103 if (index == NULL) {
1106 index = be_transform_node(index);
1109 res = new_bd_ia32_Lea(dbgi, block, base, index);
1110 set_address(res, addr);
1116 * Returns non-zero if a given address mode has a symbolic or
1117 * numerical offset != 0.
1119 static int am_has_immediates(const ia32_address_t *addr)
1121 return addr->offset != 0 || addr->symconst_ent != NULL
1122 || addr->frame_entity || addr->use_frame;
1126 * Creates an ia32 Add.
1128 * @return the created ia32 Add node
1130 static ir_node *gen_Add(ir_node *node)
1132 ir_mode *mode = get_irn_mode(node);
1133 ir_node *op1 = get_Add_left(node);
1134 ir_node *op2 = get_Add_right(node);
1136 ir_node *block, *new_block, *new_node, *add_immediate_op;
1137 ia32_address_t addr;
1138 ia32_address_mode_t am;
1140 if (mode_is_float(mode)) {
1141 if (ia32_cg_config.use_sse2)
1142 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1143 match_commutative | match_am);
1145 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1148 ia32_mark_non_am(node);
1150 op2 = ia32_skip_downconv(op2);
1151 op1 = ia32_skip_downconv(op1);
1155 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1156 * 1. Add with immediate -> Lea
1157 * 2. Add with possible source address mode -> Add
1158 * 3. Otherwise -> Lea
1160 memset(&addr, 0, sizeof(addr));
1161 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1162 add_immediate_op = NULL;
1164 dbgi = get_irn_dbg_info(node);
1165 block = get_nodes_block(node);
1166 new_block = be_transform_node(block);
1169 if (addr.base == NULL && addr.index == NULL) {
1170 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1171 addr.symconst_sign, addr.offset);
1172 be_dep_on_frame(new_node);
1173 SET_IA32_ORIG_NODE(new_node, node);
1176 /* add with immediate? */
1177 if (addr.index == NULL) {
1178 add_immediate_op = addr.base;
1179 } else if (addr.base == NULL && addr.scale == 0) {
1180 add_immediate_op = addr.index;
1183 if (add_immediate_op != NULL) {
1184 if (!am_has_immediates(&addr)) {
1185 #ifdef DEBUG_libfirm
1186 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1189 return be_transform_node(add_immediate_op);
1192 new_node = create_lea_from_address(dbgi, new_block, &addr);
1193 SET_IA32_ORIG_NODE(new_node, node);
1197 /* test if we can use source address mode */
1198 match_arguments(&am, block, op1, op2, NULL, match_commutative
1199 | match_mode_neutral | match_am | match_immediate | match_try_am);
1201 /* construct an Add with source address mode */
1202 if (am.op_type == ia32_AddrModeS) {
1203 ia32_address_t *am_addr = &am.addr;
1204 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1205 am_addr->index, am_addr->mem, am.new_op1,
1207 set_am_attributes(new_node, &am);
1208 SET_IA32_ORIG_NODE(new_node, node);
1210 new_node = fix_mem_proj(new_node, &am);
1215 /* otherwise construct a lea */
1216 new_node = create_lea_from_address(dbgi, new_block, &addr);
1217 SET_IA32_ORIG_NODE(new_node, node);
1222 * Creates an ia32 Mul.
1224 * @return the created ia32 Mul node
1226 static ir_node *gen_Mul(ir_node *node)
1228 ir_node *op1 = get_Mul_left(node);
1229 ir_node *op2 = get_Mul_right(node);
1230 ir_mode *mode = get_irn_mode(node);
1232 if (mode_is_float(mode)) {
1233 if (ia32_cg_config.use_sse2)
1234 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1235 match_commutative | match_am);
1237 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1239 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1240 match_commutative | match_am | match_mode_neutral |
1241 match_immediate | match_am_and_immediates);
1245 * Creates an ia32 Mulh.
1246 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1247 * this result while Mul returns the lower 32 bit.
1249 * @return the created ia32 Mulh node
1251 static ir_node *gen_Mulh(ir_node *node)
1253 ir_node *block = get_nodes_block(node);
1254 ir_node *new_block = be_transform_node(block);
1255 dbg_info *dbgi = get_irn_dbg_info(node);
1256 ir_node *op1 = get_Mulh_left(node);
1257 ir_node *op2 = get_Mulh_right(node);
1258 ir_mode *mode = get_irn_mode(node);
1260 ir_node *proj_res_high;
1262 if (mode_is_signed(mode)) {
1263 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1264 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1265 mode_Iu, pn_ia32_IMul1OP_res_high);
1267 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1268 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1269 mode_Iu, pn_ia32_Mul_res_high);
1271 return proj_res_high;
1275 * Creates an ia32 And.
1277 * @return The created ia32 And node
1279 static ir_node *gen_And(ir_node *node)
1281 ir_node *op1 = get_And_left(node);
1282 ir_node *op2 = get_And_right(node);
1283 assert(! mode_is_float(get_irn_mode(node)));
1285 /* is it a zero extension? */
1286 if (is_Const(op2)) {
1287 tarval *tv = get_Const_tarval(op2);
1288 long v = get_tarval_long(tv);
1290 if (v == 0xFF || v == 0xFFFF) {
1291 dbg_info *dbgi = get_irn_dbg_info(node);
1292 ir_node *block = get_nodes_block(node);
1299 assert(v == 0xFFFF);
1302 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1307 return gen_binop(node, op1, op2, new_bd_ia32_And,
1308 match_commutative | match_mode_neutral | match_am | match_immediate);
1314 * Creates an ia32 Or.
1316 * @return The created ia32 Or node
1318 static ir_node *gen_Or(ir_node *node)
1320 ir_node *op1 = get_Or_left(node);
1321 ir_node *op2 = get_Or_right(node);
1323 assert (! mode_is_float(get_irn_mode(node)));
1324 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1325 | match_mode_neutral | match_am | match_immediate);
1331 * Creates an ia32 Eor.
1333 * @return The created ia32 Eor node
1335 static ir_node *gen_Eor(ir_node *node)
1337 ir_node *op1 = get_Eor_left(node);
1338 ir_node *op2 = get_Eor_right(node);
1340 assert(! mode_is_float(get_irn_mode(node)));
1341 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1342 | match_mode_neutral | match_am | match_immediate);
1347 * Creates an ia32 Sub.
1349 * @return The created ia32 Sub node
1351 static ir_node *gen_Sub(ir_node *node)
1353 ir_node *op1 = get_Sub_left(node);
1354 ir_node *op2 = get_Sub_right(node);
1355 ir_mode *mode = get_irn_mode(node);
1357 if (mode_is_float(mode)) {
1358 if (ia32_cg_config.use_sse2)
1359 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1361 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1364 if (is_Const(op2)) {
1365 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1369 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1370 | match_am | match_immediate);
1373 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1374 ir_node *const src_val,
1375 ir_node *const src_mem,
1376 ir_node *const am_mem)
1378 if (is_NoMem(am_mem)) {
1379 return be_transform_node(src_mem);
1380 } else if (is_Proj(src_val) &&
1382 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1383 /* avoid memory loop */
1385 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1386 ir_node *const ptr_pred = get_Proj_pred(src_val);
1387 int const arity = get_Sync_n_preds(src_mem);
1392 NEW_ARR_A(ir_node*, ins, arity + 1);
1394 /* NOTE: This sometimes produces dead-code because the old sync in
1395 * src_mem might not be used anymore, we should detect this case
1396 * and kill the sync... */
1397 for (i = arity - 1; i >= 0; --i) {
1398 ir_node *const pred = get_Sync_pred(src_mem, i);
1400 /* avoid memory loop */
1401 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1404 ins[n++] = be_transform_node(pred);
1409 return new_r_Sync(irg, block, n, ins);
1413 ins[0] = be_transform_node(src_mem);
1415 return new_r_Sync(irg, block, 2, ins);
1419 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1420 ir_node *val, const ir_node *orig)
1425 if (ia32_cg_config.use_short_sex_eax) {
1426 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1427 be_dep_on_frame(pval);
1428 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1430 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1431 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1433 SET_IA32_ORIG_NODE(res, orig);
1438 * Generates an ia32 DivMod with additional infrastructure for the
1439 * register allocator if needed.
1441 static ir_node *create_Div(ir_node *node)
1443 dbg_info *dbgi = get_irn_dbg_info(node);
1444 ir_node *block = get_nodes_block(node);
1445 ir_node *new_block = be_transform_node(block);
1452 ir_node *sign_extension;
1453 ia32_address_mode_t am;
1454 ia32_address_t *addr = &am.addr;
1456 /* the upper bits have random contents for smaller modes */
1457 switch (get_irn_opcode(node)) {
1459 op1 = get_Div_left(node);
1460 op2 = get_Div_right(node);
1461 mem = get_Div_mem(node);
1462 mode = get_Div_resmode(node);
1465 op1 = get_Mod_left(node);
1466 op2 = get_Mod_right(node);
1467 mem = get_Mod_mem(node);
1468 mode = get_Mod_resmode(node);
1471 op1 = get_DivMod_left(node);
1472 op2 = get_DivMod_right(node);
1473 mem = get_DivMod_mem(node);
1474 mode = get_DivMod_resmode(node);
1477 panic("invalid divmod node %+F", node);
1480 match_arguments(&am, block, op1, op2, NULL, match_am);
1482 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1483 is the memory of the consumed address. We can have only the second op as address
1484 in Div nodes, so check only op2. */
1485 new_mem = transform_AM_mem(current_ir_graph, block, op2, mem, addr->mem);
1487 if (mode_is_signed(mode)) {
1488 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1489 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1490 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1492 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0);
1493 be_dep_on_frame(sign_extension);
1495 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1496 addr->index, new_mem, am.new_op2,
1497 am.new_op1, sign_extension);
1500 set_irn_pinned(new_node, get_irn_pinned(node));
1502 set_am_attributes(new_node, &am);
1503 SET_IA32_ORIG_NODE(new_node, node);
1505 new_node = fix_mem_proj(new_node, &am);
1511 static ir_node *gen_Mod(ir_node *node)
1513 return create_Div(node);
1516 static ir_node *gen_Div(ir_node *node)
1518 return create_Div(node);
1521 static ir_node *gen_DivMod(ir_node *node)
1523 return create_Div(node);
1529 * Creates an ia32 floating Div.
1531 * @return The created ia32 xDiv node
1533 static ir_node *gen_Quot(ir_node *node)
1535 ir_node *op1 = get_Quot_left(node);
1536 ir_node *op2 = get_Quot_right(node);
1538 if (ia32_cg_config.use_sse2) {
1539 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1541 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1547 * Creates an ia32 Shl.
1549 * @return The created ia32 Shl node
1551 static ir_node *gen_Shl(ir_node *node)
1553 ir_node *left = get_Shl_left(node);
1554 ir_node *right = get_Shl_right(node);
1556 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1557 match_mode_neutral | match_immediate);
1561 * Creates an ia32 Shr.
1563 * @return The created ia32 Shr node
1565 static ir_node *gen_Shr(ir_node *node)
1567 ir_node *left = get_Shr_left(node);
1568 ir_node *right = get_Shr_right(node);
1570 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1576 * Creates an ia32 Sar.
1578 * @return The created ia32 Shrs node
1580 static ir_node *gen_Shrs(ir_node *node)
1582 ir_node *left = get_Shrs_left(node);
1583 ir_node *right = get_Shrs_right(node);
1585 if (is_Const(right)) {
1586 tarval *tv = get_Const_tarval(right);
1587 long val = get_tarval_long(tv);
1589 /* this is a sign extension */
1590 dbg_info *dbgi = get_irn_dbg_info(node);
1591 ir_node *block = be_transform_node(get_nodes_block(node));
1592 ir_node *new_op = be_transform_node(left);
1594 return create_sex_32_64(dbgi, block, new_op, node);
1598 /* 8 or 16 bit sign extension? */
1599 if (is_Const(right) && is_Shl(left)) {
1600 ir_node *shl_left = get_Shl_left(left);
1601 ir_node *shl_right = get_Shl_right(left);
1602 if (is_Const(shl_right)) {
1603 tarval *tv1 = get_Const_tarval(right);
1604 tarval *tv2 = get_Const_tarval(shl_right);
1605 if (tv1 == tv2 && tarval_is_long(tv1)) {
1606 long val = get_tarval_long(tv1);
1607 if (val == 16 || val == 24) {
1608 dbg_info *dbgi = get_irn_dbg_info(node);
1609 ir_node *block = get_nodes_block(node);
1619 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1628 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1634 * Creates an ia32 Rol.
1636 * @param op1 The first operator
1637 * @param op2 The second operator
1638 * @return The created ia32 RotL node
1640 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1642 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1648 * Creates an ia32 Ror.
1649 * NOTE: There is no RotR with immediate because this would always be a RotL
1650 * "imm-mode_size_bits" which can be pre-calculated.
1652 * @param op1 The first operator
1653 * @param op2 The second operator
1654 * @return The created ia32 RotR node
1656 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1658 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1664 * Creates an ia32 RotR or RotL (depending on the found pattern).
1666 * @return The created ia32 RotL or RotR node
1668 static ir_node *gen_Rotl(ir_node *node)
1670 ir_node *rotate = NULL;
1671 ir_node *op1 = get_Rotl_left(node);
1672 ir_node *op2 = get_Rotl_right(node);
1674 /* Firm has only RotL, so we are looking for a right (op2)
1675 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1676 that means we can create a RotR instead of an Add and a RotL */
1680 ir_node *left = get_Add_left(add);
1681 ir_node *right = get_Add_right(add);
1682 if (is_Const(right)) {
1683 tarval *tv = get_Const_tarval(right);
1684 ir_mode *mode = get_irn_mode(node);
1685 long bits = get_mode_size_bits(mode);
1687 if (is_Minus(left) &&
1688 tarval_is_long(tv) &&
1689 get_tarval_long(tv) == bits &&
1692 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1693 rotate = gen_Ror(node, op1, get_Minus_op(left));
1698 if (rotate == NULL) {
1699 rotate = gen_Rol(node, op1, op2);
1708 * Transforms a Minus node.
1710 * @return The created ia32 Minus node
1712 static ir_node *gen_Minus(ir_node *node)
1714 ir_node *op = get_Minus_op(node);
1715 ir_node *block = be_transform_node(get_nodes_block(node));
1716 dbg_info *dbgi = get_irn_dbg_info(node);
1717 ir_mode *mode = get_irn_mode(node);
1722 if (mode_is_float(mode)) {
1723 ir_node *new_op = be_transform_node(op);
1724 if (ia32_cg_config.use_sse2) {
1725 /* TODO: non-optimal... if we have many xXors, then we should
1726 * rather create a load for the const and use that instead of
1727 * several AM nodes... */
1728 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1730 new_node = new_bd_ia32_xXor(dbgi, block, noreg_GP, noreg_GP,
1731 nomem, new_op, noreg_xmm);
1733 size = get_mode_size_bits(mode);
1734 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1736 set_ia32_am_sc(new_node, ent);
1737 set_ia32_op_type(new_node, ia32_AddrModeS);
1738 set_ia32_ls_mode(new_node, mode);
1740 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1743 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1746 SET_IA32_ORIG_NODE(new_node, node);
1752 * Transforms a Not node.
1754 * @return The created ia32 Not node
1756 static ir_node *gen_Not(ir_node *node)
1758 ir_node *op = get_Not_op(node);
1760 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1761 assert (! mode_is_float(get_irn_mode(node)));
1763 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1769 * Transforms an Abs node.
1771 * @return The created ia32 Abs node
1773 static ir_node *gen_Abs(ir_node *node)
1775 ir_node *block = get_nodes_block(node);
1776 ir_node *new_block = be_transform_node(block);
1777 ir_node *op = get_Abs_op(node);
1778 dbg_info *dbgi = get_irn_dbg_info(node);
1779 ir_mode *mode = get_irn_mode(node);
1785 if (mode_is_float(mode)) {
1786 new_op = be_transform_node(op);
1788 if (ia32_cg_config.use_sse2) {
1789 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1790 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_GP, noreg_GP,
1791 nomem, new_op, noreg_fp);
1793 size = get_mode_size_bits(mode);
1794 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1796 set_ia32_am_sc(new_node, ent);
1798 SET_IA32_ORIG_NODE(new_node, node);
1800 set_ia32_op_type(new_node, ia32_AddrModeS);
1801 set_ia32_ls_mode(new_node, mode);
1803 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1804 SET_IA32_ORIG_NODE(new_node, node);
1807 ir_node *xor, *sign_extension;
1809 if (get_mode_size_bits(mode) == 32) {
1810 new_op = be_transform_node(op);
1812 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1815 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1817 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1818 nomem, new_op, sign_extension);
1819 SET_IA32_ORIG_NODE(xor, node);
1821 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1822 nomem, xor, sign_extension);
1823 SET_IA32_ORIG_NODE(new_node, node);
1830 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1832 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1834 dbg_info *dbgi = get_irn_dbg_info(cmp);
1835 ir_node *block = get_nodes_block(cmp);
1836 ir_node *new_block = be_transform_node(block);
1837 ir_node *op1 = be_transform_node(x);
1838 ir_node *op2 = be_transform_node(n);
1840 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1844 * Transform a node returning a "flag" result.
1846 * @param node the node to transform
1847 * @param pnc_out the compare mode to use
1849 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1856 /* we have a Cmp as input */
1857 if (is_Proj(node)) {
1858 ir_node *pred = get_Proj_pred(node);
1860 pn_Cmp pnc = get_Proj_proj(node);
1861 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1862 ir_node *l = get_Cmp_left(pred);
1863 ir_node *r = get_Cmp_right(pred);
1865 ir_node *la = get_And_left(l);
1866 ir_node *ra = get_And_right(l);
1868 ir_node *c = get_Shl_left(la);
1869 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1870 /* (1 << n) & ra) */
1871 ir_node *n = get_Shl_right(la);
1872 flags = gen_bt(pred, ra, n);
1873 /* we must generate a Jc/Jnc jump */
1874 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1877 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1882 ir_node *c = get_Shl_left(ra);
1883 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1884 /* la & (1 << n)) */
1885 ir_node *n = get_Shl_right(ra);
1886 flags = gen_bt(pred, la, n);
1887 /* we must generate a Jc/Jnc jump */
1888 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1891 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1897 flags = be_transform_node(pred);
1903 /* a mode_b value, we have to compare it against 0 */
1904 dbgi = get_irn_dbg_info(node);
1905 new_block = be_transform_node(get_nodes_block(node));
1906 new_op = be_transform_node(node);
1907 flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op,
1908 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1909 *pnc_out = pn_Cmp_Lg;
1914 * Transforms a Load.
1916 * @return the created ia32 Load node
1918 static ir_node *gen_Load(ir_node *node)
1920 ir_node *old_block = get_nodes_block(node);
1921 ir_node *block = be_transform_node(old_block);
1922 ir_node *ptr = get_Load_ptr(node);
1923 ir_node *mem = get_Load_mem(node);
1924 ir_node *new_mem = be_transform_node(mem);
1927 dbg_info *dbgi = get_irn_dbg_info(node);
1928 ir_mode *mode = get_Load_mode(node);
1931 ia32_address_t addr;
1933 /* construct load address */
1934 memset(&addr, 0, sizeof(addr));
1935 ia32_create_address_mode(&addr, ptr, 0);
1942 base = be_transform_node(base);
1945 if (index == NULL) {
1948 index = be_transform_node(index);
1951 if (mode_is_float(mode)) {
1952 if (ia32_cg_config.use_sse2) {
1953 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1955 res_mode = mode_xmm;
1957 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1959 res_mode = mode_vfp;
1962 assert(mode != mode_b);
1964 /* create a conv node with address mode for smaller modes */
1965 if (get_mode_size_bits(mode) < 32) {
1966 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1967 new_mem, noreg_GP, mode);
1969 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1974 set_irn_pinned(new_node, get_irn_pinned(node));
1975 set_ia32_op_type(new_node, ia32_AddrModeS);
1976 set_ia32_ls_mode(new_node, mode);
1977 set_address(new_node, &addr);
1979 if (get_irn_pinned(node) == op_pin_state_floats) {
1980 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1981 && pn_ia32_vfld_res == pn_ia32_Load_res
1982 && pn_ia32_Load_res == pn_ia32_res);
1983 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1986 SET_IA32_ORIG_NODE(new_node, node);
1988 be_dep_on_frame(new_node);
1992 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1993 ir_node *ptr, ir_node *other)
2000 /* we only use address mode if we're the only user of the load */
2001 if (get_irn_n_edges(node) > 1)
2004 load = get_Proj_pred(node);
2007 if (get_nodes_block(load) != block)
2010 /* store should have the same pointer as the load */
2011 if (get_Load_ptr(load) != ptr)
2014 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2015 if (other != NULL &&
2016 get_nodes_block(other) == block &&
2017 heights_reachable_in_block(heights, other, load)) {
2021 if (prevents_AM(block, load, mem))
2023 /* Store should be attached to the load via mem */
2024 assert(heights_reachable_in_block(heights, mem, load));
2029 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2030 ir_node *mem, ir_node *ptr, ir_mode *mode,
2031 construct_binop_dest_func *func,
2032 construct_binop_dest_func *func8bit,
2033 match_flags_t flags)
2035 ir_node *src_block = get_nodes_block(node);
2043 ia32_address_mode_t am;
2044 ia32_address_t *addr = &am.addr;
2045 memset(&am, 0, sizeof(am));
2047 assert(flags & match_immediate); /* there is no destam node without... */
2048 commutative = (flags & match_commutative) != 0;
2050 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2051 build_address(&am, op1, ia32_create_am_double_use);
2052 new_op = create_immediate_or_transform(op2, 0);
2053 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2054 build_address(&am, op2, ia32_create_am_double_use);
2055 new_op = create_immediate_or_transform(op1, 0);
2060 if (addr->base == NULL)
2061 addr->base = noreg_GP;
2062 if (addr->index == NULL)
2063 addr->index = noreg_GP;
2064 if (addr->mem == NULL)
2067 dbgi = get_irn_dbg_info(node);
2068 block = be_transform_node(src_block);
2069 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2071 if (get_mode_size_bits(mode) == 8) {
2072 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2074 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2076 set_address(new_node, addr);
2077 set_ia32_op_type(new_node, ia32_AddrModeD);
2078 set_ia32_ls_mode(new_node, mode);
2079 SET_IA32_ORIG_NODE(new_node, node);
2081 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2082 mem_proj = be_transform_node(am.mem_proj);
2083 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2088 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2089 ir_node *ptr, ir_mode *mode,
2090 construct_unop_dest_func *func)
2092 ir_node *src_block = get_nodes_block(node);
2098 ia32_address_mode_t am;
2099 ia32_address_t *addr = &am.addr;
2101 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2104 memset(&am, 0, sizeof(am));
2105 build_address(&am, op, ia32_create_am_double_use);
2107 dbgi = get_irn_dbg_info(node);
2108 block = be_transform_node(src_block);
2109 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2110 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2111 set_address(new_node, addr);
2112 set_ia32_op_type(new_node, ia32_AddrModeD);
2113 set_ia32_ls_mode(new_node, mode);
2114 SET_IA32_ORIG_NODE(new_node, node);
2116 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2117 mem_proj = be_transform_node(am.mem_proj);
2118 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2123 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2125 ir_mode *mode = get_irn_mode(node);
2126 ir_node *mux_true = get_Mux_true(node);
2127 ir_node *mux_false = get_Mux_false(node);
2137 ia32_address_t addr;
2139 if (get_mode_size_bits(mode) != 8)
2142 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2144 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2150 build_address_ptr(&addr, ptr, mem);
2152 dbgi = get_irn_dbg_info(node);
2153 block = get_nodes_block(node);
2154 new_block = be_transform_node(block);
2155 cond = get_Mux_sel(node);
2156 flags = get_flags_node(cond, &pnc);
2157 new_mem = be_transform_node(mem);
2158 new_node = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2159 addr.index, addr.mem, flags, pnc, negated);
2160 set_address(new_node, &addr);
2161 set_ia32_op_type(new_node, ia32_AddrModeD);
2162 set_ia32_ls_mode(new_node, mode);
2163 SET_IA32_ORIG_NODE(new_node, node);
2168 static ir_node *try_create_dest_am(ir_node *node)
2170 ir_node *val = get_Store_value(node);
2171 ir_node *mem = get_Store_mem(node);
2172 ir_node *ptr = get_Store_ptr(node);
2173 ir_mode *mode = get_irn_mode(val);
2174 unsigned bits = get_mode_size_bits(mode);
2179 /* handle only GP modes for now... */
2180 if (!ia32_mode_needs_gp_reg(mode))
2184 /* store must be the only user of the val node */
2185 if (get_irn_n_edges(val) > 1)
2187 /* skip pointless convs */
2189 ir_node *conv_op = get_Conv_op(val);
2190 ir_mode *pred_mode = get_irn_mode(conv_op);
2191 if (!ia32_mode_needs_gp_reg(pred_mode))
2193 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2201 /* value must be in the same block */
2202 if (get_nodes_block(node) != get_nodes_block(val))
2205 switch (get_irn_opcode(val)) {
2207 op1 = get_Add_left(val);
2208 op2 = get_Add_right(val);
2209 if (ia32_cg_config.use_incdec) {
2210 if (is_Const_1(op2)) {
2211 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2213 } else if (is_Const_Minus_1(op2)) {
2214 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2218 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2219 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2220 match_commutative | match_immediate);
2223 op1 = get_Sub_left(val);
2224 op2 = get_Sub_right(val);
2225 if (is_Const(op2)) {
2226 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2228 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2229 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2233 op1 = get_And_left(val);
2234 op2 = get_And_right(val);
2235 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2236 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2237 match_commutative | match_immediate);
2240 op1 = get_Or_left(val);
2241 op2 = get_Or_right(val);
2242 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2243 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2244 match_commutative | match_immediate);
2247 op1 = get_Eor_left(val);
2248 op2 = get_Eor_right(val);
2249 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2250 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2251 match_commutative | match_immediate);
2254 op1 = get_Shl_left(val);
2255 op2 = get_Shl_right(val);
2256 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2257 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2261 op1 = get_Shr_left(val);
2262 op2 = get_Shr_right(val);
2263 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2264 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2268 op1 = get_Shrs_left(val);
2269 op2 = get_Shrs_right(val);
2270 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2271 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2275 op1 = get_Rotl_left(val);
2276 op2 = get_Rotl_right(val);
2277 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2278 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2281 /* TODO: match ROR patterns... */
2283 new_node = try_create_SetMem(val, ptr, mem);
2286 op1 = get_Minus_op(val);
2287 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2290 /* should be lowered already */
2291 assert(mode != mode_b);
2292 op1 = get_Not_op(val);
2293 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2299 if (new_node != NULL) {
2300 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2301 get_irn_pinned(node) == op_pin_state_pinned) {
2302 set_irn_pinned(new_node, op_pin_state_pinned);
2309 static bool possible_int_mode_for_fp(ir_mode *mode)
2313 if (!mode_is_signed(mode))
2315 size = get_mode_size_bits(mode);
2316 if (size != 16 && size != 32)
2321 static int is_float_to_int_conv(const ir_node *node)
2323 ir_mode *mode = get_irn_mode(node);
2327 if (!possible_int_mode_for_fp(mode))
2332 conv_op = get_Conv_op(node);
2333 conv_mode = get_irn_mode(conv_op);
2335 if (!mode_is_float(conv_mode))
2342 * Transform a Store(floatConst) into a sequence of
2345 * @return the created ia32 Store node
2347 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2349 ir_mode *mode = get_irn_mode(cns);
2350 unsigned size = get_mode_size_bytes(mode);
2351 tarval *tv = get_Const_tarval(cns);
2352 ir_node *block = get_nodes_block(node);
2353 ir_node *new_block = be_transform_node(block);
2354 ir_node *ptr = get_Store_ptr(node);
2355 ir_node *mem = get_Store_mem(node);
2356 dbg_info *dbgi = get_irn_dbg_info(node);
2360 ia32_address_t addr;
2362 assert(size % 4 == 0);
2365 build_address_ptr(&addr, ptr, mem);
2369 get_tarval_sub_bits(tv, ofs) |
2370 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2371 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2372 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2373 ir_node *imm = create_Immediate(NULL, 0, val);
2375 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2376 addr.index, addr.mem, imm);
2378 set_irn_pinned(new_node, get_irn_pinned(node));
2379 set_ia32_op_type(new_node, ia32_AddrModeD);
2380 set_ia32_ls_mode(new_node, mode_Iu);
2381 set_address(new_node, &addr);
2382 SET_IA32_ORIG_NODE(new_node, node);
2385 ins[i++] = new_node;
2390 } while (size != 0);
2393 return new_rd_Sync(dbgi, current_ir_graph, new_block, i, ins);
2400 * Generate a vfist or vfisttp instruction.
2402 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2403 ir_node *mem, ir_node *val, ir_node **fist)
2407 if (ia32_cg_config.use_fisttp) {
2408 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2409 if other users exists */
2410 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2411 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2412 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2413 be_new_Keep(reg_class, irg, block, 1, &value);
2415 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2418 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2421 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2427 * Transforms a general (no special case) Store.
2429 * @return the created ia32 Store node
2431 static ir_node *gen_general_Store(ir_node *node)
2433 ir_node *val = get_Store_value(node);
2434 ir_mode *mode = get_irn_mode(val);
2435 ir_node *block = get_nodes_block(node);
2436 ir_node *new_block = be_transform_node(block);
2437 ir_node *ptr = get_Store_ptr(node);
2438 ir_node *mem = get_Store_mem(node);
2439 dbg_info *dbgi = get_irn_dbg_info(node);
2440 ir_node *new_val, *new_node, *store;
2441 ia32_address_t addr;
2443 /* check for destination address mode */
2444 new_node = try_create_dest_am(node);
2445 if (new_node != NULL)
2448 /* construct store address */
2449 memset(&addr, 0, sizeof(addr));
2450 ia32_create_address_mode(&addr, ptr, 0);
2452 if (addr.base == NULL) {
2453 addr.base = noreg_GP;
2455 addr.base = be_transform_node(addr.base);
2458 if (addr.index == NULL) {
2459 addr.index = noreg_GP;
2461 addr.index = be_transform_node(addr.index);
2463 addr.mem = be_transform_node(mem);
2465 if (mode_is_float(mode)) {
2466 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2468 while (is_Conv(val) && mode == get_irn_mode(val)) {
2469 ir_node *op = get_Conv_op(val);
2470 if (!mode_is_float(get_irn_mode(op)))
2474 new_val = be_transform_node(val);
2475 if (ia32_cg_config.use_sse2) {
2476 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2477 addr.index, addr.mem, new_val);
2479 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2480 addr.index, addr.mem, new_val, mode);
2483 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2484 val = get_Conv_op(val);
2486 /* TODO: is this optimisation still necessary at all (middleend)? */
2487 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2488 while (is_Conv(val)) {
2489 ir_node *op = get_Conv_op(val);
2490 if (!mode_is_float(get_irn_mode(op)))
2492 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2496 new_val = be_transform_node(val);
2497 new_node = gen_vfist(dbgi, current_ir_graph, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2499 new_val = create_immediate_or_transform(val, 0);
2500 assert(mode != mode_b);
2502 if (get_mode_size_bits(mode) == 8) {
2503 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2504 addr.index, addr.mem, new_val);
2506 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2507 addr.index, addr.mem, new_val);
2512 set_irn_pinned(store, get_irn_pinned(node));
2513 set_ia32_op_type(store, ia32_AddrModeD);
2514 set_ia32_ls_mode(store, mode);
2516 set_address(store, &addr);
2517 SET_IA32_ORIG_NODE(store, node);
2523 * Transforms a Store.
2525 * @return the created ia32 Store node
2527 static ir_node *gen_Store(ir_node *node)
2529 ir_node *val = get_Store_value(node);
2530 ir_mode *mode = get_irn_mode(val);
2532 if (mode_is_float(mode) && is_Const(val)) {
2533 /* We can transform every floating const store
2534 into a sequence of integer stores.
2535 If the constant is already in a register,
2536 it would be better to use it, but we don't
2537 have this information here. */
2538 return gen_float_const_Store(node, val);
2540 return gen_general_Store(node);
2544 * Transforms a Switch.
2546 * @return the created ia32 SwitchJmp node
2548 static ir_node *create_Switch(ir_node *node)
2550 dbg_info *dbgi = get_irn_dbg_info(node);
2551 ir_node *block = be_transform_node(get_nodes_block(node));
2552 ir_node *sel = get_Cond_selector(node);
2553 ir_node *new_sel = be_transform_node(sel);
2554 long switch_min = LONG_MAX;
2555 long switch_max = LONG_MIN;
2556 long default_pn = get_Cond_defaultProj(node);
2558 const ir_edge_t *edge;
2560 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2562 /* determine the smallest switch case value */
2563 foreach_out_edge(node, edge) {
2564 ir_node *proj = get_edge_src_irn(edge);
2565 long pn = get_Proj_proj(proj);
2566 if (pn == default_pn)
2569 if (pn < switch_min)
2571 if (pn > switch_max)
2575 if ((unsigned long) (switch_max - switch_min) > 256000) {
2576 panic("Size of switch %+F bigger than 256000", node);
2579 if (switch_min != 0) {
2580 /* if smallest switch case is not 0 we need an additional sub */
2581 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2582 add_ia32_am_offs_int(new_sel, -switch_min);
2583 set_ia32_op_type(new_sel, ia32_AddrModeS);
2585 SET_IA32_ORIG_NODE(new_sel, node);
2588 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2589 SET_IA32_ORIG_NODE(new_node, node);
2595 * Transform a Cond node.
2597 static ir_node *gen_Cond(ir_node *node)
2599 ir_node *block = get_nodes_block(node);
2600 ir_node *new_block = be_transform_node(block);
2601 dbg_info *dbgi = get_irn_dbg_info(node);
2602 ir_node *sel = get_Cond_selector(node);
2603 ir_mode *sel_mode = get_irn_mode(sel);
2604 ir_node *flags = NULL;
2608 if (sel_mode != mode_b) {
2609 return create_Switch(node);
2612 /* we get flags from a Cmp */
2613 flags = get_flags_node(sel, &pnc);
2615 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2616 SET_IA32_ORIG_NODE(new_node, node);
2621 static ir_node *gen_be_Copy(ir_node *node)
2623 ir_node *new_node = be_duplicate_node(node);
2624 ir_mode *mode = get_irn_mode(new_node);
2626 if (ia32_mode_needs_gp_reg(mode)) {
2627 set_irn_mode(new_node, mode_Iu);
2633 static ir_node *create_Fucom(ir_node *node)
2635 dbg_info *dbgi = get_irn_dbg_info(node);
2636 ir_node *block = get_nodes_block(node);
2637 ir_node *new_block = be_transform_node(block);
2638 ir_node *left = get_Cmp_left(node);
2639 ir_node *new_left = be_transform_node(left);
2640 ir_node *right = get_Cmp_right(node);
2644 if (ia32_cg_config.use_fucomi) {
2645 new_right = be_transform_node(right);
2646 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2648 set_ia32_commutative(new_node);
2649 SET_IA32_ORIG_NODE(new_node, node);
2651 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2652 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2654 new_right = be_transform_node(right);
2655 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2658 set_ia32_commutative(new_node);
2660 SET_IA32_ORIG_NODE(new_node, node);
2662 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2663 SET_IA32_ORIG_NODE(new_node, node);
2669 static ir_node *create_Ucomi(ir_node *node)
2671 dbg_info *dbgi = get_irn_dbg_info(node);
2672 ir_node *src_block = get_nodes_block(node);
2673 ir_node *new_block = be_transform_node(src_block);
2674 ir_node *left = get_Cmp_left(node);
2675 ir_node *right = get_Cmp_right(node);
2677 ia32_address_mode_t am;
2678 ia32_address_t *addr = &am.addr;
2680 match_arguments(&am, src_block, left, right, NULL,
2681 match_commutative | match_am);
2683 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2684 addr->mem, am.new_op1, am.new_op2,
2686 set_am_attributes(new_node, &am);
2688 SET_IA32_ORIG_NODE(new_node, node);
2690 new_node = fix_mem_proj(new_node, &am);
2696 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2697 * to fold an and into a test node
2699 static bool can_fold_test_and(ir_node *node)
2701 const ir_edge_t *edge;
2703 /** we can only have eq and lg projs */
2704 foreach_out_edge(node, edge) {
2705 ir_node *proj = get_edge_src_irn(edge);
2706 pn_Cmp pnc = get_Proj_proj(proj);
2707 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2715 * returns true if it is assured, that the upper bits of a node are "clean"
2716 * which means for a 16 or 8 bit value, that the upper bits in the register
2717 * are 0 for unsigned and a copy of the last significant bit for signed
2720 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2722 assert(ia32_mode_needs_gp_reg(mode));
2723 if (get_mode_size_bits(mode) >= 32)
2726 if (is_Proj(transformed_node))
2727 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2729 switch (get_ia32_irn_opcode(transformed_node)) {
2730 case iro_ia32_Conv_I2I:
2731 case iro_ia32_Conv_I2I8Bit: {
2732 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2733 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2735 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2742 if (mode_is_signed(mode)) {
2743 return false; /* TODO handle signed modes */
2745 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2746 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2747 const ia32_immediate_attr_t *attr
2748 = get_ia32_immediate_attr_const(right);
2749 if (attr->symconst == 0 &&
2750 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2754 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2758 /* TODO too conservative if shift amount is constant */
2759 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2762 if (!mode_is_signed(mode)) {
2764 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2765 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2767 /* TODO if one is known to be zero extended, then || is sufficient */
2772 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2773 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2775 case iro_ia32_Const:
2776 case iro_ia32_Immediate: {
2777 const ia32_immediate_attr_t *attr =
2778 get_ia32_immediate_attr_const(transformed_node);
2779 if (mode_is_signed(mode)) {
2780 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2781 return shifted == 0 || shifted == -1;
2783 unsigned long shifted = (unsigned long)attr->offset;
2784 shifted >>= get_mode_size_bits(mode);
2785 return shifted == 0;
2795 * Generate code for a Cmp.
2797 static ir_node *gen_Cmp(ir_node *node)
2799 dbg_info *dbgi = get_irn_dbg_info(node);
2800 ir_node *block = get_nodes_block(node);
2801 ir_node *new_block = be_transform_node(block);
2802 ir_node *left = get_Cmp_left(node);
2803 ir_node *right = get_Cmp_right(node);
2804 ir_mode *cmp_mode = get_irn_mode(left);
2806 ia32_address_mode_t am;
2807 ia32_address_t *addr = &am.addr;
2810 if (mode_is_float(cmp_mode)) {
2811 if (ia32_cg_config.use_sse2) {
2812 return create_Ucomi(node);
2814 return create_Fucom(node);
2818 assert(ia32_mode_needs_gp_reg(cmp_mode));
2820 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2821 cmp_unsigned = !mode_is_signed(cmp_mode);
2822 if (is_Const_0(right) &&
2824 get_irn_n_edges(left) == 1 &&
2825 can_fold_test_and(node)) {
2826 /* Test(and_left, and_right) */
2827 ir_node *and_left = get_And_left(left);
2828 ir_node *and_right = get_And_right(left);
2830 /* matze: code here used mode instead of cmd_mode, I think it is always
2831 * the same as cmp_mode, but I leave this here to see if this is really
2834 assert(get_irn_mode(and_left) == cmp_mode);
2836 match_arguments(&am, block, and_left, and_right, NULL,
2838 match_am | match_8bit_am | match_16bit_am |
2839 match_am_and_immediates | match_immediate);
2841 /* use 32bit compare mode if possible since the opcode is smaller */
2842 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2843 upper_bits_clean(am.new_op2, cmp_mode)) {
2844 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2847 if (get_mode_size_bits(cmp_mode) == 8) {
2848 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2849 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2852 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2853 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2856 /* Cmp(left, right) */
2857 match_arguments(&am, block, left, right, NULL,
2858 match_commutative | match_am | match_8bit_am |
2859 match_16bit_am | match_am_and_immediates |
2861 /* use 32bit compare mode if possible since the opcode is smaller */
2862 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2863 upper_bits_clean(am.new_op2, cmp_mode)) {
2864 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2867 if (get_mode_size_bits(cmp_mode) == 8) {
2868 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2869 addr->index, addr->mem, am.new_op1,
2870 am.new_op2, am.ins_permuted,
2873 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2874 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2877 set_am_attributes(new_node, &am);
2878 set_ia32_ls_mode(new_node, cmp_mode);
2880 SET_IA32_ORIG_NODE(new_node, node);
2882 new_node = fix_mem_proj(new_node, &am);
2887 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2890 dbg_info *dbgi = get_irn_dbg_info(node);
2891 ir_node *block = get_nodes_block(node);
2892 ir_node *new_block = be_transform_node(block);
2893 ir_node *val_true = get_Mux_true(node);
2894 ir_node *val_false = get_Mux_false(node);
2896 ia32_address_mode_t am;
2897 ia32_address_t *addr;
2899 assert(ia32_cg_config.use_cmov);
2900 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2904 match_arguments(&am, block, val_false, val_true, flags,
2905 match_commutative | match_am | match_16bit_am | match_mode_neutral);
2907 new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2908 addr->mem, am.new_op1, am.new_op2, new_flags,
2909 am.ins_permuted, pnc);
2910 set_am_attributes(new_node, &am);
2912 SET_IA32_ORIG_NODE(new_node, node);
2914 new_node = fix_mem_proj(new_node, &am);
2920 * Creates a ia32 Setcc instruction.
2922 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2923 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2926 ir_mode *mode = get_irn_mode(orig_node);
2929 new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2930 SET_IA32_ORIG_NODE(new_node, orig_node);
2932 /* we might need to conv the result up */
2933 if (get_mode_size_bits(mode) > 8) {
2934 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
2935 nomem, new_node, mode_Bu);
2936 SET_IA32_ORIG_NODE(new_node, orig_node);
2943 * Create instruction for an unsigned Difference or Zero.
2945 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2947 ir_graph *irg = current_ir_graph;
2948 ir_mode *mode = get_irn_mode(psi);
2949 ir_node *new_node, *sub, *sbb, *eflags, *block;
2953 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2954 match_mode_neutral | match_am | match_immediate | match_two_users);
2956 block = get_nodes_block(new_node);
2958 if (is_Proj(new_node)) {
2959 sub = get_Proj_pred(new_node);
2960 assert(is_ia32_Sub(sub));
2963 set_irn_mode(sub, mode_T);
2964 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2966 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2968 dbgi = get_irn_dbg_info(psi);
2969 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
2971 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, sbb);
2972 set_ia32_commutative(new_node);
2977 * Create an const array of two float consts.
2979 * @param c0 the first constant
2980 * @param c1 the second constant
2981 * @param new_mode IN/OUT for the mode of the constants, if NULL
2982 * smallest possible mode will be used
2984 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode) {
2986 ir_mode *mode = *new_mode;
2988 ir_initializer_t *initializer;
2989 tarval *tv0 = get_Const_tarval(c0);
2990 tarval *tv1 = get_Const_tarval(c1);
2993 /* detect the best mode for the constants */
2994 mode = get_tarval_mode(tv0);
2996 if (mode != mode_F) {
2997 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
2998 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3000 tv0 = tarval_convert_to(tv0, mode);
3001 tv1 = tarval_convert_to(tv1, mode);
3002 } else if (mode != mode_D) {
3003 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3004 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3006 tv0 = tarval_convert_to(tv0, mode);
3007 tv1 = tarval_convert_to(tv1, mode);
3014 tp = ia32_create_float_type(mode, 4);
3015 tp = ia32_create_float_array(tp);
3017 ent = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp);
3019 set_entity_ld_ident(ent, get_entity_ident(ent));
3020 set_entity_visibility(ent, visibility_local);
3021 set_entity_variability(ent, variability_constant);
3022 set_entity_allocation(ent, allocation_static);
3024 initializer = create_initializer_compound(2);
3026 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3027 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3029 set_entity_initializer(ent, initializer);
3036 * Transforms a Mux node into CMov.
3038 * @return The transformed node.
3040 static ir_node *gen_Mux(ir_node *node)
3042 dbg_info *dbgi = get_irn_dbg_info(node);
3043 ir_node *block = get_nodes_block(node);
3044 ir_node *new_block = be_transform_node(block);
3045 ir_node *mux_true = get_Mux_true(node);
3046 ir_node *mux_false = get_Mux_false(node);
3047 ir_node *cond = get_Mux_sel(node);
3048 ir_mode *mode = get_irn_mode(node);
3053 assert(get_irn_mode(cond) == mode_b);
3055 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3056 if (mode_is_float(mode)) {
3057 ir_node *cmp = get_Proj_pred(cond);
3058 ir_node *cmp_left = get_Cmp_left(cmp);
3059 ir_node *cmp_right = get_Cmp_right(cmp);
3060 pn_Cmp pnc = get_Proj_proj(cond);
3062 if (ia32_cg_config.use_sse2) {
3063 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3064 if (cmp_left == mux_true && cmp_right == mux_false) {
3065 /* Mux(a <= b, a, b) => MIN */
3066 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3067 match_commutative | match_am | match_two_users);
3068 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3069 /* Mux(a <= b, b, a) => MAX */
3070 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3071 match_commutative | match_am | match_two_users);
3073 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3074 if (cmp_left == mux_true && cmp_right == mux_false) {
3075 /* Mux(a >= b, a, b) => MAX */
3076 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3077 match_commutative | match_am | match_two_users);
3078 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3079 /* Mux(a >= b, b, a) => MIN */
3080 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3081 match_commutative | match_am | match_two_users);
3085 if (is_Const(mux_true) && is_Const(mux_false)) {
3086 ia32_address_mode_t am;
3091 flags = get_flags_node(cond, &pnc);
3092 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3094 if (ia32_cg_config.use_sse2) {
3095 /* cannot load from different mode on SSE */
3098 /* x87 can load any mode */
3102 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3104 switch (get_mode_size_bytes(new_mode)) {
3114 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3115 set_ia32_am_scale(new_node, 2);
3120 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3121 set_ia32_am_scale(new_node, 1);
3124 /* arg, shift 16 NOT supported */
3126 new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, new_node);
3129 panic("Unsupported constant size");
3132 am.ls_mode = new_mode;
3133 am.addr.base = noreg_GP;
3134 am.addr.index = new_node;
3135 am.addr.mem = nomem;
3137 am.addr.scale = scale;
3138 am.addr.use_frame = 0;
3139 am.addr.frame_entity = NULL;
3140 am.addr.symconst_sign = 0;
3141 am.mem_proj = am.addr.mem;
3142 am.op_type = ia32_AddrModeS;
3145 am.pinned = op_pin_state_floats;
3147 am.ins_permuted = 0;
3149 if (ia32_cg_config.use_sse2)
3150 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3152 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3153 set_am_attributes(load, &am);
3155 return new_rd_Proj(NULL, current_ir_graph, block, load, mode_vfp, pn_ia32_res);
3157 panic("cannot transform floating point Mux");
3160 assert(ia32_mode_needs_gp_reg(mode));
3162 if (is_Proj(cond)) {
3163 ir_node *cmp = get_Proj_pred(cond);
3165 ir_node *cmp_left = get_Cmp_left(cmp);
3166 ir_node *cmp_right = get_Cmp_right(cmp);
3167 pn_Cmp pnc = get_Proj_proj(cond);
3169 /* check for unsigned Doz first */
3170 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3171 is_Const_0(mux_false) && is_Sub(mux_true) &&
3172 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3173 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3174 return create_Doz(node, cmp_left, cmp_right);
3175 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3176 is_Const_0(mux_true) && is_Sub(mux_false) &&
3177 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3178 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3179 return create_Doz(node, cmp_left, cmp_right);
3184 flags = get_flags_node(cond, &pnc);
3186 if (is_Const(mux_true) && is_Const(mux_false)) {
3187 /* both are const, good */
3188 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3189 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3190 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3191 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3193 /* Not that simple. */
3198 new_node = create_CMov(node, cond, flags, pnc);
3206 * Create a conversion from x87 state register to general purpose.
3208 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3210 ir_node *block = be_transform_node(get_nodes_block(node));
3211 ir_node *op = get_Conv_op(node);
3212 ir_node *new_op = be_transform_node(op);
3213 ia32_code_gen_t *cg = env_cg;
3214 ir_graph *irg = current_ir_graph;
3215 dbg_info *dbgi = get_irn_dbg_info(node);
3216 ir_mode *mode = get_irn_mode(node);
3217 ir_node *fist, *load, *mem;
3219 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3220 set_irn_pinned(fist, op_pin_state_floats);
3221 set_ia32_use_frame(fist);
3222 set_ia32_op_type(fist, ia32_AddrModeD);
3224 assert(get_mode_size_bits(mode) <= 32);
3225 /* exception we can only store signed 32 bit integers, so for unsigned
3226 we store a 64bit (signed) integer and load the lower bits */
3227 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3228 set_ia32_ls_mode(fist, mode_Ls);
3230 set_ia32_ls_mode(fist, mode_Is);
3232 SET_IA32_ORIG_NODE(fist, node);
3235 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3237 set_irn_pinned(load, op_pin_state_floats);
3238 set_ia32_use_frame(load);
3239 set_ia32_op_type(load, ia32_AddrModeS);
3240 set_ia32_ls_mode(load, mode_Is);
3241 if (get_ia32_ls_mode(fist) == mode_Ls) {
3242 ia32_attr_t *attr = get_ia32_attr(load);
3243 attr->data.need_64bit_stackent = 1;
3245 ia32_attr_t *attr = get_ia32_attr(load);
3246 attr->data.need_32bit_stackent = 1;
3248 SET_IA32_ORIG_NODE(load, node);
3250 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3254 * Creates a x87 strict Conv by placing a Store and a Load
3256 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3258 ir_node *block = get_nodes_block(node);
3259 ir_graph *irg = current_ir_graph;
3260 dbg_info *dbgi = get_irn_dbg_info(node);
3261 ir_node *frame = get_irg_frame(irg);
3262 ir_node *store, *load;
3265 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3266 set_ia32_use_frame(store);
3267 set_ia32_op_type(store, ia32_AddrModeD);
3268 SET_IA32_ORIG_NODE(store, node);
3270 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3271 set_ia32_use_frame(load);
3272 set_ia32_op_type(load, ia32_AddrModeS);
3273 SET_IA32_ORIG_NODE(load, node);
3275 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3279 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3280 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3282 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3284 func = get_mode_size_bits(mode) == 8 ?
3285 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3286 return func(dbgi, block, base, index, mem, val, mode);
3290 * Create a conversion from general purpose to x87 register
3292 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3294 ir_node *src_block = get_nodes_block(node);
3295 ir_node *block = be_transform_node(src_block);
3296 ir_graph *irg = current_ir_graph;
3297 dbg_info *dbgi = get_irn_dbg_info(node);
3298 ir_node *op = get_Conv_op(node);
3299 ir_node *new_op = NULL;
3301 ir_mode *store_mode;
3306 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3307 if (possible_int_mode_for_fp(src_mode)) {
3308 ia32_address_mode_t am;
3310 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3311 if (am.op_type == ia32_AddrModeS) {
3312 ia32_address_t *addr = &am.addr;
3314 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3315 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3317 set_am_attributes(fild, &am);
3318 SET_IA32_ORIG_NODE(fild, node);
3320 fix_mem_proj(fild, &am);
3325 if (new_op == NULL) {
3326 new_op = be_transform_node(op);
3329 mode = get_irn_mode(op);
3331 /* first convert to 32 bit signed if necessary */
3332 if (get_mode_size_bits(src_mode) < 32) {
3333 if (!upper_bits_clean(new_op, src_mode)) {
3334 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3335 SET_IA32_ORIG_NODE(new_op, node);
3340 assert(get_mode_size_bits(mode) == 32);
3343 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3345 set_ia32_use_frame(store);
3346 set_ia32_op_type(store, ia32_AddrModeD);
3347 set_ia32_ls_mode(store, mode_Iu);
3349 /* exception for 32bit unsigned, do a 64bit spill+load */
3350 if (!mode_is_signed(mode)) {
3353 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3355 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3356 noreg_GP, nomem, zero_const);
3358 set_ia32_use_frame(zero_store);
3359 set_ia32_op_type(zero_store, ia32_AddrModeD);
3360 add_ia32_am_offs_int(zero_store, 4);
3361 set_ia32_ls_mode(zero_store, mode_Iu);
3366 store = new_rd_Sync(dbgi, irg, block, 2, in);
3367 store_mode = mode_Ls;
3369 store_mode = mode_Is;
3373 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3375 set_ia32_use_frame(fild);
3376 set_ia32_op_type(fild, ia32_AddrModeS);
3377 set_ia32_ls_mode(fild, store_mode);
3379 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3385 * Create a conversion from one integer mode into another one
3387 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3388 dbg_info *dbgi, ir_node *block, ir_node *op,
3391 ir_node *new_block = be_transform_node(block);
3393 ir_mode *smaller_mode;
3394 ia32_address_mode_t am;
3395 ia32_address_t *addr = &am.addr;
3398 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3399 smaller_mode = src_mode;
3401 smaller_mode = tgt_mode;
3404 #ifdef DEBUG_libfirm
3406 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3411 match_arguments(&am, block, NULL, op, NULL,
3412 match_am | match_8bit_am | match_16bit_am);
3414 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3415 /* unnecessary conv. in theory it shouldn't have been AM */
3416 assert(is_ia32_NoReg_GP(addr->base));
3417 assert(is_ia32_NoReg_GP(addr->index));
3418 assert(is_NoMem(addr->mem));
3419 assert(am.addr.offset == 0);
3420 assert(am.addr.symconst_ent == NULL);
3424 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3425 addr->mem, am.new_op2, smaller_mode);
3426 set_am_attributes(new_node, &am);
3427 /* match_arguments assume that out-mode = in-mode, this isn't true here
3429 set_ia32_ls_mode(new_node, smaller_mode);
3430 SET_IA32_ORIG_NODE(new_node, node);
3431 new_node = fix_mem_proj(new_node, &am);
3436 * Transforms a Conv node.
3438 * @return The created ia32 Conv node
3440 static ir_node *gen_Conv(ir_node *node)
3442 ir_node *block = get_nodes_block(node);
3443 ir_node *new_block = be_transform_node(block);
3444 ir_node *op = get_Conv_op(node);
3445 ir_node *new_op = NULL;
3446 dbg_info *dbgi = get_irn_dbg_info(node);
3447 ir_mode *src_mode = get_irn_mode(op);
3448 ir_mode *tgt_mode = get_irn_mode(node);
3449 int src_bits = get_mode_size_bits(src_mode);
3450 int tgt_bits = get_mode_size_bits(tgt_mode);
3451 ir_node *res = NULL;
3453 assert(!mode_is_int(src_mode) || src_bits <= 32);
3454 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3456 if (src_mode == mode_b) {
3457 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3458 /* nothing to do, we already model bools as 0/1 ints */
3459 return be_transform_node(op);
3462 if (src_mode == tgt_mode) {
3463 if (get_Conv_strict(node)) {
3464 if (ia32_cg_config.use_sse2) {
3465 /* when we are in SSE mode, we can kill all strict no-op conversion */
3466 return be_transform_node(op);
3469 /* this should be optimized already, but who knows... */
3470 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3471 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3472 return be_transform_node(op);
3476 if (mode_is_float(src_mode)) {
3477 new_op = be_transform_node(op);
3478 /* we convert from float ... */
3479 if (mode_is_float(tgt_mode)) {
3481 /* Matze: I'm a bit unsure what the following is for? seems wrong
3483 if (src_mode == mode_E && tgt_mode == mode_D
3484 && !get_Conv_strict(node)) {
3485 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3491 if (ia32_cg_config.use_sse2) {
3492 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3493 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3495 set_ia32_ls_mode(res, tgt_mode);
3497 if (get_Conv_strict(node)) {
3498 /* if fp_no_float_fold is not set then we assume that we
3499 * don't have any float operations in a non
3500 * mode_float_arithmetic mode and can skip strict upconvs */
3501 if (src_bits < tgt_bits
3502 && !(get_irg_fp_model(current_ir_graph) & fp_no_float_fold)) {
3503 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3506 res = gen_x87_strict_conv(tgt_mode, new_op);
3507 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3511 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3516 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3517 if (ia32_cg_config.use_sse2) {
3518 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3520 set_ia32_ls_mode(res, src_mode);
3522 return gen_x87_fp_to_gp(node);
3526 /* we convert from int ... */
3527 if (mode_is_float(tgt_mode)) {
3529 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3530 if (ia32_cg_config.use_sse2) {
3531 new_op = be_transform_node(op);
3532 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3534 set_ia32_ls_mode(res, tgt_mode);
3536 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3537 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3538 res = gen_x87_gp_to_fp(node, src_mode);
3540 /* we need a strict-Conv, if the int mode has more bits than the
3542 if (float_mantissa < int_mantissa) {
3543 res = gen_x87_strict_conv(tgt_mode, res);
3544 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3548 } else if (tgt_mode == mode_b) {
3549 /* mode_b lowering already took care that we only have 0/1 values */
3550 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3551 src_mode, tgt_mode));
3552 return be_transform_node(op);
3555 if (src_bits == tgt_bits) {
3556 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3557 src_mode, tgt_mode));
3558 return be_transform_node(op);
3561 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3569 static ir_node *create_immediate_or_transform(ir_node *node,
3570 char immediate_constraint_type)
3572 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3573 if (new_node == NULL) {
3574 new_node = be_transform_node(node);
3580 * Transforms a FrameAddr into an ia32 Add.
3582 static ir_node *gen_be_FrameAddr(ir_node *node)
3584 ir_node *block = be_transform_node(get_nodes_block(node));
3585 ir_node *op = be_get_FrameAddr_frame(node);
3586 ir_node *new_op = be_transform_node(op);
3587 dbg_info *dbgi = get_irn_dbg_info(node);
3590 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3591 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3592 set_ia32_use_frame(new_node);
3594 SET_IA32_ORIG_NODE(new_node, node);
3600 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3602 static ir_node *gen_be_Return(ir_node *node)
3604 ir_graph *irg = current_ir_graph;
3605 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3606 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3607 ir_entity *ent = get_irg_entity(irg);
3608 ir_type *tp = get_entity_type(ent);
3613 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3614 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3616 int pn_ret_val, pn_ret_mem, arity, i;
3618 assert(ret_val != NULL);
3619 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3620 return be_duplicate_node(node);
3623 res_type = get_method_res_type(tp, 0);
3625 if (! is_Primitive_type(res_type)) {
3626 return be_duplicate_node(node);
3629 mode = get_type_mode(res_type);
3630 if (! mode_is_float(mode)) {
3631 return be_duplicate_node(node);
3634 assert(get_method_n_ress(tp) == 1);
3636 pn_ret_val = get_Proj_proj(ret_val);
3637 pn_ret_mem = get_Proj_proj(ret_mem);
3639 /* get the Barrier */
3640 barrier = get_Proj_pred(ret_val);
3642 /* get result input of the Barrier */
3643 ret_val = get_irn_n(barrier, pn_ret_val);
3644 new_ret_val = be_transform_node(ret_val);
3646 /* get memory input of the Barrier */
3647 ret_mem = get_irn_n(barrier, pn_ret_mem);
3648 new_ret_mem = be_transform_node(ret_mem);
3650 frame = get_irg_frame(irg);
3652 dbgi = get_irn_dbg_info(barrier);
3653 block = be_transform_node(get_nodes_block(barrier));
3655 /* store xmm0 onto stack */
3656 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
3657 new_ret_mem, new_ret_val);
3658 set_ia32_ls_mode(sse_store, mode);
3659 set_ia32_op_type(sse_store, ia32_AddrModeD);
3660 set_ia32_use_frame(sse_store);
3662 /* load into x87 register */
3663 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
3664 set_ia32_op_type(fld, ia32_AddrModeS);
3665 set_ia32_use_frame(fld);
3667 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3668 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3670 /* create a new barrier */
3671 arity = get_irn_arity(barrier);
3672 in = ALLOCAN(ir_node*, arity);
3673 for (i = 0; i < arity; ++i) {
3676 if (i == pn_ret_val) {
3678 } else if (i == pn_ret_mem) {
3681 ir_node *in = get_irn_n(barrier, i);
3682 new_in = be_transform_node(in);
3687 new_barrier = new_ir_node(dbgi, irg, block,
3688 get_irn_op(barrier), get_irn_mode(barrier),
3690 copy_node_attr(barrier, new_barrier);
3691 be_duplicate_deps(barrier, new_barrier);
3692 be_set_transformed_node(barrier, new_barrier);
3694 /* transform normally */
3695 return be_duplicate_node(node);
3699 * Transform a be_AddSP into an ia32_SubSP.
3701 static ir_node *gen_be_AddSP(ir_node *node)
3703 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3704 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3706 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3707 match_am | match_immediate);
3711 * Transform a be_SubSP into an ia32_AddSP
3713 static ir_node *gen_be_SubSP(ir_node *node)
3715 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3716 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3718 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3719 match_am | match_immediate);
3723 * Change some phi modes
3725 static ir_node *gen_Phi(ir_node *node)
3727 ir_node *block = be_transform_node(get_nodes_block(node));
3728 ir_graph *irg = current_ir_graph;
3729 dbg_info *dbgi = get_irn_dbg_info(node);
3730 ir_mode *mode = get_irn_mode(node);
3733 if (ia32_mode_needs_gp_reg(mode)) {
3734 /* we shouldn't have any 64bit stuff around anymore */
3735 assert(get_mode_size_bits(mode) <= 32);
3736 /* all integer operations are on 32bit registers now */
3738 } else if (mode_is_float(mode)) {
3739 if (ia32_cg_config.use_sse2) {
3746 /* phi nodes allow loops, so we use the old arguments for now
3747 * and fix this later */
3748 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3749 get_irn_in(node) + 1);
3750 copy_node_attr(node, phi);
3751 be_duplicate_deps(node, phi);
3753 be_enqueue_preds(node);
3761 static ir_node *gen_IJmp(ir_node *node)
3763 ir_node *block = get_nodes_block(node);
3764 ir_node *new_block = be_transform_node(block);
3765 dbg_info *dbgi = get_irn_dbg_info(node);
3766 ir_node *op = get_IJmp_target(node);
3768 ia32_address_mode_t am;
3769 ia32_address_t *addr = &am.addr;
3771 assert(get_irn_mode(op) == mode_P);
3773 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3775 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3776 addr->mem, am.new_op2);
3777 set_am_attributes(new_node, &am);
3778 SET_IA32_ORIG_NODE(new_node, node);
3780 new_node = fix_mem_proj(new_node, &am);
3786 * Transform a Bound node.
3788 static ir_node *gen_Bound(ir_node *node)
3791 ir_node *lower = get_Bound_lower(node);
3792 dbg_info *dbgi = get_irn_dbg_info(node);
3794 if (is_Const_0(lower)) {
3795 /* typical case for Java */
3796 ir_node *sub, *res, *flags, *block;
3797 ir_graph *irg = current_ir_graph;
3799 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3800 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3802 block = get_nodes_block(res);
3803 if (! is_Proj(res)) {
3805 set_irn_mode(sub, mode_T);
3806 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3808 sub = get_Proj_pred(res);
3810 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3811 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3812 SET_IA32_ORIG_NODE(new_node, node);
3814 panic("generic Bound not supported in ia32 Backend");
3820 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3822 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3823 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3825 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3826 match_immediate | match_mode_neutral);
3829 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3831 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3832 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3833 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3837 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3839 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3840 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3841 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3845 static ir_node *gen_ia32_l_Add(ir_node *node)
3847 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3848 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3849 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3850 match_commutative | match_am | match_immediate |
3851 match_mode_neutral);
3853 if (is_Proj(lowered)) {
3854 lowered = get_Proj_pred(lowered);
3856 assert(is_ia32_Add(lowered));
3857 set_irn_mode(lowered, mode_T);
3863 static ir_node *gen_ia32_l_Adc(ir_node *node)
3865 return gen_binop_flags(node, new_bd_ia32_Adc,
3866 match_commutative | match_am | match_immediate |
3867 match_mode_neutral);
3871 * Transforms a l_MulS into a "real" MulS node.
3873 * @return the created ia32 Mul node
3875 static ir_node *gen_ia32_l_Mul(ir_node *node)
3877 ir_node *left = get_binop_left(node);
3878 ir_node *right = get_binop_right(node);
3880 return gen_binop(node, left, right, new_bd_ia32_Mul,
3881 match_commutative | match_am | match_mode_neutral);
3885 * Transforms a l_IMulS into a "real" IMul1OPS node.
3887 * @return the created ia32 IMul1OP node
3889 static ir_node *gen_ia32_l_IMul(ir_node *node)
3891 ir_node *left = get_binop_left(node);
3892 ir_node *right = get_binop_right(node);
3894 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3895 match_commutative | match_am | match_mode_neutral);
3898 static ir_node *gen_ia32_l_Sub(ir_node *node)
3900 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3901 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3902 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3903 match_am | match_immediate | match_mode_neutral);
3905 if (is_Proj(lowered)) {
3906 lowered = get_Proj_pred(lowered);
3908 assert(is_ia32_Sub(lowered));
3909 set_irn_mode(lowered, mode_T);
3915 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3917 return gen_binop_flags(node, new_bd_ia32_Sbb,
3918 match_am | match_immediate | match_mode_neutral);
3922 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3923 * op1 - target to be shifted
3924 * op2 - contains bits to be shifted into target
3926 * Only op3 can be an immediate.
3928 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3929 ir_node *low, ir_node *count)
3931 ir_node *block = get_nodes_block(node);
3932 ir_node *new_block = be_transform_node(block);
3933 dbg_info *dbgi = get_irn_dbg_info(node);
3934 ir_node *new_high = be_transform_node(high);
3935 ir_node *new_low = be_transform_node(low);
3939 /* the shift amount can be any mode that is bigger than 5 bits, since all
3940 * other bits are ignored anyway */
3941 while (is_Conv(count) &&
3942 get_irn_n_edges(count) == 1 &&
3943 mode_is_int(get_irn_mode(count))) {
3944 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3945 count = get_Conv_op(count);
3947 new_count = create_immediate_or_transform(count, 0);
3949 if (is_ia32_l_ShlD(node)) {
3950 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3953 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3956 SET_IA32_ORIG_NODE(new_node, node);
3961 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3963 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3964 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3965 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3966 return gen_lowered_64bit_shifts(node, high, low, count);
3969 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3971 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3972 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3973 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3974 return gen_lowered_64bit_shifts(node, high, low, count);
3977 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3979 ir_node *src_block = get_nodes_block(node);
3980 ir_node *block = be_transform_node(src_block);
3981 ir_graph *irg = current_ir_graph;
3982 dbg_info *dbgi = get_irn_dbg_info(node);
3983 ir_node *frame = get_irg_frame(irg);
3984 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3985 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3986 ir_node *new_val_low = be_transform_node(val_low);
3987 ir_node *new_val_high = be_transform_node(val_high);
3989 ir_node *sync, *fild, *res;
3990 ir_node *store_low, *store_high;
3992 if (ia32_cg_config.use_sse2) {
3993 panic("ia32_l_LLtoFloat not implemented for SSE2");
3997 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
3999 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4001 SET_IA32_ORIG_NODE(store_low, node);
4002 SET_IA32_ORIG_NODE(store_high, node);
4004 set_ia32_use_frame(store_low);
4005 set_ia32_use_frame(store_high);
4006 set_ia32_op_type(store_low, ia32_AddrModeD);
4007 set_ia32_op_type(store_high, ia32_AddrModeD);
4008 set_ia32_ls_mode(store_low, mode_Iu);
4009 set_ia32_ls_mode(store_high, mode_Is);
4010 add_ia32_am_offs_int(store_high, 4);
4014 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4017 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4019 set_ia32_use_frame(fild);
4020 set_ia32_op_type(fild, ia32_AddrModeS);
4021 set_ia32_ls_mode(fild, mode_Ls);
4023 SET_IA32_ORIG_NODE(fild, node);
4025 res = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4027 if (! mode_is_signed(get_irn_mode(val_high))) {
4028 ia32_address_mode_t am;
4030 ir_node *count = create_Immediate(NULL, 0, 31);
4033 am.addr.base = noreg_GP;
4034 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4035 am.addr.mem = nomem;
4038 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4039 am.addr.use_frame = 0;
4040 am.addr.frame_entity = NULL;
4041 am.addr.symconst_sign = 0;
4042 am.ls_mode = mode_F;
4043 am.mem_proj = nomem;
4044 am.op_type = ia32_AddrModeS;
4046 am.new_op2 = ia32_new_NoReg_vfp(env_cg);
4047 am.pinned = op_pin_state_floats;
4049 am.ins_permuted = 0;
4051 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4052 am.new_op1, am.new_op2, get_fpcw());
4053 set_am_attributes(fadd, &am);
4055 set_irn_mode(fadd, mode_T);
4056 res = new_rd_Proj(NULL, irg, block, fadd, mode_vfp, pn_ia32_res);
4061 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4063 ir_node *src_block = get_nodes_block(node);
4064 ir_node *block = be_transform_node(src_block);
4065 ir_graph *irg = current_ir_graph;
4066 dbg_info *dbgi = get_irn_dbg_info(node);
4067 ir_node *frame = get_irg_frame(irg);
4068 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4069 ir_node *new_val = be_transform_node(val);
4070 ir_node *fist, *mem;
4072 mem = gen_vfist(dbgi, irg, block, frame, noreg_GP, nomem, new_val, &fist);
4073 SET_IA32_ORIG_NODE(fist, node);
4074 set_ia32_use_frame(fist);
4075 set_ia32_op_type(fist, ia32_AddrModeD);
4076 set_ia32_ls_mode(fist, mode_Ls);
4082 * the BAD transformer.
4084 static ir_node *bad_transform(ir_node *node)
4086 panic("No transform function for %+F available.", node);
4090 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4092 ir_graph *irg = current_ir_graph;
4093 ir_node *block = be_transform_node(get_nodes_block(node));
4094 ir_node *pred = get_Proj_pred(node);
4095 ir_node *new_pred = be_transform_node(pred);
4096 ir_node *frame = get_irg_frame(irg);
4097 dbg_info *dbgi = get_irn_dbg_info(node);
4098 long pn = get_Proj_proj(node);
4103 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4104 SET_IA32_ORIG_NODE(load, node);
4105 set_ia32_use_frame(load);
4106 set_ia32_op_type(load, ia32_AddrModeS);
4107 set_ia32_ls_mode(load, mode_Iu);
4108 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4109 * 32 bit from it with this particular load */
4110 attr = get_ia32_attr(load);
4111 attr->data.need_64bit_stackent = 1;
4113 if (pn == pn_ia32_l_FloattoLL_res_high) {
4114 add_ia32_am_offs_int(load, 4);
4116 assert(pn == pn_ia32_l_FloattoLL_res_low);
4119 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4125 * Transform the Projs of an AddSP.
4127 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4129 ir_node *block = be_transform_node(get_nodes_block(node));
4130 ir_node *pred = get_Proj_pred(node);
4131 ir_node *new_pred = be_transform_node(pred);
4132 ir_graph *irg = current_ir_graph;
4133 dbg_info *dbgi = get_irn_dbg_info(node);
4134 long proj = get_Proj_proj(node);
4136 if (proj == pn_be_AddSP_sp) {
4137 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4138 pn_ia32_SubSP_stack);
4139 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4141 } else if (proj == pn_be_AddSP_res) {
4142 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4143 pn_ia32_SubSP_addr);
4144 } else if (proj == pn_be_AddSP_M) {
4145 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4148 panic("No idea how to transform proj->AddSP");
4152 * Transform the Projs of a SubSP.
4154 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4156 ir_node *block = be_transform_node(get_nodes_block(node));
4157 ir_node *pred = get_Proj_pred(node);
4158 ir_node *new_pred = be_transform_node(pred);
4159 ir_graph *irg = current_ir_graph;
4160 dbg_info *dbgi = get_irn_dbg_info(node);
4161 long proj = get_Proj_proj(node);
4163 if (proj == pn_be_SubSP_sp) {
4164 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4165 pn_ia32_AddSP_stack);
4166 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4168 } else if (proj == pn_be_SubSP_M) {
4169 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4172 panic("No idea how to transform proj->SubSP");
4176 * Transform and renumber the Projs from a Load.
4178 static ir_node *gen_Proj_Load(ir_node *node)
4181 ir_node *block = be_transform_node(get_nodes_block(node));
4182 ir_node *pred = get_Proj_pred(node);
4183 ir_graph *irg = current_ir_graph;
4184 dbg_info *dbgi = get_irn_dbg_info(node);
4185 long proj = get_Proj_proj(node);
4187 /* loads might be part of source address mode matches, so we don't
4188 * transform the ProjMs yet (with the exception of loads whose result is
4191 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4194 /* this is needed, because sometimes we have loops that are only
4195 reachable through the ProjM */
4196 be_enqueue_preds(node);
4197 /* do it in 2 steps, to silence firm verifier */
4198 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4199 set_Proj_proj(res, pn_ia32_mem);
4203 /* renumber the proj */
4204 new_pred = be_transform_node(pred);
4205 if (is_ia32_Load(new_pred)) {
4208 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4210 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4211 case pn_Load_X_regular:
4212 return new_rd_Jmp(dbgi, irg, block);
4213 case pn_Load_X_except:
4214 /* This Load might raise an exception. Mark it. */
4215 set_ia32_exc_label(new_pred, 1);
4216 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4220 } else if (is_ia32_Conv_I2I(new_pred) ||
4221 is_ia32_Conv_I2I8Bit(new_pred)) {
4222 set_irn_mode(new_pred, mode_T);
4223 if (proj == pn_Load_res) {
4224 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4225 } else if (proj == pn_Load_M) {
4226 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4228 } else if (is_ia32_xLoad(new_pred)) {
4231 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4233 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4234 case pn_Load_X_regular:
4235 return new_rd_Jmp(dbgi, irg, block);
4236 case pn_Load_X_except:
4237 /* This Load might raise an exception. Mark it. */
4238 set_ia32_exc_label(new_pred, 1);
4239 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4243 } else if (is_ia32_vfld(new_pred)) {
4246 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4248 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4249 case pn_Load_X_regular:
4250 return new_rd_Jmp(dbgi, irg, block);
4251 case pn_Load_X_except:
4252 /* This Load might raise an exception. Mark it. */
4253 set_ia32_exc_label(new_pred, 1);
4254 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4259 /* can happen for ProJMs when source address mode happened for the
4262 /* however it should not be the result proj, as that would mean the
4263 load had multiple users and should not have been used for
4265 if (proj != pn_Load_M) {
4266 panic("internal error: transformed node not a Load");
4268 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4271 panic("No idea how to transform proj");
4275 * Transform and renumber the Projs from a DivMod like instruction.
4277 static ir_node *gen_Proj_DivMod(ir_node *node)
4279 ir_node *block = be_transform_node(get_nodes_block(node));
4280 ir_node *pred = get_Proj_pred(node);
4281 ir_node *new_pred = be_transform_node(pred);
4282 ir_graph *irg = current_ir_graph;
4283 dbg_info *dbgi = get_irn_dbg_info(node);
4284 long proj = get_Proj_proj(node);
4286 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4288 switch (get_irn_opcode(pred)) {
4292 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4294 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4295 case pn_Div_X_regular:
4296 return new_rd_Jmp(dbgi, irg, block);
4297 case pn_Div_X_except:
4298 set_ia32_exc_label(new_pred, 1);
4299 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4307 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4309 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4310 case pn_Mod_X_except:
4311 set_ia32_exc_label(new_pred, 1);
4312 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4320 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4321 case pn_DivMod_res_div:
4322 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4323 case pn_DivMod_res_mod:
4324 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4325 case pn_DivMod_X_regular:
4326 return new_rd_Jmp(dbgi, irg, block);
4327 case pn_DivMod_X_except:
4328 set_ia32_exc_label(new_pred, 1);
4329 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4338 panic("No idea how to transform proj->DivMod");
4342 * Transform and renumber the Projs from a CopyB.
4344 static ir_node *gen_Proj_CopyB(ir_node *node)
4346 ir_node *block = be_transform_node(get_nodes_block(node));
4347 ir_node *pred = get_Proj_pred(node);
4348 ir_node *new_pred = be_transform_node(pred);
4349 ir_graph *irg = current_ir_graph;
4350 dbg_info *dbgi = get_irn_dbg_info(node);
4351 long proj = get_Proj_proj(node);
4354 case pn_CopyB_M_regular:
4355 if (is_ia32_CopyB_i(new_pred)) {
4356 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4357 } else if (is_ia32_CopyB(new_pred)) {
4358 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4365 panic("No idea how to transform proj->CopyB");
4369 * Transform and renumber the Projs from a Quot.
4371 static ir_node *gen_Proj_Quot(ir_node *node)
4373 ir_node *block = be_transform_node(get_nodes_block(node));
4374 ir_node *pred = get_Proj_pred(node);
4375 ir_node *new_pred = be_transform_node(pred);
4376 ir_graph *irg = current_ir_graph;
4377 dbg_info *dbgi = get_irn_dbg_info(node);
4378 long proj = get_Proj_proj(node);
4382 if (is_ia32_xDiv(new_pred)) {
4383 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4384 } else if (is_ia32_vfdiv(new_pred)) {
4385 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4389 if (is_ia32_xDiv(new_pred)) {
4390 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4391 } else if (is_ia32_vfdiv(new_pred)) {
4392 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4395 case pn_Quot_X_regular:
4396 case pn_Quot_X_except:
4401 panic("No idea how to transform proj->Quot");
4404 static ir_node *gen_be_Call(ir_node *node)
4406 dbg_info *const dbgi = get_irn_dbg_info(node);
4407 ir_graph *const irg = current_ir_graph;
4408 ir_node *const src_block = get_nodes_block(node);
4409 ir_node *const block = be_transform_node(src_block);
4410 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4411 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4412 ir_node *const sp = be_transform_node(src_sp);
4413 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4414 ia32_address_mode_t am;
4415 ia32_address_t *const addr = &am.addr;
4420 ir_node * eax = noreg_GP;
4421 ir_node * ecx = noreg_GP;
4422 ir_node * edx = noreg_GP;
4423 unsigned const pop = be_Call_get_pop(node);
4424 ir_type *const call_tp = be_Call_get_type(node);
4426 /* Run the x87 simulator if the call returns a float value */
4427 if (get_method_n_ress(call_tp) > 0) {
4428 ir_type *const res_type = get_method_res_type(call_tp, 0);
4429 ir_mode *const res_mode = get_type_mode(res_type);
4431 if (res_mode != NULL && mode_is_float(res_mode)) {
4432 env_cg->do_x87_sim = 1;
4436 /* We do not want be_Call direct calls */
4437 assert(be_Call_get_entity(node) == NULL);
4439 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4440 match_am | match_immediate);
4442 i = get_irn_arity(node) - 1;
4443 fpcw = be_transform_node(get_irn_n(node, i--));
4444 for (; i >= be_pos_Call_first_arg; --i) {
4445 arch_register_req_t const *const req = arch_get_register_req(node, i);
4446 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4448 assert(req->type == arch_register_req_type_limited);
4449 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4451 switch (*req->limited) {
4452 case 1 << REG_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4453 case 1 << REG_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4454 case 1 << REG_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4455 default: panic("Invalid GP register for register parameter");
4459 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4460 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4461 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4462 set_am_attributes(call, &am);
4463 call = fix_mem_proj(call, &am);
4465 if (get_irn_pinned(node) == op_pin_state_pinned)
4466 set_irn_pinned(call, op_pin_state_pinned);
4468 SET_IA32_ORIG_NODE(call, node);
4473 * Transform Builtin trap
4475 static ir_node *gen_trap(ir_node *node) {
4476 dbg_info *dbgi = get_irn_dbg_info(node);
4477 ir_node *block = be_transform_node(get_nodes_block(node));
4478 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4480 return new_bd_ia32_UD2(dbgi, block, mem);
4484 * Transform Builtin debugbreak
4486 static ir_node *gen_debugbreak(ir_node *node) {
4487 dbg_info *dbgi = get_irn_dbg_info(node);
4488 ir_node *block = be_transform_node(get_nodes_block(node));
4489 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4491 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4495 * Transform Builtin return_address
4497 static ir_node *gen_return_address(ir_node *node) {
4498 ir_node *param = get_Builtin_param(node, 0);
4499 ir_node *frame = get_Builtin_param(node, 1);
4500 dbg_info *dbgi = get_irn_dbg_info(node);
4501 tarval *tv = get_Const_tarval(param);
4502 unsigned long value = get_tarval_long(tv);
4504 ir_node *block = be_transform_node(get_nodes_block(node));
4505 ir_node *ptr = be_transform_node(frame);
4509 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4510 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4511 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4514 /* load the return address from this frame */
4515 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, get_irg_no_mem(current_ir_graph));
4517 set_irn_pinned(load, get_irn_pinned(node));
4518 set_ia32_op_type(load, ia32_AddrModeS);
4519 set_ia32_ls_mode(load, mode_Iu);
4521 set_ia32_am_offs_int(load, 0);
4522 set_ia32_use_frame(load);
4523 set_ia32_frame_ent(load, ia32_get_return_address_entity());
4525 if (get_irn_pinned(node) == op_pin_state_floats) {
4526 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
4527 && pn_ia32_vfld_res == pn_ia32_Load_res
4528 && pn_ia32_Load_res == pn_ia32_res);
4529 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4532 SET_IA32_ORIG_NODE(load, node);
4533 return new_r_Proj(current_ir_graph, block, load, mode_Iu, pn_ia32_Load_res);
4537 * Transform Builtin frame_address
4539 static ir_node *gen_frame_address(ir_node *node) {
4540 ir_node *param = get_Builtin_param(node, 0);
4541 ir_node *frame = get_Builtin_param(node, 1);
4542 dbg_info *dbgi = get_irn_dbg_info(node);
4543 tarval *tv = get_Const_tarval(param);
4544 unsigned long value = get_tarval_long(tv);
4546 ir_node *block = be_transform_node(get_nodes_block(node));
4547 ir_node *ptr = be_transform_node(frame);
4552 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4553 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4554 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4557 /* load the frame address from this frame */
4558 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, get_irg_no_mem(current_ir_graph));
4560 set_irn_pinned(load, get_irn_pinned(node));
4561 set_ia32_op_type(load, ia32_AddrModeS);
4562 set_ia32_ls_mode(load, mode_Iu);
4564 ent = ia32_get_frame_address_entity();
4566 set_ia32_am_offs_int(load, 0);
4567 set_ia32_use_frame(load);
4568 set_ia32_frame_ent(load, ent);
4570 /* will fail anyway, but gcc does this: */
4571 set_ia32_am_offs_int(load, 0);
4574 if (get_irn_pinned(node) == op_pin_state_floats) {
4575 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
4576 && pn_ia32_vfld_res == pn_ia32_Load_res
4577 && pn_ia32_Load_res == pn_ia32_res);
4578 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4581 SET_IA32_ORIG_NODE(load, node);
4582 return new_r_Proj(current_ir_graph, block, load, mode_Iu, pn_ia32_Load_res);
4586 * Transform Builtin frame_address
4588 static ir_node *gen_prefetch(ir_node *node) {
4590 ir_node *ptr, *block, *mem, *base, *index;
4591 ir_node *param, *new_node;
4594 ia32_address_t addr;
4596 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4597 /* no prefetch at all, route memory */
4598 return be_transform_node(get_Builtin_mem(node));
4601 param = get_Builtin_param(node, 1);
4602 tv = get_Const_tarval(param);
4603 rw = get_tarval_long(tv);
4605 /* construct load address */
4606 memset(&addr, 0, sizeof(addr));
4607 ptr = get_Builtin_param(node, 0);
4608 ia32_create_address_mode(&addr, ptr, 0);
4615 base = be_transform_node(base);
4618 if (index == NULL) {
4621 index = be_transform_node(index);
4624 dbgi = get_irn_dbg_info(node);
4625 block = be_transform_node(get_nodes_block(node));
4626 mem = be_transform_node(get_Builtin_mem(node));
4628 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4629 /* we have 3DNow!, this was already checked above */
4630 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4631 } else if (ia32_cg_config.use_sse_prefetch) {
4632 /* note: rw == 1 is IGNORED in that case */
4633 param = get_Builtin_param(node, 2);
4634 tv = get_Const_tarval(param);
4635 locality = get_tarval_long(tv);
4637 /* SSE style prefetch */
4640 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4643 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4646 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4649 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4653 assert(ia32_cg_config.use_3dnow_prefetch);
4654 /* 3DNow! style prefetch */
4655 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4658 set_irn_pinned(new_node, get_irn_pinned(node));
4659 set_ia32_op_type(new_node, ia32_AddrModeS);
4660 set_ia32_ls_mode(new_node, mode_Bu);
4661 set_address(new_node, &addr);
4663 SET_IA32_ORIG_NODE(new_node, node);
4665 be_dep_on_frame(new_node);
4666 return new_r_Proj(current_ir_graph, block, new_node, mode_M, pn_ia32_Prefetch_M);
4670 * Transform bsf like node
4672 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4674 ir_node *param = get_Builtin_param(node, 0);
4675 dbg_info *dbgi = get_irn_dbg_info(node);
4677 ir_node *block = get_nodes_block(node);
4678 ir_node *new_block = be_transform_node(block);
4680 ia32_address_mode_t am;
4681 ia32_address_t *addr = &am.addr;
4684 match_arguments(&am, block, NULL, param, NULL, match_am);
4686 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4687 set_am_attributes(cnt, &am);
4688 set_ia32_ls_mode(cnt, get_irn_mode(param));
4690 SET_IA32_ORIG_NODE(cnt, node);
4691 return fix_mem_proj(cnt, &am);
4695 * Transform builtin ffs.
4697 static ir_node *gen_ffs(ir_node *node)
4699 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
4700 ir_node *real = skip_Proj(bsf);
4701 dbg_info *dbgi = get_irn_dbg_info(real);
4702 ir_node *block = get_nodes_block(real);
4703 ir_node *flag, *set, *conv, *neg, *or;
4706 if (get_irn_mode(real) != mode_T) {
4707 set_irn_mode(real, mode_T);
4708 bsf = new_r_Proj(current_ir_graph, block, real, mode_Iu, pn_ia32_res);
4711 flag = new_r_Proj(current_ir_graph, block, real, mode_b, pn_ia32_flags);
4714 set = new_bd_ia32_Set(dbgi, block, flag, pn_Cmp_Eq, 0);
4715 SET_IA32_ORIG_NODE(set, node);
4718 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
4719 SET_IA32_ORIG_NODE(conv, node);
4722 neg = new_bd_ia32_Neg(dbgi, block, conv);
4725 or = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
4726 set_ia32_commutative(or);
4729 return new_bd_ia32_Add(dbgi, block, noreg_GP, noreg_GP, nomem, or, create_Immediate(NULL, 0, 1));
4733 * Transform builtin clz.
4735 static ir_node *gen_clz(ir_node *node)
4737 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
4738 ir_node *real = skip_Proj(bsr);
4739 dbg_info *dbgi = get_irn_dbg_info(real);
4740 ir_node *block = get_nodes_block(real);
4741 ir_node *imm = create_Immediate(NULL, 0, 31);
4743 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
4747 * Transform builtin ctz.
4749 static ir_node *gen_ctz(ir_node *node)
4751 return gen_unop_AM(node, new_bd_ia32_Bsf);
4755 * Transform builtin parity.
4757 static ir_node *gen_parity(ir_node *node)
4759 ir_node *param = get_Builtin_param(node, 0);
4760 dbg_info *dbgi = get_irn_dbg_info(node);
4762 ir_node *block = get_nodes_block(node);
4764 ir_node *new_block = be_transform_node(block);
4765 ir_node *imm, *cmp, *new_node;
4767 ia32_address_mode_t am;
4768 ia32_address_t *addr = &am.addr;
4772 match_arguments(&am, block, NULL, param, NULL, match_am);
4773 imm = create_Immediate(NULL, 0, 0);
4774 cmp = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
4775 addr->mem, imm, am.new_op2, am.ins_permuted, 0);
4776 set_am_attributes(cmp, &am);
4777 set_ia32_ls_mode(cmp, mode_Iu);
4779 SET_IA32_ORIG_NODE(cmp, node);
4781 cmp = fix_mem_proj(cmp, &am);
4784 new_node = new_bd_ia32_Set(dbgi, new_block, cmp, ia32_pn_Cmp_parity, 0);
4785 SET_IA32_ORIG_NODE(new_node, node);
4788 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
4789 nomem, new_node, mode_Bu);
4790 SET_IA32_ORIG_NODE(new_node, node);
4795 * Transform builtin popcount
4797 static ir_node *gen_popcount(ir_node *node) {
4798 ir_node *param = get_Builtin_param(node, 0);
4799 dbg_info *dbgi = get_irn_dbg_info(node);
4801 ir_node *block = get_nodes_block(node);
4802 ir_node *new_block = be_transform_node(block);
4805 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
4807 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
4808 if (ia32_cg_config.use_popcnt) {
4809 ia32_address_mode_t am;
4810 ia32_address_t *addr = &am.addr;
4813 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
4815 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4816 set_am_attributes(cnt, &am);
4817 set_ia32_ls_mode(cnt, get_irn_mode(param));
4819 SET_IA32_ORIG_NODE(cnt, node);
4820 return fix_mem_proj(cnt, &am);
4823 new_param = be_transform_node(param);
4825 /* do the standard popcount algo */
4827 /* m1 = x & 0x55555555 */
4828 imm = create_Immediate(NULL, 0, 0x55555555);
4829 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
4832 simm = create_Immediate(NULL, 0, 1);
4833 s1 = new_bd_ia32_Shl(dbgi, new_block, new_param, simm);
4835 /* m2 = s1 & 0x55555555 */
4836 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
4839 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
4841 /* m4 = m3 & 0x33333333 */
4842 imm = create_Immediate(NULL, 0, 0x33333333);
4843 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
4846 simm = create_Immediate(NULL, 0, 2);
4847 s2 = new_bd_ia32_Shl(dbgi, new_block, m3, simm);
4849 /* m5 = s2 & 0x33333333 */
4850 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
4853 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
4855 /* m7 = m6 & 0x0F0F0F0F */
4856 imm = create_Immediate(NULL, 0, 0x0F0F0F0F);
4857 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
4860 simm = create_Immediate(NULL, 0, 4);
4861 s3 = new_bd_ia32_Shl(dbgi, new_block, m6, simm);
4863 /* m8 = s3 & 0x0F0F0F0F */
4864 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
4867 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
4869 /* m10 = m9 & 0x00FF00FF */
4870 imm = create_Immediate(NULL, 0, 0x00FF00FF);
4871 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
4874 simm = create_Immediate(NULL, 0, 8);
4875 s4 = new_bd_ia32_Shl(dbgi, new_block, m9, simm);
4877 /* m11 = s4 & 0x00FF00FF */
4878 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
4880 /* m12 = m10 + m11 */
4881 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
4883 /* m13 = m12 & 0x0000FFFF */
4884 imm = create_Immediate(NULL, 0, 0x0000FFFF);
4885 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
4887 /* s5 = m12 >> 16 */
4888 simm = create_Immediate(NULL, 0, 16);
4889 s5 = new_bd_ia32_Shl(dbgi, new_block, m12, simm);
4891 /* res = m13 + s5 */
4892 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
4896 * Transform builtin byte swap.
4898 static ir_node *gen_bswap(ir_node *node) {
4899 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
4900 dbg_info *dbgi = get_irn_dbg_info(node);
4902 ir_node *block = get_nodes_block(node);
4903 ir_node *new_block = be_transform_node(block);
4904 ir_mode *mode = get_irn_mode(param);
4905 unsigned size = get_mode_size_bits(mode);
4906 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
4910 if (ia32_cg_config.use_i486) {
4911 /* swap available */
4912 return new_bd_ia32_Bswap(dbgi, new_block, param);
4914 s1 = new_bd_ia32_Shl(dbgi, new_block, param, create_Immediate(NULL, 0, 24));
4915 s2 = new_bd_ia32_Shl(dbgi, new_block, param, create_Immediate(NULL, 0, 8));
4917 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, create_Immediate(NULL, 0, 0xFF00));
4918 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
4920 s3 = new_bd_ia32_Shr(dbgi, new_block, param, create_Immediate(NULL, 0, 8));
4922 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, create_Immediate(NULL, 0, 0xFF0000));
4923 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
4925 s4 = new_bd_ia32_Shr(dbgi, new_block, param, create_Immediate(NULL, 0, 24));
4926 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
4929 /* swap16 always available */
4930 return new_bd_ia32_Bswap16(dbgi, new_block, param);
4933 panic("Invalid bswap size (%d)", size);
4938 * Transform Builtin node.
4940 static ir_node *gen_Builtin(ir_node *node) {
4941 ir_builtin_kind kind = get_Builtin_kind(node);
4945 return gen_trap(node);
4946 case ir_bk_debugbreak:
4947 return gen_debugbreak(node);
4948 case ir_bk_return_address:
4949 return gen_return_address(node);
4950 case ir_bk_frame_addess:
4951 return gen_frame_address(node);
4952 case ir_bk_prefetch:
4953 return gen_prefetch(node);
4955 return gen_ffs(node);
4957 return gen_clz(node);
4959 return gen_ctz(node);
4961 return gen_parity(node);
4962 case ir_bk_popcount:
4963 return gen_popcount(node);
4965 return gen_bswap(node);
4967 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
4971 * Transform Proj(Builtin) node.
4973 static ir_node *gen_Proj_Builtin(ir_node *proj) {
4974 ir_node *node = get_Proj_pred(proj);
4975 ir_node *new_node = be_transform_node(node);
4976 ir_builtin_kind kind = get_Builtin_kind(node);
4979 case ir_bk_return_address:
4980 case ir_bk_frame_addess:
4985 case ir_bk_popcount:
4987 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
4990 case ir_bk_debugbreak:
4991 case ir_bk_prefetch:
4992 assert(get_Proj_proj(proj) == pn_Builtin_M);
4995 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
4998 static ir_node *gen_be_IncSP(ir_node *node)
5000 ir_node *res = be_duplicate_node(node);
5001 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5007 * Transform the Projs from a be_Call.
5009 static ir_node *gen_Proj_be_Call(ir_node *node)
5011 ir_node *block = be_transform_node(get_nodes_block(node));
5012 ir_node *call = get_Proj_pred(node);
5013 ir_node *new_call = be_transform_node(call);
5014 ir_graph *irg = current_ir_graph;
5015 dbg_info *dbgi = get_irn_dbg_info(node);
5016 ir_type *method_type = be_Call_get_type(call);
5017 int n_res = get_method_n_ress(method_type);
5018 long proj = get_Proj_proj(node);
5019 ir_mode *mode = get_irn_mode(node);
5023 /* The following is kinda tricky: If we're using SSE, then we have to
5024 * move the result value of the call in floating point registers to an
5025 * xmm register, we therefore construct a GetST0 -> xLoad sequence
5026 * after the call, we have to make sure to correctly make the
5027 * MemProj and the result Proj use these 2 nodes
5029 if (proj == pn_be_Call_M_regular) {
5030 // get new node for result, are we doing the sse load/store hack?
5031 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5032 ir_node *call_res_new;
5033 ir_node *call_res_pred = NULL;
5035 if (call_res != NULL) {
5036 call_res_new = be_transform_node(call_res);
5037 call_res_pred = get_Proj_pred(call_res_new);
5040 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
5041 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5044 assert(is_ia32_xLoad(call_res_pred));
5045 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5049 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5050 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5052 ir_node *frame = get_irg_frame(irg);
5054 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5057 /* in case there is no memory output: create one to serialize the copy
5059 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5060 pn_be_Call_M_regular);
5061 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5062 pn_be_Call_first_res);
5064 /* store st(0) onto stack */
5065 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, call_mem,
5067 set_ia32_op_type(fstp, ia32_AddrModeD);
5068 set_ia32_use_frame(fstp);
5070 /* load into SSE register */
5071 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg_GP, fstp, mode);
5072 set_ia32_op_type(sse_load, ia32_AddrModeS);
5073 set_ia32_use_frame(sse_load);
5075 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5081 /* transform call modes */
5082 if (mode_is_data(mode)) {
5083 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5087 /* Map from be_Call to ia32_Call proj number */
5088 if (proj == pn_be_Call_sp) {
5089 proj = pn_ia32_Call_stack;
5090 } else if (proj == pn_be_Call_M_regular) {
5091 proj = pn_ia32_Call_M;
5093 arch_register_req_t const *const req = arch_get_register_req_out(node);
5094 int const n_outs = arch_irn_get_n_outs(new_call);
5097 assert(proj >= pn_be_Call_first_res);
5098 assert(req->type & arch_register_req_type_limited);
5100 for (i = 0; i < n_outs; ++i) {
5101 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
5103 if (!(new_req->type & arch_register_req_type_limited) ||
5104 new_req->cls != req->cls ||
5105 *new_req->limited != *req->limited)
5114 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5116 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5118 case pn_ia32_Call_stack:
5119 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
5122 case pn_ia32_Call_fpcw:
5123 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
5131 * Transform the Projs from a Cmp.
5133 static ir_node *gen_Proj_Cmp(ir_node *node)
5135 /* this probably means not all mode_b nodes were lowered... */
5136 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5141 * Transform the Projs from a Bound.
5143 static ir_node *gen_Proj_Bound(ir_node *node)
5145 ir_node *new_node, *block;
5146 ir_node *pred = get_Proj_pred(node);
5148 switch (get_Proj_proj(node)) {
5150 return be_transform_node(get_Bound_mem(pred));
5151 case pn_Bound_X_regular:
5152 new_node = be_transform_node(pred);
5153 block = get_nodes_block(new_node);
5154 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
5155 case pn_Bound_X_except:
5156 new_node = be_transform_node(pred);
5157 block = get_nodes_block(new_node);
5158 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
5160 return be_transform_node(get_Bound_index(pred));
5162 panic("unsupported Proj from Bound");
5166 static ir_node *gen_Proj_ASM(ir_node *node)
5168 ir_mode *mode = get_irn_mode(node);
5169 ir_node *pred = get_Proj_pred(node);
5170 ir_node *new_pred = be_transform_node(pred);
5171 ir_node *block = get_nodes_block(new_pred);
5172 long pos = get_Proj_proj(node);
5174 if (mode == mode_M) {
5175 pos = arch_irn_get_n_outs(new_pred) + 1;
5176 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5178 } else if (mode_is_float(mode)) {
5181 panic("unexpected proj mode at ASM");
5184 return new_r_Proj(current_ir_graph, block, new_pred, mode, pos);
5188 * Transform and potentially renumber Proj nodes.
5190 static ir_node *gen_Proj(ir_node *node)
5192 ir_node *pred = get_Proj_pred(node);
5195 switch (get_irn_opcode(pred)) {
5197 proj = get_Proj_proj(node);
5198 if (proj == pn_Store_M) {
5199 return be_transform_node(pred);
5201 panic("No idea how to transform proj->Store");
5204 return gen_Proj_Load(node);
5206 return gen_Proj_ASM(node);
5208 return gen_Proj_Builtin(node);
5212 return gen_Proj_DivMod(node);
5214 return gen_Proj_CopyB(node);
5216 return gen_Proj_Quot(node);
5218 return gen_Proj_be_SubSP(node);
5220 return gen_Proj_be_AddSP(node);
5222 return gen_Proj_be_Call(node);
5224 return gen_Proj_Cmp(node);
5226 return gen_Proj_Bound(node);
5228 proj = get_Proj_proj(node);
5230 case pn_Start_X_initial_exec: {
5231 ir_node *block = get_nodes_block(pred);
5232 ir_node *new_block = be_transform_node(block);
5233 dbg_info *dbgi = get_irn_dbg_info(node);
5234 /* we exchange the ProjX with a jump */
5235 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
5240 case pn_Start_P_tls:
5241 return gen_Proj_tls(node);
5246 if (is_ia32_l_FloattoLL(pred)) {
5247 return gen_Proj_l_FloattoLL(node);
5249 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5253 ir_mode *mode = get_irn_mode(node);
5254 if (ia32_mode_needs_gp_reg(mode)) {
5255 ir_node *new_pred = be_transform_node(pred);
5256 ir_node *block = be_transform_node(get_nodes_block(node));
5257 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5258 mode_Iu, get_Proj_proj(node));
5259 #ifdef DEBUG_libfirm
5260 new_proj->node_nr = node->node_nr;
5266 return be_duplicate_node(node);
5270 * Enters all transform functions into the generic pointer
5272 static void register_transformers(void)
5274 /* first clear the generic function pointer for all ops */
5275 clear_irp_opcodes_generic_func();
5277 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5278 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5317 /* transform ops from intrinsic lowering */
5329 GEN(ia32_l_LLtoFloat);
5330 GEN(ia32_l_FloattoLL);
5336 /* we should never see these nodes */
5351 /* handle builtins */
5354 /* handle generic backend nodes */
5368 * Pre-transform all unknown and noreg nodes.
5370 static void ia32_pretransform_node(void)
5372 ia32_code_gen_t *cg = env_cg;
5374 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5375 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5376 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5377 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5378 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5379 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5381 nomem = get_irg_no_mem(current_ir_graph);
5382 noreg_GP = ia32_new_NoReg_gp(cg);
5388 * Walker, checks if all ia32 nodes producing more than one result have their
5389 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
5391 static void add_missing_keep_walker(ir_node *node, void *data)
5394 unsigned found_projs = 0;
5395 const ir_edge_t *edge;
5396 ir_mode *mode = get_irn_mode(node);
5401 if (!is_ia32_irn(node))
5404 n_outs = arch_irn_get_n_outs(node);
5407 if (is_ia32_SwitchJmp(node))
5410 assert(n_outs < (int) sizeof(unsigned) * 8);
5411 foreach_out_edge(node, edge) {
5412 ir_node *proj = get_edge_src_irn(edge);
5415 /* The node could be kept */
5419 if (get_irn_mode(proj) == mode_M)
5422 pn = get_Proj_proj(proj);
5423 assert(pn < n_outs);
5424 found_projs |= 1 << pn;
5428 /* are keeps missing? */
5430 for (i = 0; i < n_outs; ++i) {
5433 const arch_register_req_t *req;
5434 const arch_register_class_t *cls;
5436 if (found_projs & (1 << i)) {
5440 req = get_ia32_out_req(node, i);
5445 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
5449 block = get_nodes_block(node);
5450 in[0] = new_r_Proj(current_ir_graph, block, node,
5451 arch_register_class_mode(cls), i);
5452 if (last_keep != NULL) {
5453 be_Keep_add_node(last_keep, cls, in[0]);
5455 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
5456 if (sched_is_scheduled(node)) {
5457 sched_add_after(node, last_keep);
5464 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5467 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5469 ir_graph *irg = be_get_birg_irg(cg->birg);
5470 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5473 /* do the transformation */
5474 void ia32_transform_graph(ia32_code_gen_t *cg)
5478 register_transformers();
5480 initial_fpcw = NULL;
5482 BE_TIMER_PUSH(t_heights);
5483 heights = heights_new(cg->irg);
5484 BE_TIMER_POP(t_heights);
5485 ia32_calculate_non_address_mode_nodes(cg->birg);
5487 /* the transform phase is not safe for CSE (yet) because several nodes get
5488 * attributes set after their creation */
5489 cse_last = get_opt_cse();
5492 be_transform_graph(cg->birg, ia32_pretransform_node);
5494 set_opt_cse(cse_last);
5496 ia32_free_non_address_mode_nodes();
5497 heights_free(heights);
5501 void ia32_init_transform(void)
5503 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");