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 ir_graph *irg = current_ir_graph;
3214 dbg_info *dbgi = get_irn_dbg_info(node);
3215 ir_mode *mode = get_irn_mode(node);
3216 ir_node *fist, *load, *mem;
3218 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3219 set_irn_pinned(fist, op_pin_state_floats);
3220 set_ia32_use_frame(fist);
3221 set_ia32_op_type(fist, ia32_AddrModeD);
3223 assert(get_mode_size_bits(mode) <= 32);
3224 /* exception we can only store signed 32 bit integers, so for unsigned
3225 we store a 64bit (signed) integer and load the lower bits */
3226 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3227 set_ia32_ls_mode(fist, mode_Ls);
3229 set_ia32_ls_mode(fist, mode_Is);
3231 SET_IA32_ORIG_NODE(fist, node);
3234 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3236 set_irn_pinned(load, op_pin_state_floats);
3237 set_ia32_use_frame(load);
3238 set_ia32_op_type(load, ia32_AddrModeS);
3239 set_ia32_ls_mode(load, mode_Is);
3240 if (get_ia32_ls_mode(fist) == mode_Ls) {
3241 ia32_attr_t *attr = get_ia32_attr(load);
3242 attr->data.need_64bit_stackent = 1;
3244 ia32_attr_t *attr = get_ia32_attr(load);
3245 attr->data.need_32bit_stackent = 1;
3247 SET_IA32_ORIG_NODE(load, node);
3249 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3253 * Creates a x87 strict Conv by placing a Store and a Load
3255 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3257 ir_node *block = get_nodes_block(node);
3258 ir_graph *irg = current_ir_graph;
3259 dbg_info *dbgi = get_irn_dbg_info(node);
3260 ir_node *frame = get_irg_frame(irg);
3261 ir_node *store, *load;
3264 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3265 set_ia32_use_frame(store);
3266 set_ia32_op_type(store, ia32_AddrModeD);
3267 SET_IA32_ORIG_NODE(store, node);
3269 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3270 set_ia32_use_frame(load);
3271 set_ia32_op_type(load, ia32_AddrModeS);
3272 SET_IA32_ORIG_NODE(load, node);
3274 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3278 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3279 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3281 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3283 func = get_mode_size_bits(mode) == 8 ?
3284 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3285 return func(dbgi, block, base, index, mem, val, mode);
3289 * Create a conversion from general purpose to x87 register
3291 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3293 ir_node *src_block = get_nodes_block(node);
3294 ir_node *block = be_transform_node(src_block);
3295 ir_graph *irg = current_ir_graph;
3296 dbg_info *dbgi = get_irn_dbg_info(node);
3297 ir_node *op = get_Conv_op(node);
3298 ir_node *new_op = NULL;
3300 ir_mode *store_mode;
3305 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3306 if (possible_int_mode_for_fp(src_mode)) {
3307 ia32_address_mode_t am;
3309 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3310 if (am.op_type == ia32_AddrModeS) {
3311 ia32_address_t *addr = &am.addr;
3313 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3314 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3316 set_am_attributes(fild, &am);
3317 SET_IA32_ORIG_NODE(fild, node);
3319 fix_mem_proj(fild, &am);
3324 if (new_op == NULL) {
3325 new_op = be_transform_node(op);
3328 mode = get_irn_mode(op);
3330 /* first convert to 32 bit signed if necessary */
3331 if (get_mode_size_bits(src_mode) < 32) {
3332 if (!upper_bits_clean(new_op, src_mode)) {
3333 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3334 SET_IA32_ORIG_NODE(new_op, node);
3339 assert(get_mode_size_bits(mode) == 32);
3342 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3344 set_ia32_use_frame(store);
3345 set_ia32_op_type(store, ia32_AddrModeD);
3346 set_ia32_ls_mode(store, mode_Iu);
3348 /* exception for 32bit unsigned, do a 64bit spill+load */
3349 if (!mode_is_signed(mode)) {
3352 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3354 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3355 noreg_GP, nomem, zero_const);
3357 set_ia32_use_frame(zero_store);
3358 set_ia32_op_type(zero_store, ia32_AddrModeD);
3359 add_ia32_am_offs_int(zero_store, 4);
3360 set_ia32_ls_mode(zero_store, mode_Iu);
3365 store = new_rd_Sync(dbgi, irg, block, 2, in);
3366 store_mode = mode_Ls;
3368 store_mode = mode_Is;
3372 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3374 set_ia32_use_frame(fild);
3375 set_ia32_op_type(fild, ia32_AddrModeS);
3376 set_ia32_ls_mode(fild, store_mode);
3378 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3384 * Create a conversion from one integer mode into another one
3386 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3387 dbg_info *dbgi, ir_node *block, ir_node *op,
3390 ir_node *new_block = be_transform_node(block);
3392 ir_mode *smaller_mode;
3393 ia32_address_mode_t am;
3394 ia32_address_t *addr = &am.addr;
3397 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3398 smaller_mode = src_mode;
3400 smaller_mode = tgt_mode;
3403 #ifdef DEBUG_libfirm
3405 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3410 match_arguments(&am, block, NULL, op, NULL,
3411 match_am | match_8bit_am | match_16bit_am);
3413 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3414 /* unnecessary conv. in theory it shouldn't have been AM */
3415 assert(is_ia32_NoReg_GP(addr->base));
3416 assert(is_ia32_NoReg_GP(addr->index));
3417 assert(is_NoMem(addr->mem));
3418 assert(am.addr.offset == 0);
3419 assert(am.addr.symconst_ent == NULL);
3423 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3424 addr->mem, am.new_op2, smaller_mode);
3425 set_am_attributes(new_node, &am);
3426 /* match_arguments assume that out-mode = in-mode, this isn't true here
3428 set_ia32_ls_mode(new_node, smaller_mode);
3429 SET_IA32_ORIG_NODE(new_node, node);
3430 new_node = fix_mem_proj(new_node, &am);
3435 * Transforms a Conv node.
3437 * @return The created ia32 Conv node
3439 static ir_node *gen_Conv(ir_node *node)
3441 ir_node *block = get_nodes_block(node);
3442 ir_node *new_block = be_transform_node(block);
3443 ir_node *op = get_Conv_op(node);
3444 ir_node *new_op = NULL;
3445 dbg_info *dbgi = get_irn_dbg_info(node);
3446 ir_mode *src_mode = get_irn_mode(op);
3447 ir_mode *tgt_mode = get_irn_mode(node);
3448 int src_bits = get_mode_size_bits(src_mode);
3449 int tgt_bits = get_mode_size_bits(tgt_mode);
3450 ir_node *res = NULL;
3452 assert(!mode_is_int(src_mode) || src_bits <= 32);
3453 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3455 if (src_mode == mode_b) {
3456 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3457 /* nothing to do, we already model bools as 0/1 ints */
3458 return be_transform_node(op);
3461 if (src_mode == tgt_mode) {
3462 if (get_Conv_strict(node)) {
3463 if (ia32_cg_config.use_sse2) {
3464 /* when we are in SSE mode, we can kill all strict no-op conversion */
3465 return be_transform_node(op);
3468 /* this should be optimized already, but who knows... */
3469 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3470 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3471 return be_transform_node(op);
3475 if (mode_is_float(src_mode)) {
3476 new_op = be_transform_node(op);
3477 /* we convert from float ... */
3478 if (mode_is_float(tgt_mode)) {
3480 /* Matze: I'm a bit unsure what the following is for? seems wrong
3482 if (src_mode == mode_E && tgt_mode == mode_D
3483 && !get_Conv_strict(node)) {
3484 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3490 if (ia32_cg_config.use_sse2) {
3491 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3492 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3494 set_ia32_ls_mode(res, tgt_mode);
3496 if (get_Conv_strict(node)) {
3497 /* if fp_no_float_fold is not set then we assume that we
3498 * don't have any float operations in a non
3499 * mode_float_arithmetic mode and can skip strict upconvs */
3500 if (src_bits < tgt_bits
3501 && !(get_irg_fp_model(current_ir_graph) & fp_no_float_fold)) {
3502 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3505 res = gen_x87_strict_conv(tgt_mode, new_op);
3506 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3510 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3515 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3516 if (ia32_cg_config.use_sse2) {
3517 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3519 set_ia32_ls_mode(res, src_mode);
3521 return gen_x87_fp_to_gp(node);
3525 /* we convert from int ... */
3526 if (mode_is_float(tgt_mode)) {
3528 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3529 if (ia32_cg_config.use_sse2) {
3530 new_op = be_transform_node(op);
3531 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3533 set_ia32_ls_mode(res, tgt_mode);
3535 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3536 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3537 res = gen_x87_gp_to_fp(node, src_mode);
3539 /* we need a strict-Conv, if the int mode has more bits than the
3541 if (float_mantissa < int_mantissa) {
3542 res = gen_x87_strict_conv(tgt_mode, res);
3543 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3547 } else if (tgt_mode == mode_b) {
3548 /* mode_b lowering already took care that we only have 0/1 values */
3549 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3550 src_mode, tgt_mode));
3551 return be_transform_node(op);
3554 if (src_bits == tgt_bits) {
3555 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3556 src_mode, tgt_mode));
3557 return be_transform_node(op);
3560 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3568 static ir_node *create_immediate_or_transform(ir_node *node,
3569 char immediate_constraint_type)
3571 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3572 if (new_node == NULL) {
3573 new_node = be_transform_node(node);
3579 * Transforms a FrameAddr into an ia32 Add.
3581 static ir_node *gen_be_FrameAddr(ir_node *node)
3583 ir_node *block = be_transform_node(get_nodes_block(node));
3584 ir_node *op = be_get_FrameAddr_frame(node);
3585 ir_node *new_op = be_transform_node(op);
3586 dbg_info *dbgi = get_irn_dbg_info(node);
3589 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3590 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3591 set_ia32_use_frame(new_node);
3593 SET_IA32_ORIG_NODE(new_node, node);
3599 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3601 static ir_node *gen_be_Return(ir_node *node)
3603 ir_graph *irg = current_ir_graph;
3604 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3605 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3606 ir_entity *ent = get_irg_entity(irg);
3607 ir_type *tp = get_entity_type(ent);
3612 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3613 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3615 int pn_ret_val, pn_ret_mem, arity, i;
3617 assert(ret_val != NULL);
3618 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3619 return be_duplicate_node(node);
3622 res_type = get_method_res_type(tp, 0);
3624 if (! is_Primitive_type(res_type)) {
3625 return be_duplicate_node(node);
3628 mode = get_type_mode(res_type);
3629 if (! mode_is_float(mode)) {
3630 return be_duplicate_node(node);
3633 assert(get_method_n_ress(tp) == 1);
3635 pn_ret_val = get_Proj_proj(ret_val);
3636 pn_ret_mem = get_Proj_proj(ret_mem);
3638 /* get the Barrier */
3639 barrier = get_Proj_pred(ret_val);
3641 /* get result input of the Barrier */
3642 ret_val = get_irn_n(barrier, pn_ret_val);
3643 new_ret_val = be_transform_node(ret_val);
3645 /* get memory input of the Barrier */
3646 ret_mem = get_irn_n(barrier, pn_ret_mem);
3647 new_ret_mem = be_transform_node(ret_mem);
3649 frame = get_irg_frame(irg);
3651 dbgi = get_irn_dbg_info(barrier);
3652 block = be_transform_node(get_nodes_block(barrier));
3654 /* store xmm0 onto stack */
3655 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
3656 new_ret_mem, new_ret_val);
3657 set_ia32_ls_mode(sse_store, mode);
3658 set_ia32_op_type(sse_store, ia32_AddrModeD);
3659 set_ia32_use_frame(sse_store);
3661 /* load into x87 register */
3662 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
3663 set_ia32_op_type(fld, ia32_AddrModeS);
3664 set_ia32_use_frame(fld);
3666 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3667 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3669 /* create a new barrier */
3670 arity = get_irn_arity(barrier);
3671 in = ALLOCAN(ir_node*, arity);
3672 for (i = 0; i < arity; ++i) {
3675 if (i == pn_ret_val) {
3677 } else if (i == pn_ret_mem) {
3680 ir_node *in = get_irn_n(barrier, i);
3681 new_in = be_transform_node(in);
3686 new_barrier = new_ir_node(dbgi, irg, block,
3687 get_irn_op(barrier), get_irn_mode(barrier),
3689 copy_node_attr(barrier, new_barrier);
3690 be_duplicate_deps(barrier, new_barrier);
3691 be_set_transformed_node(barrier, new_barrier);
3693 /* transform normally */
3694 return be_duplicate_node(node);
3698 * Transform a be_AddSP into an ia32_SubSP.
3700 static ir_node *gen_be_AddSP(ir_node *node)
3702 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3703 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3705 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3706 match_am | match_immediate);
3710 * Transform a be_SubSP into an ia32_AddSP
3712 static ir_node *gen_be_SubSP(ir_node *node)
3714 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3715 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3717 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3718 match_am | match_immediate);
3722 * Change some phi modes
3724 static ir_node *gen_Phi(ir_node *node)
3726 ir_node *block = be_transform_node(get_nodes_block(node));
3727 ir_graph *irg = current_ir_graph;
3728 dbg_info *dbgi = get_irn_dbg_info(node);
3729 ir_mode *mode = get_irn_mode(node);
3732 if (ia32_mode_needs_gp_reg(mode)) {
3733 /* we shouldn't have any 64bit stuff around anymore */
3734 assert(get_mode_size_bits(mode) <= 32);
3735 /* all integer operations are on 32bit registers now */
3737 } else if (mode_is_float(mode)) {
3738 if (ia32_cg_config.use_sse2) {
3745 /* phi nodes allow loops, so we use the old arguments for now
3746 * and fix this later */
3747 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3748 get_irn_in(node) + 1);
3749 copy_node_attr(node, phi);
3750 be_duplicate_deps(node, phi);
3752 be_enqueue_preds(node);
3760 static ir_node *gen_IJmp(ir_node *node)
3762 ir_node *block = get_nodes_block(node);
3763 ir_node *new_block = be_transform_node(block);
3764 dbg_info *dbgi = get_irn_dbg_info(node);
3765 ir_node *op = get_IJmp_target(node);
3767 ia32_address_mode_t am;
3768 ia32_address_t *addr = &am.addr;
3770 assert(get_irn_mode(op) == mode_P);
3772 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3774 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3775 addr->mem, am.new_op2);
3776 set_am_attributes(new_node, &am);
3777 SET_IA32_ORIG_NODE(new_node, node);
3779 new_node = fix_mem_proj(new_node, &am);
3785 * Transform a Bound node.
3787 static ir_node *gen_Bound(ir_node *node)
3790 ir_node *lower = get_Bound_lower(node);
3791 dbg_info *dbgi = get_irn_dbg_info(node);
3793 if (is_Const_0(lower)) {
3794 /* typical case for Java */
3795 ir_node *sub, *res, *flags, *block;
3796 ir_graph *irg = current_ir_graph;
3798 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3799 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3801 block = get_nodes_block(res);
3802 if (! is_Proj(res)) {
3804 set_irn_mode(sub, mode_T);
3805 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3807 sub = get_Proj_pred(res);
3809 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3810 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3811 SET_IA32_ORIG_NODE(new_node, node);
3813 panic("generic Bound not supported in ia32 Backend");
3819 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3821 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3822 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3824 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3825 match_immediate | match_mode_neutral);
3828 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3830 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3831 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3832 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3836 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3838 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3839 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3840 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3844 static ir_node *gen_ia32_l_Add(ir_node *node)
3846 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3847 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3848 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3849 match_commutative | match_am | match_immediate |
3850 match_mode_neutral);
3852 if (is_Proj(lowered)) {
3853 lowered = get_Proj_pred(lowered);
3855 assert(is_ia32_Add(lowered));
3856 set_irn_mode(lowered, mode_T);
3862 static ir_node *gen_ia32_l_Adc(ir_node *node)
3864 return gen_binop_flags(node, new_bd_ia32_Adc,
3865 match_commutative | match_am | match_immediate |
3866 match_mode_neutral);
3870 * Transforms a l_MulS into a "real" MulS node.
3872 * @return the created ia32 Mul node
3874 static ir_node *gen_ia32_l_Mul(ir_node *node)
3876 ir_node *left = get_binop_left(node);
3877 ir_node *right = get_binop_right(node);
3879 return gen_binop(node, left, right, new_bd_ia32_Mul,
3880 match_commutative | match_am | match_mode_neutral);
3884 * Transforms a l_IMulS into a "real" IMul1OPS node.
3886 * @return the created ia32 IMul1OP node
3888 static ir_node *gen_ia32_l_IMul(ir_node *node)
3890 ir_node *left = get_binop_left(node);
3891 ir_node *right = get_binop_right(node);
3893 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3894 match_commutative | match_am | match_mode_neutral);
3897 static ir_node *gen_ia32_l_Sub(ir_node *node)
3899 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3900 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3901 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3902 match_am | match_immediate | match_mode_neutral);
3904 if (is_Proj(lowered)) {
3905 lowered = get_Proj_pred(lowered);
3907 assert(is_ia32_Sub(lowered));
3908 set_irn_mode(lowered, mode_T);
3914 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3916 return gen_binop_flags(node, new_bd_ia32_Sbb,
3917 match_am | match_immediate | match_mode_neutral);
3921 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3922 * op1 - target to be shifted
3923 * op2 - contains bits to be shifted into target
3925 * Only op3 can be an immediate.
3927 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3928 ir_node *low, ir_node *count)
3930 ir_node *block = get_nodes_block(node);
3931 ir_node *new_block = be_transform_node(block);
3932 dbg_info *dbgi = get_irn_dbg_info(node);
3933 ir_node *new_high = be_transform_node(high);
3934 ir_node *new_low = be_transform_node(low);
3938 /* the shift amount can be any mode that is bigger than 5 bits, since all
3939 * other bits are ignored anyway */
3940 while (is_Conv(count) &&
3941 get_irn_n_edges(count) == 1 &&
3942 mode_is_int(get_irn_mode(count))) {
3943 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3944 count = get_Conv_op(count);
3946 new_count = create_immediate_or_transform(count, 0);
3948 if (is_ia32_l_ShlD(node)) {
3949 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3952 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3955 SET_IA32_ORIG_NODE(new_node, node);
3960 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3962 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
3963 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
3964 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3965 return gen_lowered_64bit_shifts(node, high, low, count);
3968 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3970 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
3971 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
3972 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3973 return gen_lowered_64bit_shifts(node, high, low, count);
3976 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3978 ir_node *src_block = get_nodes_block(node);
3979 ir_node *block = be_transform_node(src_block);
3980 ir_graph *irg = current_ir_graph;
3981 dbg_info *dbgi = get_irn_dbg_info(node);
3982 ir_node *frame = get_irg_frame(irg);
3983 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3984 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3985 ir_node *new_val_low = be_transform_node(val_low);
3986 ir_node *new_val_high = be_transform_node(val_high);
3988 ir_node *sync, *fild, *res;
3989 ir_node *store_low, *store_high;
3991 if (ia32_cg_config.use_sse2) {
3992 panic("ia32_l_LLtoFloat not implemented for SSE2");
3996 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
3998 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4000 SET_IA32_ORIG_NODE(store_low, node);
4001 SET_IA32_ORIG_NODE(store_high, node);
4003 set_ia32_use_frame(store_low);
4004 set_ia32_use_frame(store_high);
4005 set_ia32_op_type(store_low, ia32_AddrModeD);
4006 set_ia32_op_type(store_high, ia32_AddrModeD);
4007 set_ia32_ls_mode(store_low, mode_Iu);
4008 set_ia32_ls_mode(store_high, mode_Is);
4009 add_ia32_am_offs_int(store_high, 4);
4013 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4016 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4018 set_ia32_use_frame(fild);
4019 set_ia32_op_type(fild, ia32_AddrModeS);
4020 set_ia32_ls_mode(fild, mode_Ls);
4022 SET_IA32_ORIG_NODE(fild, node);
4024 res = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4026 if (! mode_is_signed(get_irn_mode(val_high))) {
4027 ia32_address_mode_t am;
4029 ir_node *count = create_Immediate(NULL, 0, 31);
4032 am.addr.base = noreg_GP;
4033 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4034 am.addr.mem = nomem;
4037 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4038 am.addr.use_frame = 0;
4039 am.addr.frame_entity = NULL;
4040 am.addr.symconst_sign = 0;
4041 am.ls_mode = mode_F;
4042 am.mem_proj = nomem;
4043 am.op_type = ia32_AddrModeS;
4045 am.new_op2 = ia32_new_NoReg_vfp(env_cg);
4046 am.pinned = op_pin_state_floats;
4048 am.ins_permuted = 0;
4050 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4051 am.new_op1, am.new_op2, get_fpcw());
4052 set_am_attributes(fadd, &am);
4054 set_irn_mode(fadd, mode_T);
4055 res = new_rd_Proj(NULL, irg, block, fadd, mode_vfp, pn_ia32_res);
4060 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4062 ir_node *src_block = get_nodes_block(node);
4063 ir_node *block = be_transform_node(src_block);
4064 ir_graph *irg = current_ir_graph;
4065 dbg_info *dbgi = get_irn_dbg_info(node);
4066 ir_node *frame = get_irg_frame(irg);
4067 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4068 ir_node *new_val = be_transform_node(val);
4069 ir_node *fist, *mem;
4071 mem = gen_vfist(dbgi, irg, block, frame, noreg_GP, nomem, new_val, &fist);
4072 SET_IA32_ORIG_NODE(fist, node);
4073 set_ia32_use_frame(fist);
4074 set_ia32_op_type(fist, ia32_AddrModeD);
4075 set_ia32_ls_mode(fist, mode_Ls);
4081 * the BAD transformer.
4083 static ir_node *bad_transform(ir_node *node)
4085 panic("No transform function for %+F available.", node);
4089 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4091 ir_graph *irg = current_ir_graph;
4092 ir_node *block = be_transform_node(get_nodes_block(node));
4093 ir_node *pred = get_Proj_pred(node);
4094 ir_node *new_pred = be_transform_node(pred);
4095 ir_node *frame = get_irg_frame(irg);
4096 dbg_info *dbgi = get_irn_dbg_info(node);
4097 long pn = get_Proj_proj(node);
4102 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4103 SET_IA32_ORIG_NODE(load, node);
4104 set_ia32_use_frame(load);
4105 set_ia32_op_type(load, ia32_AddrModeS);
4106 set_ia32_ls_mode(load, mode_Iu);
4107 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4108 * 32 bit from it with this particular load */
4109 attr = get_ia32_attr(load);
4110 attr->data.need_64bit_stackent = 1;
4112 if (pn == pn_ia32_l_FloattoLL_res_high) {
4113 add_ia32_am_offs_int(load, 4);
4115 assert(pn == pn_ia32_l_FloattoLL_res_low);
4118 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4124 * Transform the Projs of an AddSP.
4126 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4128 ir_node *block = be_transform_node(get_nodes_block(node));
4129 ir_node *pred = get_Proj_pred(node);
4130 ir_node *new_pred = be_transform_node(pred);
4131 ir_graph *irg = current_ir_graph;
4132 dbg_info *dbgi = get_irn_dbg_info(node);
4133 long proj = get_Proj_proj(node);
4135 if (proj == pn_be_AddSP_sp) {
4136 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4137 pn_ia32_SubSP_stack);
4138 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4140 } else if (proj == pn_be_AddSP_res) {
4141 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4142 pn_ia32_SubSP_addr);
4143 } else if (proj == pn_be_AddSP_M) {
4144 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4147 panic("No idea how to transform proj->AddSP");
4151 * Transform the Projs of a SubSP.
4153 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4155 ir_node *block = be_transform_node(get_nodes_block(node));
4156 ir_node *pred = get_Proj_pred(node);
4157 ir_node *new_pred = be_transform_node(pred);
4158 ir_graph *irg = current_ir_graph;
4159 dbg_info *dbgi = get_irn_dbg_info(node);
4160 long proj = get_Proj_proj(node);
4162 if (proj == pn_be_SubSP_sp) {
4163 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4164 pn_ia32_AddSP_stack);
4165 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4167 } else if (proj == pn_be_SubSP_M) {
4168 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4171 panic("No idea how to transform proj->SubSP");
4175 * Transform and renumber the Projs from a Load.
4177 static ir_node *gen_Proj_Load(ir_node *node)
4180 ir_node *block = be_transform_node(get_nodes_block(node));
4181 ir_node *pred = get_Proj_pred(node);
4182 ir_graph *irg = current_ir_graph;
4183 dbg_info *dbgi = get_irn_dbg_info(node);
4184 long proj = get_Proj_proj(node);
4186 /* loads might be part of source address mode matches, so we don't
4187 * transform the ProjMs yet (with the exception of loads whose result is
4190 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4193 /* this is needed, because sometimes we have loops that are only
4194 reachable through the ProjM */
4195 be_enqueue_preds(node);
4196 /* do it in 2 steps, to silence firm verifier */
4197 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4198 set_Proj_proj(res, pn_ia32_mem);
4202 /* renumber the proj */
4203 new_pred = be_transform_node(pred);
4204 if (is_ia32_Load(new_pred)) {
4207 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4209 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4210 case pn_Load_X_regular:
4211 return new_rd_Jmp(dbgi, irg, block);
4212 case pn_Load_X_except:
4213 /* This Load might raise an exception. Mark it. */
4214 set_ia32_exc_label(new_pred, 1);
4215 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4219 } else if (is_ia32_Conv_I2I(new_pred) ||
4220 is_ia32_Conv_I2I8Bit(new_pred)) {
4221 set_irn_mode(new_pred, mode_T);
4222 if (proj == pn_Load_res) {
4223 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4224 } else if (proj == pn_Load_M) {
4225 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4227 } else if (is_ia32_xLoad(new_pred)) {
4230 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4232 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4233 case pn_Load_X_regular:
4234 return new_rd_Jmp(dbgi, irg, block);
4235 case pn_Load_X_except:
4236 /* This Load might raise an exception. Mark it. */
4237 set_ia32_exc_label(new_pred, 1);
4238 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4242 } else if (is_ia32_vfld(new_pred)) {
4245 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4247 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4248 case pn_Load_X_regular:
4249 return new_rd_Jmp(dbgi, irg, block);
4250 case pn_Load_X_except:
4251 /* This Load might raise an exception. Mark it. */
4252 set_ia32_exc_label(new_pred, 1);
4253 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4258 /* can happen for ProJMs when source address mode happened for the
4261 /* however it should not be the result proj, as that would mean the
4262 load had multiple users and should not have been used for
4264 if (proj != pn_Load_M) {
4265 panic("internal error: transformed node not a Load");
4267 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4270 panic("No idea how to transform proj");
4274 * Transform and renumber the Projs from a DivMod like instruction.
4276 static ir_node *gen_Proj_DivMod(ir_node *node)
4278 ir_node *block = be_transform_node(get_nodes_block(node));
4279 ir_node *pred = get_Proj_pred(node);
4280 ir_node *new_pred = be_transform_node(pred);
4281 ir_graph *irg = current_ir_graph;
4282 dbg_info *dbgi = get_irn_dbg_info(node);
4283 long proj = get_Proj_proj(node);
4285 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4287 switch (get_irn_opcode(pred)) {
4291 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4293 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4294 case pn_Div_X_regular:
4295 return new_rd_Jmp(dbgi, irg, block);
4296 case pn_Div_X_except:
4297 set_ia32_exc_label(new_pred, 1);
4298 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4306 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4308 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4309 case pn_Mod_X_except:
4310 set_ia32_exc_label(new_pred, 1);
4311 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4319 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4320 case pn_DivMod_res_div:
4321 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4322 case pn_DivMod_res_mod:
4323 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4324 case pn_DivMod_X_regular:
4325 return new_rd_Jmp(dbgi, irg, block);
4326 case pn_DivMod_X_except:
4327 set_ia32_exc_label(new_pred, 1);
4328 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4337 panic("No idea how to transform proj->DivMod");
4341 * Transform and renumber the Projs from a CopyB.
4343 static ir_node *gen_Proj_CopyB(ir_node *node)
4345 ir_node *block = be_transform_node(get_nodes_block(node));
4346 ir_node *pred = get_Proj_pred(node);
4347 ir_node *new_pred = be_transform_node(pred);
4348 ir_graph *irg = current_ir_graph;
4349 dbg_info *dbgi = get_irn_dbg_info(node);
4350 long proj = get_Proj_proj(node);
4353 case pn_CopyB_M_regular:
4354 if (is_ia32_CopyB_i(new_pred)) {
4355 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4356 } else if (is_ia32_CopyB(new_pred)) {
4357 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4364 panic("No idea how to transform proj->CopyB");
4368 * Transform and renumber the Projs from a Quot.
4370 static ir_node *gen_Proj_Quot(ir_node *node)
4372 ir_node *block = be_transform_node(get_nodes_block(node));
4373 ir_node *pred = get_Proj_pred(node);
4374 ir_node *new_pred = be_transform_node(pred);
4375 ir_graph *irg = current_ir_graph;
4376 dbg_info *dbgi = get_irn_dbg_info(node);
4377 long proj = get_Proj_proj(node);
4381 if (is_ia32_xDiv(new_pred)) {
4382 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4383 } else if (is_ia32_vfdiv(new_pred)) {
4384 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4388 if (is_ia32_xDiv(new_pred)) {
4389 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4390 } else if (is_ia32_vfdiv(new_pred)) {
4391 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4394 case pn_Quot_X_regular:
4395 case pn_Quot_X_except:
4400 panic("No idea how to transform proj->Quot");
4403 static ir_node *gen_be_Call(ir_node *node)
4405 dbg_info *const dbgi = get_irn_dbg_info(node);
4406 ir_graph *const irg = current_ir_graph;
4407 ir_node *const src_block = get_nodes_block(node);
4408 ir_node *const block = be_transform_node(src_block);
4409 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4410 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4411 ir_node *const sp = be_transform_node(src_sp);
4412 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4413 ia32_address_mode_t am;
4414 ia32_address_t *const addr = &am.addr;
4419 ir_node * eax = noreg_GP;
4420 ir_node * ecx = noreg_GP;
4421 ir_node * edx = noreg_GP;
4422 unsigned const pop = be_Call_get_pop(node);
4423 ir_type *const call_tp = be_Call_get_type(node);
4425 /* Run the x87 simulator if the call returns a float value */
4426 if (get_method_n_ress(call_tp) > 0) {
4427 ir_type *const res_type = get_method_res_type(call_tp, 0);
4428 ir_mode *const res_mode = get_type_mode(res_type);
4430 if (res_mode != NULL && mode_is_float(res_mode)) {
4431 env_cg->do_x87_sim = 1;
4435 /* We do not want be_Call direct calls */
4436 assert(be_Call_get_entity(node) == NULL);
4438 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4439 match_am | match_immediate);
4441 i = get_irn_arity(node) - 1;
4442 fpcw = be_transform_node(get_irn_n(node, i--));
4443 for (; i >= be_pos_Call_first_arg; --i) {
4444 arch_register_req_t const *const req = arch_get_register_req(node, i);
4445 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4447 assert(req->type == arch_register_req_type_limited);
4448 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4450 switch (*req->limited) {
4451 case 1 << REG_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4452 case 1 << REG_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4453 case 1 << REG_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4454 default: panic("Invalid GP register for register parameter");
4458 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4459 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4460 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4461 set_am_attributes(call, &am);
4462 call = fix_mem_proj(call, &am);
4464 if (get_irn_pinned(node) == op_pin_state_pinned)
4465 set_irn_pinned(call, op_pin_state_pinned);
4467 SET_IA32_ORIG_NODE(call, node);
4472 * Transform Builtin trap
4474 static ir_node *gen_trap(ir_node *node) {
4475 dbg_info *dbgi = get_irn_dbg_info(node);
4476 ir_node *block = be_transform_node(get_nodes_block(node));
4477 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4479 return new_bd_ia32_UD2(dbgi, block, mem);
4483 * Transform Builtin debugbreak
4485 static ir_node *gen_debugbreak(ir_node *node) {
4486 dbg_info *dbgi = get_irn_dbg_info(node);
4487 ir_node *block = be_transform_node(get_nodes_block(node));
4488 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4490 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4494 * Transform Builtin return_address
4496 static ir_node *gen_return_address(ir_node *node) {
4497 ir_node *param = get_Builtin_param(node, 0);
4498 ir_node *frame = get_Builtin_param(node, 1);
4499 dbg_info *dbgi = get_irn_dbg_info(node);
4500 tarval *tv = get_Const_tarval(param);
4501 unsigned long value = get_tarval_long(tv);
4503 ir_node *block = be_transform_node(get_nodes_block(node));
4504 ir_node *ptr = be_transform_node(frame);
4508 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4509 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4510 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4513 /* load the return address from this frame */
4514 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, get_irg_no_mem(current_ir_graph));
4516 set_irn_pinned(load, get_irn_pinned(node));
4517 set_ia32_op_type(load, ia32_AddrModeS);
4518 set_ia32_ls_mode(load, mode_Iu);
4520 set_ia32_am_offs_int(load, 0);
4521 set_ia32_use_frame(load);
4522 set_ia32_frame_ent(load, ia32_get_return_address_entity());
4524 if (get_irn_pinned(node) == op_pin_state_floats) {
4525 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
4526 && pn_ia32_vfld_res == pn_ia32_Load_res
4527 && pn_ia32_Load_res == pn_ia32_res);
4528 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4531 SET_IA32_ORIG_NODE(load, node);
4532 return new_r_Proj(current_ir_graph, block, load, mode_Iu, pn_ia32_Load_res);
4536 * Transform Builtin frame_address
4538 static ir_node *gen_frame_address(ir_node *node) {
4539 ir_node *param = get_Builtin_param(node, 0);
4540 ir_node *frame = get_Builtin_param(node, 1);
4541 dbg_info *dbgi = get_irn_dbg_info(node);
4542 tarval *tv = get_Const_tarval(param);
4543 unsigned long value = get_tarval_long(tv);
4545 ir_node *block = be_transform_node(get_nodes_block(node));
4546 ir_node *ptr = be_transform_node(frame);
4551 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4552 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4553 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4556 /* load the frame address from this frame */
4557 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, get_irg_no_mem(current_ir_graph));
4559 set_irn_pinned(load, get_irn_pinned(node));
4560 set_ia32_op_type(load, ia32_AddrModeS);
4561 set_ia32_ls_mode(load, mode_Iu);
4563 ent = ia32_get_frame_address_entity();
4565 set_ia32_am_offs_int(load, 0);
4566 set_ia32_use_frame(load);
4567 set_ia32_frame_ent(load, ent);
4569 /* will fail anyway, but gcc does this: */
4570 set_ia32_am_offs_int(load, 0);
4573 if (get_irn_pinned(node) == op_pin_state_floats) {
4574 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
4575 && pn_ia32_vfld_res == pn_ia32_Load_res
4576 && pn_ia32_Load_res == pn_ia32_res);
4577 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4580 SET_IA32_ORIG_NODE(load, node);
4581 return new_r_Proj(current_ir_graph, block, load, mode_Iu, pn_ia32_Load_res);
4585 * Transform Builtin frame_address
4587 static ir_node *gen_prefetch(ir_node *node) {
4589 ir_node *ptr, *block, *mem, *base, *index;
4590 ir_node *param, *new_node;
4593 ia32_address_t addr;
4595 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4596 /* no prefetch at all, route memory */
4597 return be_transform_node(get_Builtin_mem(node));
4600 param = get_Builtin_param(node, 1);
4601 tv = get_Const_tarval(param);
4602 rw = get_tarval_long(tv);
4604 /* construct load address */
4605 memset(&addr, 0, sizeof(addr));
4606 ptr = get_Builtin_param(node, 0);
4607 ia32_create_address_mode(&addr, ptr, 0);
4614 base = be_transform_node(base);
4617 if (index == NULL) {
4620 index = be_transform_node(index);
4623 dbgi = get_irn_dbg_info(node);
4624 block = be_transform_node(get_nodes_block(node));
4625 mem = be_transform_node(get_Builtin_mem(node));
4627 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4628 /* we have 3DNow!, this was already checked above */
4629 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4630 } else if (ia32_cg_config.use_sse_prefetch) {
4631 /* note: rw == 1 is IGNORED in that case */
4632 param = get_Builtin_param(node, 2);
4633 tv = get_Const_tarval(param);
4634 locality = get_tarval_long(tv);
4636 /* SSE style prefetch */
4639 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4642 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4645 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4648 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4652 assert(ia32_cg_config.use_3dnow_prefetch);
4653 /* 3DNow! style prefetch */
4654 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4657 set_irn_pinned(new_node, get_irn_pinned(node));
4658 set_ia32_op_type(new_node, ia32_AddrModeS);
4659 set_ia32_ls_mode(new_node, mode_Bu);
4660 set_address(new_node, &addr);
4662 SET_IA32_ORIG_NODE(new_node, node);
4664 be_dep_on_frame(new_node);
4665 return new_r_Proj(current_ir_graph, block, new_node, mode_M, pn_ia32_Prefetch_M);
4669 * Transform bsf like node
4671 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4673 ir_node *param = get_Builtin_param(node, 0);
4674 dbg_info *dbgi = get_irn_dbg_info(node);
4676 ir_node *block = get_nodes_block(node);
4677 ir_node *new_block = be_transform_node(block);
4679 ia32_address_mode_t am;
4680 ia32_address_t *addr = &am.addr;
4683 match_arguments(&am, block, NULL, param, NULL, match_am);
4685 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4686 set_am_attributes(cnt, &am);
4687 set_ia32_ls_mode(cnt, get_irn_mode(param));
4689 SET_IA32_ORIG_NODE(cnt, node);
4690 return fix_mem_proj(cnt, &am);
4694 * Transform builtin ffs.
4696 static ir_node *gen_ffs(ir_node *node)
4698 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
4699 ir_node *real = skip_Proj(bsf);
4700 dbg_info *dbgi = get_irn_dbg_info(real);
4701 ir_node *block = get_nodes_block(real);
4702 ir_node *flag, *set, *conv, *neg, *or;
4705 if (get_irn_mode(real) != mode_T) {
4706 set_irn_mode(real, mode_T);
4707 bsf = new_r_Proj(current_ir_graph, block, real, mode_Iu, pn_ia32_res);
4710 flag = new_r_Proj(current_ir_graph, block, real, mode_b, pn_ia32_flags);
4713 set = new_bd_ia32_Set(dbgi, block, flag, pn_Cmp_Eq, 0);
4714 SET_IA32_ORIG_NODE(set, node);
4717 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
4718 SET_IA32_ORIG_NODE(conv, node);
4721 neg = new_bd_ia32_Neg(dbgi, block, conv);
4724 or = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
4725 set_ia32_commutative(or);
4728 return new_bd_ia32_Add(dbgi, block, noreg_GP, noreg_GP, nomem, or, create_Immediate(NULL, 0, 1));
4732 * Transform builtin clz.
4734 static ir_node *gen_clz(ir_node *node)
4736 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
4737 ir_node *real = skip_Proj(bsr);
4738 dbg_info *dbgi = get_irn_dbg_info(real);
4739 ir_node *block = get_nodes_block(real);
4740 ir_node *imm = create_Immediate(NULL, 0, 31);
4742 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
4746 * Transform builtin ctz.
4748 static ir_node *gen_ctz(ir_node *node)
4750 return gen_unop_AM(node, new_bd_ia32_Bsf);
4754 * Transform builtin parity.
4756 static ir_node *gen_parity(ir_node *node)
4758 ir_node *param = get_Builtin_param(node, 0);
4759 dbg_info *dbgi = get_irn_dbg_info(node);
4761 ir_node *block = get_nodes_block(node);
4763 ir_node *new_block = be_transform_node(block);
4764 ir_node *imm, *cmp, *new_node;
4766 ia32_address_mode_t am;
4767 ia32_address_t *addr = &am.addr;
4771 match_arguments(&am, block, NULL, param, NULL, match_am);
4772 imm = create_Immediate(NULL, 0, 0);
4773 cmp = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
4774 addr->mem, imm, am.new_op2, am.ins_permuted, 0);
4775 set_am_attributes(cmp, &am);
4776 set_ia32_ls_mode(cmp, mode_Iu);
4778 SET_IA32_ORIG_NODE(cmp, node);
4780 cmp = fix_mem_proj(cmp, &am);
4783 new_node = new_bd_ia32_Set(dbgi, new_block, cmp, ia32_pn_Cmp_parity, 0);
4784 SET_IA32_ORIG_NODE(new_node, node);
4787 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
4788 nomem, new_node, mode_Bu);
4789 SET_IA32_ORIG_NODE(new_node, node);
4794 * Transform builtin popcount
4796 static ir_node *gen_popcount(ir_node *node) {
4797 ir_node *param = get_Builtin_param(node, 0);
4798 dbg_info *dbgi = get_irn_dbg_info(node);
4800 ir_node *block = get_nodes_block(node);
4801 ir_node *new_block = be_transform_node(block);
4804 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
4806 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
4807 if (ia32_cg_config.use_popcnt) {
4808 ia32_address_mode_t am;
4809 ia32_address_t *addr = &am.addr;
4812 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
4814 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4815 set_am_attributes(cnt, &am);
4816 set_ia32_ls_mode(cnt, get_irn_mode(param));
4818 SET_IA32_ORIG_NODE(cnt, node);
4819 return fix_mem_proj(cnt, &am);
4822 new_param = be_transform_node(param);
4824 /* do the standard popcount algo */
4826 /* m1 = x & 0x55555555 */
4827 imm = create_Immediate(NULL, 0, 0x55555555);
4828 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
4831 simm = create_Immediate(NULL, 0, 1);
4832 s1 = new_bd_ia32_Shl(dbgi, new_block, new_param, simm);
4834 /* m2 = s1 & 0x55555555 */
4835 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
4838 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
4840 /* m4 = m3 & 0x33333333 */
4841 imm = create_Immediate(NULL, 0, 0x33333333);
4842 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
4845 simm = create_Immediate(NULL, 0, 2);
4846 s2 = new_bd_ia32_Shl(dbgi, new_block, m3, simm);
4848 /* m5 = s2 & 0x33333333 */
4849 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
4852 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
4854 /* m7 = m6 & 0x0F0F0F0F */
4855 imm = create_Immediate(NULL, 0, 0x0F0F0F0F);
4856 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
4859 simm = create_Immediate(NULL, 0, 4);
4860 s3 = new_bd_ia32_Shl(dbgi, new_block, m6, simm);
4862 /* m8 = s3 & 0x0F0F0F0F */
4863 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
4866 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
4868 /* m10 = m9 & 0x00FF00FF */
4869 imm = create_Immediate(NULL, 0, 0x00FF00FF);
4870 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
4873 simm = create_Immediate(NULL, 0, 8);
4874 s4 = new_bd_ia32_Shl(dbgi, new_block, m9, simm);
4876 /* m11 = s4 & 0x00FF00FF */
4877 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
4879 /* m12 = m10 + m11 */
4880 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
4882 /* m13 = m12 & 0x0000FFFF */
4883 imm = create_Immediate(NULL, 0, 0x0000FFFF);
4884 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
4886 /* s5 = m12 >> 16 */
4887 simm = create_Immediate(NULL, 0, 16);
4888 s5 = new_bd_ia32_Shl(dbgi, new_block, m12, simm);
4890 /* res = m13 + s5 */
4891 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
4895 * Transform builtin byte swap.
4897 static ir_node *gen_bswap(ir_node *node) {
4898 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
4899 dbg_info *dbgi = get_irn_dbg_info(node);
4901 ir_node *block = get_nodes_block(node);
4902 ir_node *new_block = be_transform_node(block);
4903 ir_mode *mode = get_irn_mode(param);
4904 unsigned size = get_mode_size_bits(mode);
4905 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
4909 if (ia32_cg_config.use_i486) {
4910 /* swap available */
4911 return new_bd_ia32_Bswap(dbgi, new_block, param);
4913 s1 = new_bd_ia32_Shl(dbgi, new_block, param, create_Immediate(NULL, 0, 24));
4914 s2 = new_bd_ia32_Shl(dbgi, new_block, param, create_Immediate(NULL, 0, 8));
4916 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, create_Immediate(NULL, 0, 0xFF00));
4917 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
4919 s3 = new_bd_ia32_Shr(dbgi, new_block, param, create_Immediate(NULL, 0, 8));
4921 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, create_Immediate(NULL, 0, 0xFF0000));
4922 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
4924 s4 = new_bd_ia32_Shr(dbgi, new_block, param, create_Immediate(NULL, 0, 24));
4925 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
4928 /* swap16 always available */
4929 return new_bd_ia32_Bswap16(dbgi, new_block, param);
4932 panic("Invalid bswap size (%d)", size);
4937 * Transform Builtin node.
4939 static ir_node *gen_Builtin(ir_node *node) {
4940 ir_builtin_kind kind = get_Builtin_kind(node);
4944 return gen_trap(node);
4945 case ir_bk_debugbreak:
4946 return gen_debugbreak(node);
4947 case ir_bk_return_address:
4948 return gen_return_address(node);
4949 case ir_bk_frame_addess:
4950 return gen_frame_address(node);
4951 case ir_bk_prefetch:
4952 return gen_prefetch(node);
4954 return gen_ffs(node);
4956 return gen_clz(node);
4958 return gen_ctz(node);
4960 return gen_parity(node);
4961 case ir_bk_popcount:
4962 return gen_popcount(node);
4964 return gen_bswap(node);
4966 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
4970 * Transform Proj(Builtin) node.
4972 static ir_node *gen_Proj_Builtin(ir_node *proj) {
4973 ir_node *node = get_Proj_pred(proj);
4974 ir_node *new_node = be_transform_node(node);
4975 ir_builtin_kind kind = get_Builtin_kind(node);
4978 case ir_bk_return_address:
4979 case ir_bk_frame_addess:
4984 case ir_bk_popcount:
4986 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
4989 case ir_bk_debugbreak:
4990 case ir_bk_prefetch:
4991 assert(get_Proj_proj(proj) == pn_Builtin_M);
4994 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
4997 static ir_node *gen_be_IncSP(ir_node *node)
4999 ir_node *res = be_duplicate_node(node);
5000 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5006 * Transform the Projs from a be_Call.
5008 static ir_node *gen_Proj_be_Call(ir_node *node)
5010 ir_node *block = be_transform_node(get_nodes_block(node));
5011 ir_node *call = get_Proj_pred(node);
5012 ir_node *new_call = be_transform_node(call);
5013 ir_graph *irg = current_ir_graph;
5014 dbg_info *dbgi = get_irn_dbg_info(node);
5015 ir_type *method_type = be_Call_get_type(call);
5016 int n_res = get_method_n_ress(method_type);
5017 long proj = get_Proj_proj(node);
5018 ir_mode *mode = get_irn_mode(node);
5022 /* The following is kinda tricky: If we're using SSE, then we have to
5023 * move the result value of the call in floating point registers to an
5024 * xmm register, we therefore construct a GetST0 -> xLoad sequence
5025 * after the call, we have to make sure to correctly make the
5026 * MemProj and the result Proj use these 2 nodes
5028 if (proj == pn_be_Call_M_regular) {
5029 // get new node for result, are we doing the sse load/store hack?
5030 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5031 ir_node *call_res_new;
5032 ir_node *call_res_pred = NULL;
5034 if (call_res != NULL) {
5035 call_res_new = be_transform_node(call_res);
5036 call_res_pred = get_Proj_pred(call_res_new);
5039 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
5040 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5043 assert(is_ia32_xLoad(call_res_pred));
5044 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5048 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5049 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5051 ir_node *frame = get_irg_frame(irg);
5053 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5056 /* in case there is no memory output: create one to serialize the copy
5058 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5059 pn_be_Call_M_regular);
5060 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5061 pn_be_Call_first_res);
5063 /* store st(0) onto stack */
5064 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, call_mem,
5066 set_ia32_op_type(fstp, ia32_AddrModeD);
5067 set_ia32_use_frame(fstp);
5069 /* load into SSE register */
5070 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg_GP, fstp, mode);
5071 set_ia32_op_type(sse_load, ia32_AddrModeS);
5072 set_ia32_use_frame(sse_load);
5074 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5080 /* transform call modes */
5081 if (mode_is_data(mode)) {
5082 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5086 /* Map from be_Call to ia32_Call proj number */
5087 if (proj == pn_be_Call_sp) {
5088 proj = pn_ia32_Call_stack;
5089 } else if (proj == pn_be_Call_M_regular) {
5090 proj = pn_ia32_Call_M;
5092 arch_register_req_t const *const req = arch_get_register_req_out(node);
5093 int const n_outs = arch_irn_get_n_outs(new_call);
5096 assert(proj >= pn_be_Call_first_res);
5097 assert(req->type & arch_register_req_type_limited);
5099 for (i = 0; i < n_outs; ++i) {
5100 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
5102 if (!(new_req->type & arch_register_req_type_limited) ||
5103 new_req->cls != req->cls ||
5104 *new_req->limited != *req->limited)
5113 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5115 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5117 case pn_ia32_Call_stack:
5118 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
5121 case pn_ia32_Call_fpcw:
5122 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
5130 * Transform the Projs from a Cmp.
5132 static ir_node *gen_Proj_Cmp(ir_node *node)
5134 /* this probably means not all mode_b nodes were lowered... */
5135 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5140 * Transform the Projs from a Bound.
5142 static ir_node *gen_Proj_Bound(ir_node *node)
5144 ir_node *new_node, *block;
5145 ir_node *pred = get_Proj_pred(node);
5147 switch (get_Proj_proj(node)) {
5149 return be_transform_node(get_Bound_mem(pred));
5150 case pn_Bound_X_regular:
5151 new_node = be_transform_node(pred);
5152 block = get_nodes_block(new_node);
5153 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
5154 case pn_Bound_X_except:
5155 new_node = be_transform_node(pred);
5156 block = get_nodes_block(new_node);
5157 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
5159 return be_transform_node(get_Bound_index(pred));
5161 panic("unsupported Proj from Bound");
5165 static ir_node *gen_Proj_ASM(ir_node *node)
5167 ir_mode *mode = get_irn_mode(node);
5168 ir_node *pred = get_Proj_pred(node);
5169 ir_node *new_pred = be_transform_node(pred);
5170 ir_node *block = get_nodes_block(new_pred);
5171 long pos = get_Proj_proj(node);
5173 if (mode == mode_M) {
5174 pos = arch_irn_get_n_outs(new_pred) + 1;
5175 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5177 } else if (mode_is_float(mode)) {
5180 panic("unexpected proj mode at ASM");
5183 return new_r_Proj(current_ir_graph, block, new_pred, mode, pos);
5187 * Transform and potentially renumber Proj nodes.
5189 static ir_node *gen_Proj(ir_node *node)
5191 ir_node *pred = get_Proj_pred(node);
5194 switch (get_irn_opcode(pred)) {
5196 proj = get_Proj_proj(node);
5197 if (proj == pn_Store_M) {
5198 return be_transform_node(pred);
5200 panic("No idea how to transform proj->Store");
5203 return gen_Proj_Load(node);
5205 return gen_Proj_ASM(node);
5207 return gen_Proj_Builtin(node);
5211 return gen_Proj_DivMod(node);
5213 return gen_Proj_CopyB(node);
5215 return gen_Proj_Quot(node);
5217 return gen_Proj_be_SubSP(node);
5219 return gen_Proj_be_AddSP(node);
5221 return gen_Proj_be_Call(node);
5223 return gen_Proj_Cmp(node);
5225 return gen_Proj_Bound(node);
5227 proj = get_Proj_proj(node);
5229 case pn_Start_X_initial_exec: {
5230 ir_node *block = get_nodes_block(pred);
5231 ir_node *new_block = be_transform_node(block);
5232 dbg_info *dbgi = get_irn_dbg_info(node);
5233 /* we exchange the ProjX with a jump */
5234 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
5239 case pn_Start_P_tls:
5240 return gen_Proj_tls(node);
5245 if (is_ia32_l_FloattoLL(pred)) {
5246 return gen_Proj_l_FloattoLL(node);
5248 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5252 ir_mode *mode = get_irn_mode(node);
5253 if (ia32_mode_needs_gp_reg(mode)) {
5254 ir_node *new_pred = be_transform_node(pred);
5255 ir_node *block = be_transform_node(get_nodes_block(node));
5256 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5257 mode_Iu, get_Proj_proj(node));
5258 #ifdef DEBUG_libfirm
5259 new_proj->node_nr = node->node_nr;
5265 return be_duplicate_node(node);
5269 * Enters all transform functions into the generic pointer
5271 static void register_transformers(void)
5273 /* first clear the generic function pointer for all ops */
5274 clear_irp_opcodes_generic_func();
5276 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5277 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5316 /* transform ops from intrinsic lowering */
5328 GEN(ia32_l_LLtoFloat);
5329 GEN(ia32_l_FloattoLL);
5335 /* we should never see these nodes */
5350 /* handle builtins */
5353 /* handle generic backend nodes */
5367 * Pre-transform all unknown and noreg nodes.
5369 static void ia32_pretransform_node(void)
5371 ia32_code_gen_t *cg = env_cg;
5373 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5374 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5375 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5376 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5377 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5378 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5380 nomem = get_irg_no_mem(current_ir_graph);
5381 noreg_GP = ia32_new_NoReg_gp(cg);
5387 * Walker, checks if all ia32 nodes producing more than one result have their
5388 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
5390 static void add_missing_keep_walker(ir_node *node, void *data)
5393 unsigned found_projs = 0;
5394 const ir_edge_t *edge;
5395 ir_mode *mode = get_irn_mode(node);
5400 if (!is_ia32_irn(node))
5403 n_outs = arch_irn_get_n_outs(node);
5406 if (is_ia32_SwitchJmp(node))
5409 assert(n_outs < (int) sizeof(unsigned) * 8);
5410 foreach_out_edge(node, edge) {
5411 ir_node *proj = get_edge_src_irn(edge);
5414 /* The node could be kept */
5418 if (get_irn_mode(proj) == mode_M)
5421 pn = get_Proj_proj(proj);
5422 assert(pn < n_outs);
5423 found_projs |= 1 << pn;
5427 /* are keeps missing? */
5429 for (i = 0; i < n_outs; ++i) {
5432 const arch_register_req_t *req;
5433 const arch_register_class_t *cls;
5435 if (found_projs & (1 << i)) {
5439 req = get_ia32_out_req(node, i);
5444 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
5448 block = get_nodes_block(node);
5449 in[0] = new_r_Proj(current_ir_graph, block, node,
5450 arch_register_class_mode(cls), i);
5451 if (last_keep != NULL) {
5452 be_Keep_add_node(last_keep, cls, in[0]);
5454 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
5455 if (sched_is_scheduled(node)) {
5456 sched_add_after(node, last_keep);
5463 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5466 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5468 ir_graph *irg = be_get_birg_irg(cg->birg);
5469 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5472 /* do the transformation */
5473 void ia32_transform_graph(ia32_code_gen_t *cg)
5477 register_transformers();
5479 initial_fpcw = NULL;
5481 BE_TIMER_PUSH(t_heights);
5482 heights = heights_new(cg->irg);
5483 BE_TIMER_POP(t_heights);
5484 ia32_calculate_non_address_mode_nodes(cg->birg);
5486 /* the transform phase is not safe for CSE (yet) because several nodes get
5487 * attributes set after their creation */
5488 cse_last = get_opt_cse();
5491 be_transform_graph(cg->birg, ia32_pretransform_node);
5493 set_opt_cse(cse_last);
5495 ia32_free_non_address_mode_nodes();
5496 heights_free(heights);
5500 void ia32_init_transform(void)
5502 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");