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.h"
52 #include "../besched.h"
54 #include "../beutil.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 this to construct SSE constants instead of load them */
74 #undef CONSTRUCT_SSE_CONST
77 #define SFP_SIGN "0x80000000"
78 #define DFP_SIGN "0x8000000000000000"
79 #define SFP_ABS "0x7FFFFFFF"
80 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
81 #define DFP_INTMAX "9223372036854775807"
82 #define ULL_BIAS "18446744073709551616"
84 #define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
85 #define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
86 #define ENT_SFP_ABS ".LC_ia32_sfp_abs"
87 #define ENT_DFP_ABS ".LC_ia32_dfp_abs"
88 #define ENT_ULL_BIAS ".LC_ia32_ull_bias"
90 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
91 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
93 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
95 static ir_node *initial_fpcw = NULL;
98 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
99 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
102 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
103 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
106 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
107 ir_node *op1, ir_node *op2);
109 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
110 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
112 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
113 ir_node *base, ir_node *index, ir_node *mem);
115 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
116 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
119 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
121 static ir_node *create_immediate_or_transform(ir_node *node,
122 char immediate_constraint_type);
124 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
125 dbg_info *dbgi, ir_node *block,
126 ir_node *op, ir_node *orig_node);
128 /* its enough to have those once */
129 static ir_node *nomem, *noreg_GP;
131 /** a list to postprocess all calls */
132 static ir_node **call_list;
133 static ir_type **call_types;
135 /** Return non-zero is a node represents the 0 constant. */
136 static bool is_Const_0(ir_node *node)
138 return is_Const(node) && is_Const_null(node);
141 /** Return non-zero is a node represents the 1 constant. */
142 static bool is_Const_1(ir_node *node)
144 return is_Const(node) && is_Const_one(node);
147 /** Return non-zero is a node represents the -1 constant. */
148 static bool is_Const_Minus_1(ir_node *node)
150 return is_Const(node) && is_Const_all_one(node);
154 * returns true if constant can be created with a simple float command
156 static bool is_simple_x87_Const(ir_node *node)
158 tarval *tv = get_Const_tarval(node);
159 if (tarval_is_null(tv) || tarval_is_one(tv))
162 /* TODO: match all the other float constants */
167 * returns true if constant can be created with a simple float command
169 static bool is_simple_sse_Const(ir_node *node)
171 tarval *tv = get_Const_tarval(node);
172 ir_mode *mode = get_tarval_mode(tv);
177 if (tarval_is_null(tv)
178 #ifdef CONSTRUCT_SSE_CONST
183 #ifdef CONSTRUCT_SSE_CONST
184 if (mode == mode_D) {
185 unsigned val = get_tarval_sub_bits(tv, 0) |
186 (get_tarval_sub_bits(tv, 1) << 8) |
187 (get_tarval_sub_bits(tv, 2) << 16) |
188 (get_tarval_sub_bits(tv, 3) << 24);
190 /* lower 32bit are zero, really a 32bit constant */
193 #endif /* CONSTRUCT_SSE_CONST */
194 /* TODO: match all the other float constants */
199 * Transforms a Const.
201 static ir_node *gen_Const(ir_node *node)
203 ir_node *old_block = get_nodes_block(node);
204 ir_node *block = be_transform_node(old_block);
205 dbg_info *dbgi = get_irn_dbg_info(node);
206 ir_mode *mode = get_irn_mode(node);
208 assert(is_Const(node));
210 if (mode_is_float(mode)) {
215 if (ia32_cg_config.use_sse2) {
216 tarval *tv = get_Const_tarval(node);
217 if (tarval_is_null(tv)) {
218 load = new_bd_ia32_xZero(dbgi, block);
219 set_ia32_ls_mode(load, mode);
221 #ifdef CONSTRUCT_SSE_CONST
222 } else if (tarval_is_one(tv)) {
223 int cnst = mode == mode_F ? 26 : 55;
224 ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
225 ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
226 ir_node *pslld, *psrld;
228 load = new_bd_ia32_xAllOnes(dbgi, block);
229 set_ia32_ls_mode(load, mode);
230 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
231 set_ia32_ls_mode(pslld, mode);
232 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
233 set_ia32_ls_mode(psrld, mode);
235 #endif /* CONSTRUCT_SSE_CONST */
236 } else if (mode == mode_F) {
237 /* we can place any 32bit constant by using a movd gp, sse */
238 unsigned val = get_tarval_sub_bits(tv, 0) |
239 (get_tarval_sub_bits(tv, 1) << 8) |
240 (get_tarval_sub_bits(tv, 2) << 16) |
241 (get_tarval_sub_bits(tv, 3) << 24);
242 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
243 load = new_bd_ia32_xMovd(dbgi, block, cnst);
244 set_ia32_ls_mode(load, mode);
247 #ifdef CONSTRUCT_SSE_CONST
248 if (mode == mode_D) {
249 unsigned val = get_tarval_sub_bits(tv, 0) |
250 (get_tarval_sub_bits(tv, 1) << 8) |
251 (get_tarval_sub_bits(tv, 2) << 16) |
252 (get_tarval_sub_bits(tv, 3) << 24);
254 ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
255 ir_node *cnst, *psllq;
257 /* fine, lower 32bit are zero, produce 32bit value */
258 val = get_tarval_sub_bits(tv, 4) |
259 (get_tarval_sub_bits(tv, 5) << 8) |
260 (get_tarval_sub_bits(tv, 6) << 16) |
261 (get_tarval_sub_bits(tv, 7) << 24);
262 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
263 load = new_bd_ia32_xMovd(dbgi, block, cnst);
264 set_ia32_ls_mode(load, mode);
265 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
266 set_ia32_ls_mode(psllq, mode);
271 #endif /* CONSTRUCT_SSE_CONST */
272 floatent = create_float_const_entity(node);
274 load = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode);
275 set_ia32_op_type(load, ia32_AddrModeS);
276 set_ia32_am_sc(load, floatent);
277 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
278 res = new_r_Proj(block, load, mode_xmm, pn_ia32_xLoad_res);
281 if (is_Const_null(node)) {
282 load = new_bd_ia32_vfldz(dbgi, block);
284 set_ia32_ls_mode(load, mode);
285 } else if (is_Const_one(node)) {
286 load = new_bd_ia32_vfld1(dbgi, block);
288 set_ia32_ls_mode(load, mode);
293 floatent = create_float_const_entity(node);
294 /* create_float_const_ent is smart and sometimes creates
296 ls_mode = get_type_mode(get_entity_type(floatent));
298 if (env_cg->birg->main_env->options->pic) {
299 base = arch_code_generator_get_pic_base(env_cg);
304 load = new_bd_ia32_vfld(dbgi, block, base, noreg_GP, nomem,
306 set_ia32_op_type(load, ia32_AddrModeS);
307 set_ia32_am_sc(load, floatent);
308 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
309 res = new_r_Proj(block, load, mode_vfp, pn_ia32_vfld_res);
312 #ifdef CONSTRUCT_SSE_CONST
314 #endif /* CONSTRUCT_SSE_CONST */
315 SET_IA32_ORIG_NODE(load, node);
317 be_dep_on_frame(load);
319 } else { /* non-float mode */
321 tarval *tv = get_Const_tarval(node);
324 tv = tarval_convert_to(tv, mode_Iu);
326 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
328 panic("couldn't convert constant tarval (%+F)", node);
330 val = get_tarval_long(tv);
332 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
333 SET_IA32_ORIG_NODE(cnst, node);
335 be_dep_on_frame(cnst);
341 * Transforms a SymConst.
343 static ir_node *gen_SymConst(ir_node *node)
345 ir_node *old_block = get_nodes_block(node);
346 ir_node *block = be_transform_node(old_block);
347 dbg_info *dbgi = get_irn_dbg_info(node);
348 ir_mode *mode = get_irn_mode(node);
351 if (mode_is_float(mode)) {
352 if (ia32_cg_config.use_sse2)
353 cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
355 cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
356 set_ia32_am_sc(cnst, get_SymConst_entity(node));
357 set_ia32_use_frame(cnst);
361 if (get_SymConst_kind(node) != symconst_addr_ent) {
362 panic("backend only support symconst_addr_ent (at %+F)", node);
364 entity = get_SymConst_entity(node);
365 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
368 SET_IA32_ORIG_NODE(cnst, node);
370 be_dep_on_frame(cnst);
375 * Create a float type for the given mode and cache it.
377 * @param mode the mode for the float type (might be integer mode for SSE2 types)
378 * @param align alignment
380 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
386 if (mode == mode_Iu) {
387 static ir_type *int_Iu[16] = {NULL, };
389 if (int_Iu[align] == NULL) {
390 int_Iu[align] = tp = new_type_primitive(mode);
391 /* set the specified alignment */
392 set_type_alignment_bytes(tp, align);
394 return int_Iu[align];
395 } else if (mode == mode_Lu) {
396 static ir_type *int_Lu[16] = {NULL, };
398 if (int_Lu[align] == NULL) {
399 int_Lu[align] = tp = new_type_primitive(mode);
400 /* set the specified alignment */
401 set_type_alignment_bytes(tp, align);
403 return int_Lu[align];
404 } else if (mode == mode_F) {
405 static ir_type *float_F[16] = {NULL, };
407 if (float_F[align] == NULL) {
408 float_F[align] = tp = new_type_primitive(mode);
409 /* set the specified alignment */
410 set_type_alignment_bytes(tp, align);
412 return float_F[align];
413 } else if (mode == mode_D) {
414 static ir_type *float_D[16] = {NULL, };
416 if (float_D[align] == NULL) {
417 float_D[align] = tp = new_type_primitive(mode);
418 /* set the specified alignment */
419 set_type_alignment_bytes(tp, align);
421 return float_D[align];
423 static ir_type *float_E[16] = {NULL, };
425 if (float_E[align] == NULL) {
426 float_E[align] = tp = new_type_primitive(mode);
427 /* set the specified alignment */
428 set_type_alignment_bytes(tp, align);
430 return float_E[align];
435 * Create a float[2] array type for the given atomic type.
437 * @param tp the atomic type
439 static ir_type *ia32_create_float_array(ir_type *tp)
441 ir_mode *mode = get_type_mode(tp);
442 unsigned align = get_type_alignment_bytes(tp);
447 if (mode == mode_F) {
448 static ir_type *float_F[16] = {NULL, };
450 if (float_F[align] != NULL)
451 return float_F[align];
452 arr = float_F[align] = new_type_array(1, tp);
453 } else if (mode == mode_D) {
454 static ir_type *float_D[16] = {NULL, };
456 if (float_D[align] != NULL)
457 return float_D[align];
458 arr = float_D[align] = new_type_array(1, tp);
460 static ir_type *float_E[16] = {NULL, };
462 if (float_E[align] != NULL)
463 return float_E[align];
464 arr = float_E[align] = new_type_array(1, tp);
466 set_type_alignment_bytes(arr, align);
467 set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
468 set_type_state(arr, layout_fixed);
472 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
473 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
475 static const struct {
476 const char *ent_name;
477 const char *cnst_str;
480 } names [ia32_known_const_max] = {
481 { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
482 { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
483 { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
484 { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
485 { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
487 static ir_entity *ent_cache[ia32_known_const_max];
489 const char *ent_name, *cnst_str;
495 ent_name = names[kct].ent_name;
496 if (! ent_cache[kct]) {
497 cnst_str = names[kct].cnst_str;
499 switch (names[kct].mode) {
500 case 0: mode = mode_Iu; break;
501 case 1: mode = mode_Lu; break;
502 default: mode = mode_F; break;
504 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
505 tp = ia32_create_float_type(mode, names[kct].align);
507 if (kct == ia32_ULLBIAS)
508 tp = ia32_create_float_array(tp);
509 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
511 set_entity_ld_ident(ent, get_entity_ident(ent));
512 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
513 set_entity_visibility(ent, ir_visibility_local);
515 if (kct == ia32_ULLBIAS) {
516 ir_initializer_t *initializer = create_initializer_compound(2);
518 set_initializer_compound_value(initializer, 0,
519 create_initializer_tarval(get_tarval_null(mode)));
520 set_initializer_compound_value(initializer, 1,
521 create_initializer_tarval(tv));
523 set_entity_initializer(ent, initializer);
525 set_entity_initializer(ent, create_initializer_tarval(tv));
528 /* cache the entry */
529 ent_cache[kct] = ent;
532 return ent_cache[kct];
536 * return true if the node is a Proj(Load) and could be used in source address
537 * mode for another node. Will return only true if the @p other node is not
538 * dependent on the memory of the Load (for binary operations use the other
539 * input here, for unary operations use NULL).
541 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
542 ir_node *other, ir_node *other2, match_flags_t flags)
547 /* float constants are always available */
548 if (is_Const(node)) {
549 ir_mode *mode = get_irn_mode(node);
550 if (mode_is_float(mode)) {
551 if (ia32_cg_config.use_sse2) {
552 if (is_simple_sse_Const(node))
555 if (is_simple_x87_Const(node))
558 if (get_irn_n_edges(node) > 1)
566 load = get_Proj_pred(node);
567 pn = get_Proj_proj(node);
568 if (!is_Load(load) || pn != pn_Load_res)
570 if (get_nodes_block(load) != block)
572 /* we only use address mode if we're the only user of the load */
573 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
575 /* in some edge cases with address mode we might reach the load normally
576 * and through some AM sequence, if it is already materialized then we
577 * can't create an AM node from it */
578 if (be_is_transformed(node))
581 /* don't do AM if other node inputs depend on the load (via mem-proj) */
582 if (other != NULL && prevents_AM(block, load, other))
585 if (other2 != NULL && prevents_AM(block, load, other2))
591 typedef struct ia32_address_mode_t ia32_address_mode_t;
592 struct ia32_address_mode_t {
597 ia32_op_type_t op_type;
601 unsigned commutative : 1;
602 unsigned ins_permuted : 1;
605 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
607 /* construct load address */
608 memset(addr, 0, sizeof(addr[0]));
609 ia32_create_address_mode(addr, ptr, 0);
611 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
612 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
613 addr->mem = be_transform_node(mem);
616 static void build_address(ia32_address_mode_t *am, ir_node *node,
617 ia32_create_am_flags_t flags)
619 ia32_address_t *addr = &am->addr;
625 if (is_Const(node)) {
626 ir_entity *entity = create_float_const_entity(node);
627 addr->base = noreg_GP;
628 addr->index = noreg_GP;
630 addr->symconst_ent = entity;
632 am->ls_mode = get_type_mode(get_entity_type(entity));
633 am->pinned = op_pin_state_floats;
637 load = get_Proj_pred(node);
638 ptr = get_Load_ptr(load);
639 mem = get_Load_mem(load);
640 new_mem = be_transform_node(mem);
641 am->pinned = get_irn_pinned(load);
642 am->ls_mode = get_Load_mode(load);
643 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
646 /* construct load address */
647 ia32_create_address_mode(addr, ptr, flags);
649 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
650 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
654 static void set_address(ir_node *node, const ia32_address_t *addr)
656 set_ia32_am_scale(node, addr->scale);
657 set_ia32_am_sc(node, addr->symconst_ent);
658 set_ia32_am_offs_int(node, addr->offset);
659 if (addr->symconst_sign)
660 set_ia32_am_sc_sign(node);
662 set_ia32_use_frame(node);
663 set_ia32_frame_ent(node, addr->frame_entity);
667 * Apply attributes of a given address mode to a node.
669 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
671 set_address(node, &am->addr);
673 set_ia32_op_type(node, am->op_type);
674 set_ia32_ls_mode(node, am->ls_mode);
675 if (am->pinned == op_pin_state_pinned) {
676 /* beware: some nodes are already pinned and did not allow to change the state */
677 if (get_irn_pinned(node) != op_pin_state_pinned)
678 set_irn_pinned(node, op_pin_state_pinned);
681 set_ia32_commutative(node);
685 * Check, if a given node is a Down-Conv, ie. a integer Conv
686 * from a mode with a mode with more bits to a mode with lesser bits.
687 * Moreover, we return only true if the node has not more than 1 user.
689 * @param node the node
690 * @return non-zero if node is a Down-Conv
692 static int is_downconv(const ir_node *node)
700 /* we only want to skip the conv when we're the only user
701 * (not optimal but for now...)
703 if (get_irn_n_edges(node) > 1)
706 src_mode = get_irn_mode(get_Conv_op(node));
707 dest_mode = get_irn_mode(node);
709 ia32_mode_needs_gp_reg(src_mode) &&
710 ia32_mode_needs_gp_reg(dest_mode) &&
711 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
714 /* Skip all Down-Conv's on a given node and return the resulting node. */
715 ir_node *ia32_skip_downconv(ir_node *node)
717 while (is_downconv(node))
718 node = get_Conv_op(node);
723 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
725 ir_mode *mode = get_irn_mode(node);
730 if (mode_is_signed(mode)) {
735 block = get_nodes_block(node);
736 dbgi = get_irn_dbg_info(node);
738 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
742 * matches operands of a node into ia32 addressing/operand modes. This covers
743 * usage of source address mode, immediates, operations with non 32-bit modes,
745 * The resulting data is filled into the @p am struct. block is the block
746 * of the node whose arguments are matched. op1, op2 are the first and second
747 * input that are matched (op1 may be NULL). other_op is another unrelated
748 * input that is not matched! but which is needed sometimes to check if AM
749 * for op1/op2 is legal.
750 * @p flags describes the supported modes of the operation in detail.
752 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
753 ir_node *op1, ir_node *op2, ir_node *other_op,
756 ia32_address_t *addr = &am->addr;
757 ir_mode *mode = get_irn_mode(op2);
758 int mode_bits = get_mode_size_bits(mode);
759 ir_node *new_op1, *new_op2;
761 unsigned commutative;
762 int use_am_and_immediates;
765 memset(am, 0, sizeof(am[0]));
767 commutative = (flags & match_commutative) != 0;
768 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
769 use_am = (flags & match_am) != 0;
770 use_immediate = (flags & match_immediate) != 0;
771 assert(!use_am_and_immediates || use_immediate);
774 assert(!commutative || op1 != NULL);
775 assert(use_am || !(flags & match_8bit_am));
776 assert(use_am || !(flags & match_16bit_am));
778 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
779 (mode_bits == 16 && !(flags & match_16bit_am))) {
783 /* we can simply skip downconvs for mode neutral nodes: the upper bits
784 * can be random for these operations */
785 if (flags & match_mode_neutral) {
786 op2 = ia32_skip_downconv(op2);
788 op1 = ia32_skip_downconv(op1);
792 /* match immediates. firm nodes are normalized: constants are always on the
795 if (!(flags & match_try_am) && use_immediate) {
796 new_op2 = try_create_Immediate(op2, 0);
799 if (new_op2 == NULL &&
800 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
801 build_address(am, op2, 0);
802 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
803 if (mode_is_float(mode)) {
804 new_op2 = ia32_new_NoReg_vfp(env_cg);
808 am->op_type = ia32_AddrModeS;
809 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
811 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
813 build_address(am, op1, 0);
815 if (mode_is_float(mode)) {
816 noreg = ia32_new_NoReg_vfp(env_cg);
821 if (new_op2 != NULL) {
824 new_op1 = be_transform_node(op2);
826 am->ins_permuted = 1;
828 am->op_type = ia32_AddrModeS;
831 am->op_type = ia32_Normal;
833 if (flags & match_try_am) {
839 mode = get_irn_mode(op2);
840 if (flags & match_upconv_32 && get_mode_size_bits(mode) != 32) {
841 new_op1 = (op1 == NULL ? NULL : create_upconv(op1, NULL));
843 new_op2 = create_upconv(op2, NULL);
844 am->ls_mode = mode_Iu;
846 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
848 new_op2 = be_transform_node(op2);
849 am->ls_mode = (flags & match_mode_neutral) ? mode_Iu : mode;
852 if (addr->base == NULL)
853 addr->base = noreg_GP;
854 if (addr->index == NULL)
855 addr->index = noreg_GP;
856 if (addr->mem == NULL)
859 am->new_op1 = new_op1;
860 am->new_op2 = new_op2;
861 am->commutative = commutative;
865 * "Fixes" a node that uses address mode by turning it into mode_T
866 * and returning a pn_ia32_res Proj.
868 * @param node the node
869 * @param am its address mode
871 * @return a Proj(pn_ia32_res) if a memory address mode is used,
874 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
879 if (am->mem_proj == NULL)
882 /* we have to create a mode_T so the old MemProj can attach to us */
883 mode = get_irn_mode(node);
884 load = get_Proj_pred(am->mem_proj);
886 be_set_transformed_node(load, node);
888 if (mode != mode_T) {
889 set_irn_mode(node, mode_T);
890 return new_rd_Proj(NULL, get_nodes_block(node), node, mode, pn_ia32_res);
897 * Construct a standard binary operation, set AM and immediate if required.
899 * @param node The original node for which the binop is created
900 * @param op1 The first operand
901 * @param op2 The second operand
902 * @param func The node constructor function
903 * @return The constructed ia32 node.
905 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
906 construct_binop_func *func, match_flags_t flags)
909 ir_node *block, *new_block, *new_node;
910 ia32_address_mode_t am;
911 ia32_address_t *addr = &am.addr;
913 block = get_nodes_block(node);
914 match_arguments(&am, block, op1, op2, NULL, flags);
916 dbgi = get_irn_dbg_info(node);
917 new_block = be_transform_node(block);
918 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
919 am.new_op1, am.new_op2);
920 set_am_attributes(new_node, &am);
921 /* we can't use source address mode anymore when using immediates */
922 if (!(flags & match_am_and_immediates) &&
923 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
924 set_ia32_am_support(new_node, ia32_am_none);
925 SET_IA32_ORIG_NODE(new_node, node);
927 new_node = fix_mem_proj(new_node, &am);
933 * Generic names for the inputs of an ia32 binary op.
936 n_ia32_l_binop_left, /**< ia32 left input */
937 n_ia32_l_binop_right, /**< ia32 right input */
938 n_ia32_l_binop_eflags /**< ia32 eflags input */
940 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
941 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
942 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
943 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
944 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
945 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
948 * Construct a binary operation which also consumes the eflags.
950 * @param node The node to transform
951 * @param func The node constructor function
952 * @param flags The match flags
953 * @return The constructor ia32 node
955 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
958 ir_node *src_block = get_nodes_block(node);
959 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
960 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
961 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
963 ir_node *block, *new_node, *new_eflags;
964 ia32_address_mode_t am;
965 ia32_address_t *addr = &am.addr;
967 match_arguments(&am, src_block, op1, op2, eflags, flags);
969 dbgi = get_irn_dbg_info(node);
970 block = be_transform_node(src_block);
971 new_eflags = be_transform_node(eflags);
972 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
973 am.new_op1, am.new_op2, new_eflags);
974 set_am_attributes(new_node, &am);
975 /* we can't use source address mode anymore when using immediates */
976 if (!(flags & match_am_and_immediates) &&
977 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
978 set_ia32_am_support(new_node, ia32_am_none);
979 SET_IA32_ORIG_NODE(new_node, node);
981 new_node = fix_mem_proj(new_node, &am);
986 static ir_node *get_fpcw(void)
989 if (initial_fpcw != NULL)
992 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
993 &ia32_fp_cw_regs[REG_FPCW]);
994 initial_fpcw = be_transform_node(fpcw);
1000 * Construct a standard binary operation, set AM and immediate if required.
1002 * @param op1 The first operand
1003 * @param op2 The second operand
1004 * @param func The node constructor function
1005 * @return The constructed ia32 node.
1007 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1008 construct_binop_float_func *func)
1010 ir_mode *mode = get_irn_mode(node);
1012 ir_node *block, *new_block, *new_node;
1013 ia32_address_mode_t am;
1014 ia32_address_t *addr = &am.addr;
1015 ia32_x87_attr_t *attr;
1016 /* All operations are considered commutative, because there are reverse
1018 match_flags_t flags = match_commutative;
1020 /* happens for div nodes... */
1022 mode = get_divop_resmod(node);
1024 /* cannot use address mode with long double on x87 */
1025 if (get_mode_size_bits(mode) <= 64)
1028 block = get_nodes_block(node);
1029 match_arguments(&am, block, op1, op2, NULL, flags);
1031 dbgi = get_irn_dbg_info(node);
1032 new_block = be_transform_node(block);
1033 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
1034 am.new_op1, am.new_op2, get_fpcw());
1035 set_am_attributes(new_node, &am);
1037 attr = get_ia32_x87_attr(new_node);
1038 attr->attr.data.ins_permuted = am.ins_permuted;
1040 SET_IA32_ORIG_NODE(new_node, node);
1042 new_node = fix_mem_proj(new_node, &am);
1048 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1050 * @param op1 The first operand
1051 * @param op2 The second operand
1052 * @param func The node constructor function
1053 * @return The constructed ia32 node.
1055 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1056 construct_shift_func *func,
1057 match_flags_t flags)
1060 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1062 assert(! mode_is_float(get_irn_mode(node)));
1063 assert(flags & match_immediate);
1064 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1066 if (flags & match_mode_neutral) {
1067 op1 = ia32_skip_downconv(op1);
1068 new_op1 = be_transform_node(op1);
1069 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1070 new_op1 = create_upconv(op1, node);
1072 new_op1 = be_transform_node(op1);
1075 /* the shift amount can be any mode that is bigger than 5 bits, since all
1076 * other bits are ignored anyway */
1077 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1078 ir_node *const op = get_Conv_op(op2);
1079 if (mode_is_float(get_irn_mode(op)))
1082 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1084 new_op2 = create_immediate_or_transform(op2, 0);
1086 dbgi = get_irn_dbg_info(node);
1087 block = get_nodes_block(node);
1088 new_block = be_transform_node(block);
1089 new_node = func(dbgi, new_block, new_op1, new_op2);
1090 SET_IA32_ORIG_NODE(new_node, node);
1092 /* lowered shift instruction may have a dependency operand, handle it here */
1093 if (get_irn_arity(node) == 3) {
1094 /* we have a dependency */
1095 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1096 add_irn_dep(new_node, new_dep);
1104 * Construct a standard unary operation, set AM and immediate if required.
1106 * @param op The operand
1107 * @param func The node constructor function
1108 * @return The constructed ia32 node.
1110 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1111 match_flags_t flags)
1114 ir_node *block, *new_block, *new_op, *new_node;
1116 assert(flags == 0 || flags == match_mode_neutral);
1117 if (flags & match_mode_neutral) {
1118 op = ia32_skip_downconv(op);
1121 new_op = be_transform_node(op);
1122 dbgi = get_irn_dbg_info(node);
1123 block = get_nodes_block(node);
1124 new_block = be_transform_node(block);
1125 new_node = func(dbgi, new_block, new_op);
1127 SET_IA32_ORIG_NODE(new_node, node);
1132 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1133 ia32_address_t *addr)
1135 ir_node *base, *index, *res;
1141 base = be_transform_node(base);
1144 index = addr->index;
1145 if (index == NULL) {
1148 index = be_transform_node(index);
1151 res = new_bd_ia32_Lea(dbgi, block, base, index);
1152 set_address(res, addr);
1158 * Returns non-zero if a given address mode has a symbolic or
1159 * numerical offset != 0.
1161 static int am_has_immediates(const ia32_address_t *addr)
1163 return addr->offset != 0 || addr->symconst_ent != NULL
1164 || addr->frame_entity || addr->use_frame;
1168 * Creates an ia32 Add.
1170 * @return the created ia32 Add node
1172 static ir_node *gen_Add(ir_node *node)
1174 ir_mode *mode = get_irn_mode(node);
1175 ir_node *op1 = get_Add_left(node);
1176 ir_node *op2 = get_Add_right(node);
1178 ir_node *block, *new_block, *new_node, *add_immediate_op;
1179 ia32_address_t addr;
1180 ia32_address_mode_t am;
1182 if (mode_is_float(mode)) {
1183 if (ia32_cg_config.use_sse2)
1184 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1185 match_commutative | match_am);
1187 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1190 ia32_mark_non_am(node);
1192 op2 = ia32_skip_downconv(op2);
1193 op1 = ia32_skip_downconv(op1);
1197 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1198 * 1. Add with immediate -> Lea
1199 * 2. Add with possible source address mode -> Add
1200 * 3. Otherwise -> Lea
1202 memset(&addr, 0, sizeof(addr));
1203 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1204 add_immediate_op = NULL;
1206 dbgi = get_irn_dbg_info(node);
1207 block = get_nodes_block(node);
1208 new_block = be_transform_node(block);
1211 if (addr.base == NULL && addr.index == NULL) {
1212 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1213 addr.symconst_sign, 0, addr.offset);
1214 be_dep_on_frame(new_node);
1215 SET_IA32_ORIG_NODE(new_node, node);
1218 /* add with immediate? */
1219 if (addr.index == NULL) {
1220 add_immediate_op = addr.base;
1221 } else if (addr.base == NULL && addr.scale == 0) {
1222 add_immediate_op = addr.index;
1225 if (add_immediate_op != NULL) {
1226 if (!am_has_immediates(&addr)) {
1227 #ifdef DEBUG_libfirm
1228 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1231 return be_transform_node(add_immediate_op);
1234 new_node = create_lea_from_address(dbgi, new_block, &addr);
1235 SET_IA32_ORIG_NODE(new_node, node);
1239 /* test if we can use source address mode */
1240 match_arguments(&am, block, op1, op2, NULL, match_commutative
1241 | match_mode_neutral | match_am | match_immediate | match_try_am);
1243 /* construct an Add with source address mode */
1244 if (am.op_type == ia32_AddrModeS) {
1245 ia32_address_t *am_addr = &am.addr;
1246 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1247 am_addr->index, am_addr->mem, am.new_op1,
1249 set_am_attributes(new_node, &am);
1250 SET_IA32_ORIG_NODE(new_node, node);
1252 new_node = fix_mem_proj(new_node, &am);
1257 /* otherwise construct a lea */
1258 new_node = create_lea_from_address(dbgi, new_block, &addr);
1259 SET_IA32_ORIG_NODE(new_node, node);
1264 * Creates an ia32 Mul.
1266 * @return the created ia32 Mul node
1268 static ir_node *gen_Mul(ir_node *node)
1270 ir_node *op1 = get_Mul_left(node);
1271 ir_node *op2 = get_Mul_right(node);
1272 ir_mode *mode = get_irn_mode(node);
1274 if (mode_is_float(mode)) {
1275 if (ia32_cg_config.use_sse2)
1276 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1277 match_commutative | match_am);
1279 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1281 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1282 match_commutative | match_am | match_mode_neutral |
1283 match_immediate | match_am_and_immediates);
1287 * Creates an ia32 Mulh.
1288 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1289 * this result while Mul returns the lower 32 bit.
1291 * @return the created ia32 Mulh node
1293 static ir_node *gen_Mulh(ir_node *node)
1295 ir_node *block = get_nodes_block(node);
1296 ir_node *new_block = be_transform_node(block);
1297 dbg_info *dbgi = get_irn_dbg_info(node);
1298 ir_node *op1 = get_Mulh_left(node);
1299 ir_node *op2 = get_Mulh_right(node);
1300 ir_mode *mode = get_irn_mode(node);
1302 ir_node *proj_res_high;
1304 if (get_mode_size_bits(mode) != 32) {
1305 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1308 if (mode_is_signed(mode)) {
1309 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1310 proj_res_high = new_rd_Proj(dbgi, new_block, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1312 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1313 proj_res_high = new_rd_Proj(dbgi, new_block, new_node, mode_Iu, pn_ia32_Mul_res_high);
1315 return proj_res_high;
1319 * Creates an ia32 And.
1321 * @return The created ia32 And node
1323 static ir_node *gen_And(ir_node *node)
1325 ir_node *op1 = get_And_left(node);
1326 ir_node *op2 = get_And_right(node);
1327 assert(! mode_is_float(get_irn_mode(node)));
1329 /* is it a zero extension? */
1330 if (is_Const(op2)) {
1331 tarval *tv = get_Const_tarval(op2);
1332 long v = get_tarval_long(tv);
1334 if (v == 0xFF || v == 0xFFFF) {
1335 dbg_info *dbgi = get_irn_dbg_info(node);
1336 ir_node *block = get_nodes_block(node);
1343 assert(v == 0xFFFF);
1346 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1351 return gen_binop(node, op1, op2, new_bd_ia32_And,
1352 match_commutative | match_mode_neutral | match_am | match_immediate);
1358 * Creates an ia32 Or.
1360 * @return The created ia32 Or node
1362 static ir_node *gen_Or(ir_node *node)
1364 ir_node *op1 = get_Or_left(node);
1365 ir_node *op2 = get_Or_right(node);
1367 assert (! mode_is_float(get_irn_mode(node)));
1368 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1369 | match_mode_neutral | match_am | match_immediate);
1375 * Creates an ia32 Eor.
1377 * @return The created ia32 Eor node
1379 static ir_node *gen_Eor(ir_node *node)
1381 ir_node *op1 = get_Eor_left(node);
1382 ir_node *op2 = get_Eor_right(node);
1384 assert(! mode_is_float(get_irn_mode(node)));
1385 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1386 | match_mode_neutral | match_am | match_immediate);
1391 * Creates an ia32 Sub.
1393 * @return The created ia32 Sub node
1395 static ir_node *gen_Sub(ir_node *node)
1397 ir_node *op1 = get_Sub_left(node);
1398 ir_node *op2 = get_Sub_right(node);
1399 ir_mode *mode = get_irn_mode(node);
1401 if (mode_is_float(mode)) {
1402 if (ia32_cg_config.use_sse2)
1403 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1405 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1408 if (is_Const(op2)) {
1409 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1413 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1414 | match_am | match_immediate);
1417 static ir_node *transform_AM_mem(ir_node *const block,
1418 ir_node *const src_val,
1419 ir_node *const src_mem,
1420 ir_node *const am_mem)
1422 if (is_NoMem(am_mem)) {
1423 return be_transform_node(src_mem);
1424 } else if (is_Proj(src_val) &&
1426 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1427 /* avoid memory loop */
1429 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1430 ir_node *const ptr_pred = get_Proj_pred(src_val);
1431 int const arity = get_Sync_n_preds(src_mem);
1436 NEW_ARR_A(ir_node*, ins, arity + 1);
1438 /* NOTE: This sometimes produces dead-code because the old sync in
1439 * src_mem might not be used anymore, we should detect this case
1440 * and kill the sync... */
1441 for (i = arity - 1; i >= 0; --i) {
1442 ir_node *const pred = get_Sync_pred(src_mem, i);
1444 /* avoid memory loop */
1445 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1448 ins[n++] = be_transform_node(pred);
1453 return new_r_Sync(block, n, ins);
1457 ins[0] = be_transform_node(src_mem);
1459 return new_r_Sync(block, 2, ins);
1464 * Create a 32bit to 64bit signed extension.
1466 * @param dbgi debug info
1467 * @param block the block where node nodes should be placed
1468 * @param val the value to extend
1469 * @param orig the original node
1471 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1472 ir_node *val, const ir_node *orig)
1477 if (ia32_cg_config.use_short_sex_eax) {
1478 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1479 be_dep_on_frame(pval);
1480 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1482 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1483 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1485 SET_IA32_ORIG_NODE(res, orig);
1490 * Generates an ia32 DivMod with additional infrastructure for the
1491 * register allocator if needed.
1493 static ir_node *create_Div(ir_node *node)
1495 dbg_info *dbgi = get_irn_dbg_info(node);
1496 ir_node *block = get_nodes_block(node);
1497 ir_node *new_block = be_transform_node(block);
1504 ir_node *sign_extension;
1505 ia32_address_mode_t am;
1506 ia32_address_t *addr = &am.addr;
1508 /* the upper bits have random contents for smaller modes */
1509 switch (get_irn_opcode(node)) {
1511 op1 = get_Div_left(node);
1512 op2 = get_Div_right(node);
1513 mem = get_Div_mem(node);
1514 mode = get_Div_resmode(node);
1517 op1 = get_Mod_left(node);
1518 op2 = get_Mod_right(node);
1519 mem = get_Mod_mem(node);
1520 mode = get_Mod_resmode(node);
1523 op1 = get_DivMod_left(node);
1524 op2 = get_DivMod_right(node);
1525 mem = get_DivMod_mem(node);
1526 mode = get_DivMod_resmode(node);
1529 panic("invalid divmod node %+F", node);
1532 match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1534 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1535 is the memory of the consumed address. We can have only the second op as address
1536 in Div nodes, so check only op2. */
1537 new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1539 if (mode_is_signed(mode)) {
1540 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1541 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1542 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1544 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1545 be_dep_on_frame(sign_extension);
1547 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1548 addr->index, new_mem, am.new_op2,
1549 am.new_op1, sign_extension);
1552 set_irn_pinned(new_node, get_irn_pinned(node));
1554 set_am_attributes(new_node, &am);
1555 SET_IA32_ORIG_NODE(new_node, node);
1557 new_node = fix_mem_proj(new_node, &am);
1563 * Generates an ia32 Mod.
1565 static ir_node *gen_Mod(ir_node *node)
1567 return create_Div(node);
1571 * Generates an ia32 Div.
1573 static ir_node *gen_Div(ir_node *node)
1575 return create_Div(node);
1579 * Generates an ia32 DivMod.
1581 static ir_node *gen_DivMod(ir_node *node)
1583 return create_Div(node);
1589 * Creates an ia32 floating Div.
1591 * @return The created ia32 xDiv node
1593 static ir_node *gen_Quot(ir_node *node)
1595 ir_node *op1 = get_Quot_left(node);
1596 ir_node *op2 = get_Quot_right(node);
1598 if (ia32_cg_config.use_sse2) {
1599 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1601 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1607 * Creates an ia32 Shl.
1609 * @return The created ia32 Shl node
1611 static ir_node *gen_Shl(ir_node *node)
1613 ir_node *left = get_Shl_left(node);
1614 ir_node *right = get_Shl_right(node);
1616 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1617 match_mode_neutral | match_immediate);
1621 * Creates an ia32 Shr.
1623 * @return The created ia32 Shr node
1625 static ir_node *gen_Shr(ir_node *node)
1627 ir_node *left = get_Shr_left(node);
1628 ir_node *right = get_Shr_right(node);
1630 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1636 * Creates an ia32 Sar.
1638 * @return The created ia32 Shrs node
1640 static ir_node *gen_Shrs(ir_node *node)
1642 ir_node *left = get_Shrs_left(node);
1643 ir_node *right = get_Shrs_right(node);
1645 if (is_Const(right)) {
1646 tarval *tv = get_Const_tarval(right);
1647 long val = get_tarval_long(tv);
1649 /* this is a sign extension */
1650 dbg_info *dbgi = get_irn_dbg_info(node);
1651 ir_node *block = be_transform_node(get_nodes_block(node));
1652 ir_node *new_op = be_transform_node(left);
1654 return create_sex_32_64(dbgi, block, new_op, node);
1658 /* 8 or 16 bit sign extension? */
1659 if (is_Const(right) && is_Shl(left)) {
1660 ir_node *shl_left = get_Shl_left(left);
1661 ir_node *shl_right = get_Shl_right(left);
1662 if (is_Const(shl_right)) {
1663 tarval *tv1 = get_Const_tarval(right);
1664 tarval *tv2 = get_Const_tarval(shl_right);
1665 if (tv1 == tv2 && tarval_is_long(tv1)) {
1666 long val = get_tarval_long(tv1);
1667 if (val == 16 || val == 24) {
1668 dbg_info *dbgi = get_irn_dbg_info(node);
1669 ir_node *block = get_nodes_block(node);
1679 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1688 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1694 * Creates an ia32 Rol.
1696 * @param op1 The first operator
1697 * @param op2 The second operator
1698 * @return The created ia32 RotL node
1700 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1702 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1708 * Creates an ia32 Ror.
1709 * NOTE: There is no RotR with immediate because this would always be a RotL
1710 * "imm-mode_size_bits" which can be pre-calculated.
1712 * @param op1 The first operator
1713 * @param op2 The second operator
1714 * @return The created ia32 RotR node
1716 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1718 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1724 * Creates an ia32 RotR or RotL (depending on the found pattern).
1726 * @return The created ia32 RotL or RotR node
1728 static ir_node *gen_Rotl(ir_node *node)
1730 ir_node *rotate = NULL;
1731 ir_node *op1 = get_Rotl_left(node);
1732 ir_node *op2 = get_Rotl_right(node);
1734 /* Firm has only RotL, so we are looking for a right (op2)
1735 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1736 that means we can create a RotR instead of an Add and a RotL */
1740 ir_node *left = get_Add_left(add);
1741 ir_node *right = get_Add_right(add);
1742 if (is_Const(right)) {
1743 tarval *tv = get_Const_tarval(right);
1744 ir_mode *mode = get_irn_mode(node);
1745 long bits = get_mode_size_bits(mode);
1747 if (is_Minus(left) &&
1748 tarval_is_long(tv) &&
1749 get_tarval_long(tv) == bits &&
1752 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1753 rotate = gen_Ror(node, op1, get_Minus_op(left));
1758 if (rotate == NULL) {
1759 rotate = gen_Rol(node, op1, op2);
1768 * Transforms a Minus node.
1770 * @return The created ia32 Minus node
1772 static ir_node *gen_Minus(ir_node *node)
1774 ir_node *op = get_Minus_op(node);
1775 ir_node *block = be_transform_node(get_nodes_block(node));
1776 dbg_info *dbgi = get_irn_dbg_info(node);
1777 ir_mode *mode = get_irn_mode(node);
1782 if (mode_is_float(mode)) {
1783 ir_node *new_op = be_transform_node(op);
1784 if (ia32_cg_config.use_sse2) {
1785 /* TODO: non-optimal... if we have many xXors, then we should
1786 * rather create a load for the const and use that instead of
1787 * several AM nodes... */
1788 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1790 new_node = new_bd_ia32_xXor(dbgi, block, noreg_GP, noreg_GP,
1791 nomem, new_op, noreg_xmm);
1793 size = get_mode_size_bits(mode);
1794 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1796 set_ia32_am_sc(new_node, ent);
1797 set_ia32_op_type(new_node, ia32_AddrModeS);
1798 set_ia32_ls_mode(new_node, mode);
1800 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1803 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1806 SET_IA32_ORIG_NODE(new_node, node);
1812 * Transforms a Not node.
1814 * @return The created ia32 Not node
1816 static ir_node *gen_Not(ir_node *node)
1818 ir_node *op = get_Not_op(node);
1820 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1821 assert (! mode_is_float(get_irn_mode(node)));
1823 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1829 * Transforms an Abs node.
1831 * @return The created ia32 Abs node
1833 static ir_node *gen_Abs(ir_node *node)
1835 ir_node *block = get_nodes_block(node);
1836 ir_node *new_block = be_transform_node(block);
1837 ir_node *op = get_Abs_op(node);
1838 dbg_info *dbgi = get_irn_dbg_info(node);
1839 ir_mode *mode = get_irn_mode(node);
1845 if (mode_is_float(mode)) {
1846 new_op = be_transform_node(op);
1848 if (ia32_cg_config.use_sse2) {
1849 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1850 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_GP, noreg_GP,
1851 nomem, new_op, noreg_fp);
1853 size = get_mode_size_bits(mode);
1854 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1856 set_ia32_am_sc(new_node, ent);
1858 SET_IA32_ORIG_NODE(new_node, node);
1860 set_ia32_op_type(new_node, ia32_AddrModeS);
1861 set_ia32_ls_mode(new_node, mode);
1863 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1864 SET_IA32_ORIG_NODE(new_node, node);
1867 ir_node *xor, *sign_extension;
1869 if (get_mode_size_bits(mode) == 32) {
1870 new_op = be_transform_node(op);
1872 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1875 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1877 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1878 nomem, new_op, sign_extension);
1879 SET_IA32_ORIG_NODE(xor, node);
1881 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1882 nomem, xor, sign_extension);
1883 SET_IA32_ORIG_NODE(new_node, node);
1890 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1892 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1894 dbg_info *dbgi = get_irn_dbg_info(cmp);
1895 ir_node *block = get_nodes_block(cmp);
1896 ir_node *new_block = be_transform_node(block);
1897 ir_node *op1 = be_transform_node(x);
1898 ir_node *op2 = be_transform_node(n);
1900 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1904 * Transform a node returning a "flag" result.
1906 * @param node the node to transform
1907 * @param pnc_out the compare mode to use
1909 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1916 /* we have a Cmp as input */
1917 if (is_Proj(node)) {
1918 ir_node *pred = get_Proj_pred(node);
1920 pn_Cmp pnc = get_Proj_proj(node);
1921 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1922 ir_node *l = get_Cmp_left(pred);
1923 ir_node *r = get_Cmp_right(pred);
1925 ir_node *la = get_And_left(l);
1926 ir_node *ra = get_And_right(l);
1928 ir_node *c = get_Shl_left(la);
1929 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1930 /* (1 << n) & ra) */
1931 ir_node *n = get_Shl_right(la);
1932 flags = gen_bt(pred, ra, n);
1933 /* we must generate a Jc/Jnc jump */
1934 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1937 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1942 ir_node *c = get_Shl_left(ra);
1943 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1944 /* la & (1 << n)) */
1945 ir_node *n = get_Shl_right(ra);
1946 flags = gen_bt(pred, la, n);
1947 /* we must generate a Jc/Jnc jump */
1948 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1951 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1957 /* add ia32 compare flags */
1959 ir_node *l = get_Cmp_left(pred);
1960 ir_mode *mode = get_irn_mode(l);
1961 if (mode_is_float(mode))
1962 pnc |= ia32_pn_Cmp_float;
1963 else if (! mode_is_signed(mode))
1964 pnc |= ia32_pn_Cmp_unsigned;
1967 flags = be_transform_node(pred);
1972 /* a mode_b value, we have to compare it against 0 */
1973 dbgi = get_irn_dbg_info(node);
1974 new_block = be_transform_node(get_nodes_block(node));
1975 new_op = be_transform_node(node);
1976 flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op,
1977 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1978 *pnc_out = pn_Cmp_Lg;
1983 * Transforms a Load.
1985 * @return the created ia32 Load node
1987 static ir_node *gen_Load(ir_node *node)
1989 ir_node *old_block = get_nodes_block(node);
1990 ir_node *block = be_transform_node(old_block);
1991 ir_node *ptr = get_Load_ptr(node);
1992 ir_node *mem = get_Load_mem(node);
1993 ir_node *new_mem = be_transform_node(mem);
1996 dbg_info *dbgi = get_irn_dbg_info(node);
1997 ir_mode *mode = get_Load_mode(node);
2000 ia32_address_t addr;
2002 /* construct load address */
2003 memset(&addr, 0, sizeof(addr));
2004 ia32_create_address_mode(&addr, ptr, 0);
2011 base = be_transform_node(base);
2014 if (index == NULL) {
2017 index = be_transform_node(index);
2020 if (mode_is_float(mode)) {
2021 if (ia32_cg_config.use_sse2) {
2022 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2024 res_mode = mode_xmm;
2026 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2028 res_mode = mode_vfp;
2031 assert(mode != mode_b);
2033 /* create a conv node with address mode for smaller modes */
2034 if (get_mode_size_bits(mode) < 32) {
2035 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2036 new_mem, noreg_GP, mode);
2038 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2043 set_irn_pinned(new_node, get_irn_pinned(node));
2044 set_ia32_op_type(new_node, ia32_AddrModeS);
2045 set_ia32_ls_mode(new_node, mode);
2046 set_address(new_node, &addr);
2048 if (get_irn_pinned(node) == op_pin_state_floats) {
2049 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
2050 && pn_ia32_vfld_res == pn_ia32_Load_res
2051 && pn_ia32_Load_res == pn_ia32_res);
2052 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2055 SET_IA32_ORIG_NODE(new_node, node);
2057 be_dep_on_frame(new_node);
2061 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2062 ir_node *ptr, ir_node *other)
2069 /* we only use address mode if we're the only user of the load */
2070 if (get_irn_n_edges(node) > 1)
2073 load = get_Proj_pred(node);
2076 if (get_nodes_block(load) != block)
2079 /* store should have the same pointer as the load */
2080 if (get_Load_ptr(load) != ptr)
2083 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2084 if (other != NULL &&
2085 get_nodes_block(other) == block &&
2086 heights_reachable_in_block(heights, other, load)) {
2090 if (prevents_AM(block, load, mem))
2092 /* Store should be attached to the load via mem */
2093 assert(heights_reachable_in_block(heights, mem, load));
2098 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2099 ir_node *mem, ir_node *ptr, ir_mode *mode,
2100 construct_binop_dest_func *func,
2101 construct_binop_dest_func *func8bit,
2102 match_flags_t flags)
2104 ir_node *src_block = get_nodes_block(node);
2112 ia32_address_mode_t am;
2113 ia32_address_t *addr = &am.addr;
2114 memset(&am, 0, sizeof(am));
2116 assert(flags & match_immediate); /* there is no destam node without... */
2117 commutative = (flags & match_commutative) != 0;
2119 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2120 build_address(&am, op1, ia32_create_am_double_use);
2121 new_op = create_immediate_or_transform(op2, 0);
2122 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2123 build_address(&am, op2, ia32_create_am_double_use);
2124 new_op = create_immediate_or_transform(op1, 0);
2129 if (addr->base == NULL)
2130 addr->base = noreg_GP;
2131 if (addr->index == NULL)
2132 addr->index = noreg_GP;
2133 if (addr->mem == NULL)
2136 dbgi = get_irn_dbg_info(node);
2137 block = be_transform_node(src_block);
2138 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2140 if (get_mode_size_bits(mode) == 8) {
2141 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2143 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2145 set_address(new_node, addr);
2146 set_ia32_op_type(new_node, ia32_AddrModeD);
2147 set_ia32_ls_mode(new_node, mode);
2148 SET_IA32_ORIG_NODE(new_node, node);
2150 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2151 mem_proj = be_transform_node(am.mem_proj);
2152 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2157 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2158 ir_node *ptr, ir_mode *mode,
2159 construct_unop_dest_func *func)
2161 ir_node *src_block = get_nodes_block(node);
2167 ia32_address_mode_t am;
2168 ia32_address_t *addr = &am.addr;
2170 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2173 memset(&am, 0, sizeof(am));
2174 build_address(&am, op, ia32_create_am_double_use);
2176 dbgi = get_irn_dbg_info(node);
2177 block = be_transform_node(src_block);
2178 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2179 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2180 set_address(new_node, addr);
2181 set_ia32_op_type(new_node, ia32_AddrModeD);
2182 set_ia32_ls_mode(new_node, mode);
2183 SET_IA32_ORIG_NODE(new_node, node);
2185 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2186 mem_proj = be_transform_node(am.mem_proj);
2187 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2192 static pn_Cmp ia32_get_negated_pnc(pn_Cmp pnc)
2194 ir_mode *mode = pnc & ia32_pn_Cmp_float ? mode_F : mode_Iu;
2195 return get_negated_pnc(pnc, mode);
2198 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2200 ir_mode *mode = get_irn_mode(node);
2201 ir_node *mux_true = get_Mux_true(node);
2202 ir_node *mux_false = get_Mux_false(node);
2212 ia32_address_t addr;
2214 if (get_mode_size_bits(mode) != 8)
2217 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2219 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2225 cond = get_Mux_sel(node);
2226 flags = get_flags_node(cond, &pnc);
2227 /* we can't handle the float special cases with SetM */
2228 if (pnc & ia32_pn_Cmp_float)
2231 pnc = ia32_get_negated_pnc(pnc);
2233 build_address_ptr(&addr, ptr, mem);
2235 dbgi = get_irn_dbg_info(node);
2236 block = get_nodes_block(node);
2237 new_block = be_transform_node(block);
2238 new_mem = be_transform_node(mem);
2239 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2240 addr.index, addr.mem, flags, pnc);
2241 set_address(new_node, &addr);
2242 set_ia32_op_type(new_node, ia32_AddrModeD);
2243 set_ia32_ls_mode(new_node, mode);
2244 SET_IA32_ORIG_NODE(new_node, node);
2249 static ir_node *try_create_dest_am(ir_node *node)
2251 ir_node *val = get_Store_value(node);
2252 ir_node *mem = get_Store_mem(node);
2253 ir_node *ptr = get_Store_ptr(node);
2254 ir_mode *mode = get_irn_mode(val);
2255 unsigned bits = get_mode_size_bits(mode);
2260 /* handle only GP modes for now... */
2261 if (!ia32_mode_needs_gp_reg(mode))
2265 /* store must be the only user of the val node */
2266 if (get_irn_n_edges(val) > 1)
2268 /* skip pointless convs */
2270 ir_node *conv_op = get_Conv_op(val);
2271 ir_mode *pred_mode = get_irn_mode(conv_op);
2272 if (!ia32_mode_needs_gp_reg(pred_mode))
2274 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2282 /* value must be in the same block */
2283 if (get_nodes_block(node) != get_nodes_block(val))
2286 switch (get_irn_opcode(val)) {
2288 op1 = get_Add_left(val);
2289 op2 = get_Add_right(val);
2290 if (ia32_cg_config.use_incdec) {
2291 if (is_Const_1(op2)) {
2292 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2294 } else if (is_Const_Minus_1(op2)) {
2295 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2299 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2300 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2301 match_commutative | match_immediate);
2304 op1 = get_Sub_left(val);
2305 op2 = get_Sub_right(val);
2306 if (is_Const(op2)) {
2307 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2309 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2310 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2314 op1 = get_And_left(val);
2315 op2 = get_And_right(val);
2316 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2317 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2318 match_commutative | match_immediate);
2321 op1 = get_Or_left(val);
2322 op2 = get_Or_right(val);
2323 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2324 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2325 match_commutative | match_immediate);
2328 op1 = get_Eor_left(val);
2329 op2 = get_Eor_right(val);
2330 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2331 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2332 match_commutative | match_immediate);
2335 op1 = get_Shl_left(val);
2336 op2 = get_Shl_right(val);
2337 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2338 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2342 op1 = get_Shr_left(val);
2343 op2 = get_Shr_right(val);
2344 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2345 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2349 op1 = get_Shrs_left(val);
2350 op2 = get_Shrs_right(val);
2351 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2352 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2356 op1 = get_Rotl_left(val);
2357 op2 = get_Rotl_right(val);
2358 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2359 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2362 /* TODO: match ROR patterns... */
2364 new_node = try_create_SetMem(val, ptr, mem);
2368 op1 = get_Minus_op(val);
2369 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2372 /* should be lowered already */
2373 assert(mode != mode_b);
2374 op1 = get_Not_op(val);
2375 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2381 if (new_node != NULL) {
2382 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2383 get_irn_pinned(node) == op_pin_state_pinned) {
2384 set_irn_pinned(new_node, op_pin_state_pinned);
2391 static bool possible_int_mode_for_fp(ir_mode *mode)
2395 if (!mode_is_signed(mode))
2397 size = get_mode_size_bits(mode);
2398 if (size != 16 && size != 32)
2403 static int is_float_to_int_conv(const ir_node *node)
2405 ir_mode *mode = get_irn_mode(node);
2409 if (!possible_int_mode_for_fp(mode))
2414 conv_op = get_Conv_op(node);
2415 conv_mode = get_irn_mode(conv_op);
2417 if (!mode_is_float(conv_mode))
2424 * Transform a Store(floatConst) into a sequence of
2427 * @return the created ia32 Store node
2429 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2431 ir_mode *mode = get_irn_mode(cns);
2432 unsigned size = get_mode_size_bytes(mode);
2433 tarval *tv = get_Const_tarval(cns);
2434 ir_node *block = get_nodes_block(node);
2435 ir_node *new_block = be_transform_node(block);
2436 ir_node *ptr = get_Store_ptr(node);
2437 ir_node *mem = get_Store_mem(node);
2438 dbg_info *dbgi = get_irn_dbg_info(node);
2442 ia32_address_t addr;
2444 assert(size % 4 == 0);
2447 build_address_ptr(&addr, ptr, mem);
2451 get_tarval_sub_bits(tv, ofs) |
2452 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2453 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2454 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2455 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2457 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2458 addr.index, addr.mem, imm);
2460 set_irn_pinned(new_node, get_irn_pinned(node));
2461 set_ia32_op_type(new_node, ia32_AddrModeD);
2462 set_ia32_ls_mode(new_node, mode_Iu);
2463 set_address(new_node, &addr);
2464 SET_IA32_ORIG_NODE(new_node, node);
2467 ins[i++] = new_node;
2472 } while (size != 0);
2475 return new_rd_Sync(dbgi, new_block, i, ins);
2482 * Generate a vfist or vfisttp instruction.
2484 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2485 ir_node *mem, ir_node *val, ir_node **fist)
2489 if (ia32_cg_config.use_fisttp) {
2490 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2491 if other users exists */
2492 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2493 ir_node *value = new_r_Proj(block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2494 be_new_Keep(block, 1, &value);
2496 new_node = new_r_Proj(block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2499 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2502 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2508 * Transforms a general (no special case) Store.
2510 * @return the created ia32 Store node
2512 static ir_node *gen_general_Store(ir_node *node)
2514 ir_node *val = get_Store_value(node);
2515 ir_mode *mode = get_irn_mode(val);
2516 ir_node *block = get_nodes_block(node);
2517 ir_node *new_block = be_transform_node(block);
2518 ir_node *ptr = get_Store_ptr(node);
2519 ir_node *mem = get_Store_mem(node);
2520 dbg_info *dbgi = get_irn_dbg_info(node);
2521 ir_node *new_val, *new_node, *store;
2522 ia32_address_t addr;
2524 /* check for destination address mode */
2525 new_node = try_create_dest_am(node);
2526 if (new_node != NULL)
2529 /* construct store address */
2530 memset(&addr, 0, sizeof(addr));
2531 ia32_create_address_mode(&addr, ptr, 0);
2533 if (addr.base == NULL) {
2534 addr.base = noreg_GP;
2536 addr.base = be_transform_node(addr.base);
2539 if (addr.index == NULL) {
2540 addr.index = noreg_GP;
2542 addr.index = be_transform_node(addr.index);
2544 addr.mem = be_transform_node(mem);
2546 if (mode_is_float(mode)) {
2547 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2549 while (is_Conv(val) && mode == get_irn_mode(val)) {
2550 ir_node *op = get_Conv_op(val);
2551 if (!mode_is_float(get_irn_mode(op)))
2555 new_val = be_transform_node(val);
2556 if (ia32_cg_config.use_sse2) {
2557 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2558 addr.index, addr.mem, new_val);
2560 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2561 addr.index, addr.mem, new_val, mode);
2564 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2565 val = get_Conv_op(val);
2567 /* TODO: is this optimisation still necessary at all (middleend)? */
2568 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2569 while (is_Conv(val)) {
2570 ir_node *op = get_Conv_op(val);
2571 if (!mode_is_float(get_irn_mode(op)))
2573 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2577 new_val = be_transform_node(val);
2578 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2580 new_val = create_immediate_or_transform(val, 0);
2581 assert(mode != mode_b);
2583 if (get_mode_size_bits(mode) == 8) {
2584 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2585 addr.index, addr.mem, new_val);
2587 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2588 addr.index, addr.mem, new_val);
2593 set_irn_pinned(store, get_irn_pinned(node));
2594 set_ia32_op_type(store, ia32_AddrModeD);
2595 set_ia32_ls_mode(store, mode);
2597 set_address(store, &addr);
2598 SET_IA32_ORIG_NODE(store, node);
2604 * Transforms a Store.
2606 * @return the created ia32 Store node
2608 static ir_node *gen_Store(ir_node *node)
2610 ir_node *val = get_Store_value(node);
2611 ir_mode *mode = get_irn_mode(val);
2613 if (mode_is_float(mode) && is_Const(val)) {
2614 /* We can transform every floating const store
2615 into a sequence of integer stores.
2616 If the constant is already in a register,
2617 it would be better to use it, but we don't
2618 have this information here. */
2619 return gen_float_const_Store(node, val);
2621 return gen_general_Store(node);
2625 * Transforms a Switch.
2627 * @return the created ia32 SwitchJmp node
2629 static ir_node *create_Switch(ir_node *node)
2631 dbg_info *dbgi = get_irn_dbg_info(node);
2632 ir_node *block = be_transform_node(get_nodes_block(node));
2633 ir_node *sel = get_Cond_selector(node);
2634 ir_node *new_sel = be_transform_node(sel);
2635 long switch_min = LONG_MAX;
2636 long switch_max = LONG_MIN;
2637 long default_pn = get_Cond_default_proj(node);
2639 const ir_edge_t *edge;
2641 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2643 /* determine the smallest switch case value */
2644 foreach_out_edge(node, edge) {
2645 ir_node *proj = get_edge_src_irn(edge);
2646 long pn = get_Proj_proj(proj);
2647 if (pn == default_pn)
2650 if (pn < switch_min)
2652 if (pn > switch_max)
2656 if ((unsigned long) (switch_max - switch_min) > 128000) {
2657 panic("Size of switch %+F bigger than 128000", node);
2660 if (switch_min != 0) {
2661 /* if smallest switch case is not 0 we need an additional sub */
2662 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2663 add_ia32_am_offs_int(new_sel, -switch_min);
2664 set_ia32_op_type(new_sel, ia32_AddrModeS);
2666 SET_IA32_ORIG_NODE(new_sel, node);
2669 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2670 SET_IA32_ORIG_NODE(new_node, node);
2676 * Transform a Cond node.
2678 static ir_node *gen_Cond(ir_node *node)
2680 ir_node *block = get_nodes_block(node);
2681 ir_node *new_block = be_transform_node(block);
2682 dbg_info *dbgi = get_irn_dbg_info(node);
2683 ir_node *sel = get_Cond_selector(node);
2684 ir_mode *sel_mode = get_irn_mode(sel);
2685 ir_node *flags = NULL;
2689 if (sel_mode != mode_b) {
2690 return create_Switch(node);
2693 /* we get flags from a Cmp */
2694 flags = get_flags_node(sel, &pnc);
2696 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2697 SET_IA32_ORIG_NODE(new_node, node);
2703 * Transform a be_Copy.
2705 static ir_node *gen_be_Copy(ir_node *node)
2707 ir_node *new_node = be_duplicate_node(node);
2708 ir_mode *mode = get_irn_mode(new_node);
2710 if (ia32_mode_needs_gp_reg(mode)) {
2711 set_irn_mode(new_node, mode_Iu);
2717 static ir_node *create_Fucom(ir_node *node)
2719 dbg_info *dbgi = get_irn_dbg_info(node);
2720 ir_node *block = get_nodes_block(node);
2721 ir_node *new_block = be_transform_node(block);
2722 ir_node *left = get_Cmp_left(node);
2723 ir_node *new_left = be_transform_node(left);
2724 ir_node *right = get_Cmp_right(node);
2728 if (ia32_cg_config.use_fucomi) {
2729 new_right = be_transform_node(right);
2730 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2732 set_ia32_commutative(new_node);
2733 SET_IA32_ORIG_NODE(new_node, node);
2735 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2736 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2738 new_right = be_transform_node(right);
2739 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2742 set_ia32_commutative(new_node);
2744 SET_IA32_ORIG_NODE(new_node, node);
2746 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2747 SET_IA32_ORIG_NODE(new_node, node);
2753 static ir_node *create_Ucomi(ir_node *node)
2755 dbg_info *dbgi = get_irn_dbg_info(node);
2756 ir_node *src_block = get_nodes_block(node);
2757 ir_node *new_block = be_transform_node(src_block);
2758 ir_node *left = get_Cmp_left(node);
2759 ir_node *right = get_Cmp_right(node);
2761 ia32_address_mode_t am;
2762 ia32_address_t *addr = &am.addr;
2764 match_arguments(&am, src_block, left, right, NULL,
2765 match_commutative | match_am);
2767 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2768 addr->mem, am.new_op1, am.new_op2,
2770 set_am_attributes(new_node, &am);
2772 SET_IA32_ORIG_NODE(new_node, node);
2774 new_node = fix_mem_proj(new_node, &am);
2780 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2781 * to fold an and into a test node
2783 static bool can_fold_test_and(ir_node *node)
2785 const ir_edge_t *edge;
2787 /** we can only have eq and lg projs */
2788 foreach_out_edge(node, edge) {
2789 ir_node *proj = get_edge_src_irn(edge);
2790 pn_Cmp pnc = get_Proj_proj(proj);
2791 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2799 * returns true if it is assured, that the upper bits of a node are "clean"
2800 * which means for a 16 or 8 bit value, that the upper bits in the register
2801 * are 0 for unsigned and a copy of the last significant bit for signed
2804 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2806 assert(ia32_mode_needs_gp_reg(mode));
2807 if (get_mode_size_bits(mode) >= 32)
2810 if (is_Proj(transformed_node))
2811 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2813 switch (get_ia32_irn_opcode(transformed_node)) {
2814 case iro_ia32_Conv_I2I:
2815 case iro_ia32_Conv_I2I8Bit: {
2816 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2817 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2819 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2826 if (mode_is_signed(mode)) {
2827 return false; /* TODO handle signed modes */
2829 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2830 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2831 const ia32_immediate_attr_t *attr
2832 = get_ia32_immediate_attr_const(right);
2833 if (attr->symconst == 0 &&
2834 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2838 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2842 /* TODO too conservative if shift amount is constant */
2843 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2846 if (!mode_is_signed(mode)) {
2848 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2849 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2851 /* TODO if one is known to be zero extended, then || is sufficient */
2856 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2857 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2859 case iro_ia32_Const:
2860 case iro_ia32_Immediate: {
2861 const ia32_immediate_attr_t *attr =
2862 get_ia32_immediate_attr_const(transformed_node);
2863 if (mode_is_signed(mode)) {
2864 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2865 return shifted == 0 || shifted == -1;
2867 unsigned long shifted = (unsigned long)attr->offset;
2868 shifted >>= get_mode_size_bits(mode);
2869 return shifted == 0;
2879 * Generate code for a Cmp.
2881 static ir_node *gen_Cmp(ir_node *node)
2883 dbg_info *dbgi = get_irn_dbg_info(node);
2884 ir_node *block = get_nodes_block(node);
2885 ir_node *new_block = be_transform_node(block);
2886 ir_node *left = get_Cmp_left(node);
2887 ir_node *right = get_Cmp_right(node);
2888 ir_mode *cmp_mode = get_irn_mode(left);
2890 ia32_address_mode_t am;
2891 ia32_address_t *addr = &am.addr;
2894 if (mode_is_float(cmp_mode)) {
2895 if (ia32_cg_config.use_sse2) {
2896 return create_Ucomi(node);
2898 return create_Fucom(node);
2902 assert(ia32_mode_needs_gp_reg(cmp_mode));
2904 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2905 cmp_unsigned = !mode_is_signed(cmp_mode);
2906 if (is_Const_0(right) &&
2908 get_irn_n_edges(left) == 1 &&
2909 can_fold_test_and(node)) {
2910 /* Test(and_left, and_right) */
2911 ir_node *and_left = get_And_left(left);
2912 ir_node *and_right = get_And_right(left);
2914 /* matze: code here used mode instead of cmd_mode, I think it is always
2915 * the same as cmp_mode, but I leave this here to see if this is really
2918 assert(get_irn_mode(and_left) == cmp_mode);
2920 match_arguments(&am, block, and_left, and_right, NULL,
2922 match_am | match_8bit_am | match_16bit_am |
2923 match_am_and_immediates | match_immediate);
2925 /* use 32bit compare mode if possible since the opcode is smaller */
2926 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2927 upper_bits_clean(am.new_op2, cmp_mode)) {
2928 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2931 if (get_mode_size_bits(cmp_mode) == 8) {
2932 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2933 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2936 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2937 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2940 /* Cmp(left, right) */
2941 match_arguments(&am, block, left, right, NULL,
2942 match_commutative | match_am | match_8bit_am |
2943 match_16bit_am | match_am_and_immediates |
2945 /* use 32bit compare mode if possible since the opcode is smaller */
2946 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2947 upper_bits_clean(am.new_op2, cmp_mode)) {
2948 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2951 if (get_mode_size_bits(cmp_mode) == 8) {
2952 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2953 addr->index, addr->mem, am.new_op1,
2954 am.new_op2, am.ins_permuted,
2957 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2958 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2961 set_am_attributes(new_node, &am);
2962 set_ia32_ls_mode(new_node, cmp_mode);
2964 SET_IA32_ORIG_NODE(new_node, node);
2966 new_node = fix_mem_proj(new_node, &am);
2971 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2974 dbg_info *dbgi = get_irn_dbg_info(node);
2975 ir_node *block = get_nodes_block(node);
2976 ir_node *new_block = be_transform_node(block);
2977 ir_node *val_true = get_Mux_true(node);
2978 ir_node *val_false = get_Mux_false(node);
2980 ia32_address_mode_t am;
2981 ia32_address_t *addr;
2983 assert(ia32_cg_config.use_cmov);
2984 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2988 match_arguments(&am, block, val_false, val_true, flags,
2989 match_commutative | match_am | match_16bit_am | match_mode_neutral);
2991 if (am.ins_permuted)
2992 pnc = ia32_get_negated_pnc(pnc);
2994 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
2995 addr->mem, am.new_op1, am.new_op2, new_flags,
2997 set_am_attributes(new_node, &am);
2999 SET_IA32_ORIG_NODE(new_node, node);
3001 new_node = fix_mem_proj(new_node, &am);
3007 * Creates a ia32 Setcc instruction.
3009 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3010 ir_node *flags, pn_Cmp pnc,
3013 ir_mode *mode = get_irn_mode(orig_node);
3016 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, pnc);
3017 SET_IA32_ORIG_NODE(new_node, orig_node);
3019 /* we might need to conv the result up */
3020 if (get_mode_size_bits(mode) > 8) {
3021 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3022 nomem, new_node, mode_Bu);
3023 SET_IA32_ORIG_NODE(new_node, orig_node);
3030 * Create instruction for an unsigned Difference or Zero.
3032 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3034 ir_mode *mode = get_irn_mode(psi);
3044 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3045 match_mode_neutral | match_am | match_immediate | match_two_users);
3047 block = get_nodes_block(new_node);
3049 if (is_Proj(new_node)) {
3050 sub = get_Proj_pred(new_node);
3051 assert(is_ia32_Sub(sub));
3054 set_irn_mode(sub, mode_T);
3055 new_node = new_rd_Proj(NULL, block, sub, mode, pn_ia32_res);
3057 eflags = new_rd_Proj(NULL, block, sub, mode_Iu, pn_ia32_Sub_flags);
3059 dbgi = get_irn_dbg_info(psi);
3060 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3061 not = new_bd_ia32_Not(dbgi, block, sbb);
3063 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, not);
3064 set_ia32_commutative(new_node);
3069 * Create an const array of two float consts.
3071 * @param c0 the first constant
3072 * @param c1 the second constant
3073 * @param new_mode IN/OUT for the mode of the constants, if NULL
3074 * smallest possible mode will be used
3076 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode) {
3078 ir_mode *mode = *new_mode;
3080 ir_initializer_t *initializer;
3081 tarval *tv0 = get_Const_tarval(c0);
3082 tarval *tv1 = get_Const_tarval(c1);
3085 /* detect the best mode for the constants */
3086 mode = get_tarval_mode(tv0);
3088 if (mode != mode_F) {
3089 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3090 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3092 tv0 = tarval_convert_to(tv0, mode);
3093 tv1 = tarval_convert_to(tv1, mode);
3094 } else if (mode != mode_D) {
3095 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3096 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3098 tv0 = tarval_convert_to(tv0, mode);
3099 tv1 = tarval_convert_to(tv1, mode);
3106 tp = ia32_create_float_type(mode, 4);
3107 tp = ia32_create_float_array(tp);
3109 ent = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp);
3111 set_entity_ld_ident(ent, get_entity_ident(ent));
3112 set_entity_visibility(ent, ir_visibility_local);
3113 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3115 initializer = create_initializer_compound(2);
3117 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3118 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3120 set_entity_initializer(ent, initializer);
3127 * Possible transformations for creating a Setcc.
3129 enum setcc_transform_insn {
3142 typedef struct setcc_transform {
3144 unsigned permutate_cmp_ins;
3147 enum setcc_transform_insn transform;
3151 } setcc_transform_t;
3154 * Setcc can only handle 0 and 1 result.
3155 * Find a transformation that creates 0 and 1 from
3158 static void find_const_transform(pn_Cmp pnc, tarval *t, tarval *f, setcc_transform_t *res, int can_permutate)
3163 res->permutate_cmp_ins = 0;
3165 if (tarval_is_null(t)) {
3169 pnc = ia32_get_negated_pnc(pnc);
3170 } else if (tarval_cmp(t, f) == pn_Cmp_Lt) {
3171 // now, t is the bigger one
3175 pnc = ia32_get_negated_pnc(pnc);
3179 if (tarval_is_one(t)) {
3180 res->steps[step].transform = SETCC_TR_SET;
3181 res->num_steps = ++step;
3185 if (! tarval_is_null(f)) {
3186 tarval *t_sub = tarval_sub(t, f, NULL);
3189 res->steps[step].transform = SETCC_TR_ADD;
3191 if (t == tarval_bad)
3192 panic("constant subtract failed");
3193 if (! tarval_is_long(f))
3194 panic("tarval is not long");
3196 res->steps[step].val = get_tarval_long(f);
3198 f = tarval_sub(f, f, NULL);
3199 assert(tarval_is_null(f));
3202 if (tarval_is_minus_one(t)) {
3203 if (pnc == (pn_Cmp_Lt | ia32_pn_Cmp_unsigned)) {
3204 res->steps[step].transform = SETCC_TR_SBB;
3205 res->num_steps = ++step;
3207 res->steps[step].transform = SETCC_TR_NEG;
3209 res->steps[step].transform = SETCC_TR_SET;
3210 res->num_steps = ++step;
3214 if (tarval_is_long(t)) {
3215 ir_mode *mode = get_tarval_mode(t);
3216 long v = get_tarval_long(t);
3218 if (pnc & ia32_pn_Cmp_unsigned) {
3219 if (pnc == (pn_Cmp_Lt | ia32_pn_Cmp_unsigned)) {
3220 res->steps[step].transform = SETCC_TR_AND;
3221 res->steps[step].val = v;
3224 res->steps[step].transform = SETCC_TR_SBB;
3225 res->num_steps = ++step;
3227 } else if (pnc == (pn_Cmp_Ge | ia32_pn_Cmp_unsigned)) {
3228 res->steps[step].transform = SETCC_TR_AND;
3229 res->steps[step].val = v;
3232 res->steps[step].transform = SETCC_TR_NOT;
3235 res->steps[step].transform = SETCC_TR_SBB;
3236 res->num_steps = ++step;
3238 } else if (can_permutate && pnc == (pn_Cmp_Gt | ia32_pn_Cmp_unsigned)) {
3239 res->permutate_cmp_ins ^= 1;
3241 res->steps[step].transform = SETCC_TR_NOT;
3244 res->steps[step].transform = SETCC_TR_AND;
3245 res->steps[step].val = v;
3248 res->steps[step].transform = SETCC_TR_SBB;
3249 res->num_steps = ++step;
3251 } else if (can_permutate && pnc == (pn_Cmp_Le | ia32_pn_Cmp_unsigned)) {
3252 res->permutate_cmp_ins ^= 1;
3254 res->steps[step].transform = SETCC_TR_AND;
3255 res->steps[step].val = v;
3258 res->steps[step].transform = SETCC_TR_SBB;
3259 res->num_steps = ++step;
3264 res->steps[step].val = 0;
3267 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3269 res->steps[step].transform = SETCC_TR_LEAxx;
3270 res->steps[step].scale = 3; /* (a << 3) + a */
3273 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3275 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3276 res->steps[step].scale = 3; /* (a << 3) */
3279 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3281 res->steps[step].transform = SETCC_TR_LEAxx;
3282 res->steps[step].scale = 2; /* (a << 2) + a */
3285 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3287 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3288 res->steps[step].scale = 2; /* (a << 2) */
3291 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3293 res->steps[step].transform = SETCC_TR_LEAxx;
3294 res->steps[step].scale = 1; /* (a << 1) + a */
3297 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3299 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3300 res->steps[step].scale = 1; /* (a << 1) */
3303 res->num_steps = step;
3306 if (! tarval_is_single_bit(t)) {
3307 res->steps[step].transform = SETCC_TR_AND;
3308 res->steps[step].val = v;
3310 res->steps[step].transform = SETCC_TR_NEG;
3312 int v = get_tarval_lowest_bit(t);
3315 res->steps[step].transform = SETCC_TR_SHL;
3316 res->steps[step].scale = v;
3320 res->steps[step].transform = SETCC_TR_SET;
3321 res->num_steps = ++step;
3324 panic("tarval is not long");
3328 * Transforms a Mux node into some code sequence.
3330 * @return The transformed node.
3332 static ir_node *gen_Mux(ir_node *node)
3334 dbg_info *dbgi = get_irn_dbg_info(node);
3335 ir_node *block = get_nodes_block(node);
3336 ir_node *new_block = be_transform_node(block);
3337 ir_node *mux_true = get_Mux_true(node);
3338 ir_node *mux_false = get_Mux_false(node);
3339 ir_node *cond = get_Mux_sel(node);
3340 ir_mode *mode = get_irn_mode(node);
3345 assert(get_irn_mode(cond) == mode_b);
3347 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3348 if (mode_is_float(mode)) {
3349 ir_node *cmp = get_Proj_pred(cond);
3350 ir_node *cmp_left = get_Cmp_left(cmp);
3351 ir_node *cmp_right = get_Cmp_right(cmp);
3352 pn_Cmp pnc = get_Proj_proj(cond);
3354 if (ia32_cg_config.use_sse2) {
3355 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3356 if (cmp_left == mux_true && cmp_right == mux_false) {
3357 /* Mux(a <= b, a, b) => MIN */
3358 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3359 match_commutative | match_am | match_two_users);
3360 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3361 /* Mux(a <= b, b, a) => MAX */
3362 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3363 match_commutative | match_am | match_two_users);
3365 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3366 if (cmp_left == mux_true && cmp_right == mux_false) {
3367 /* Mux(a >= b, a, b) => MAX */
3368 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3369 match_commutative | match_am | match_two_users);
3370 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3371 /* Mux(a >= b, b, a) => MIN */
3372 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3373 match_commutative | match_am | match_two_users);
3378 if (is_Const(mux_true) && is_Const(mux_false)) {
3379 ia32_address_mode_t am;
3385 flags = get_flags_node(cond, &pnc);
3386 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node);
3388 if (ia32_cg_config.use_sse2) {
3389 /* cannot load from different mode on SSE */
3392 /* x87 can load any mode */
3396 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3398 switch (get_mode_size_bytes(new_mode)) {
3408 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3409 set_ia32_am_scale(new_node, 2);
3414 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3415 set_ia32_am_scale(new_node, 1);
3418 /* arg, shift 16 NOT supported */
3420 new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, new_node);
3423 panic("Unsupported constant size");
3426 if (env_cg->birg->main_env->options->pic) {
3427 base = arch_code_generator_get_pic_base(env_cg);
3432 am.ls_mode = new_mode;
3433 am.addr.base = base;
3434 am.addr.index = new_node;
3435 am.addr.mem = nomem;
3437 am.addr.scale = scale;
3438 am.addr.use_frame = 0;
3439 am.addr.frame_entity = NULL;
3440 am.addr.symconst_sign = 0;
3441 am.mem_proj = am.addr.mem;
3442 am.op_type = ia32_AddrModeS;
3445 am.pinned = op_pin_state_floats;
3447 am.ins_permuted = 0;
3449 if (ia32_cg_config.use_sse2)
3450 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3452 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3453 set_am_attributes(load, &am);
3455 return new_rd_Proj(NULL, block, load, mode_vfp, pn_ia32_res);
3457 panic("cannot transform floating point Mux");
3460 assert(ia32_mode_needs_gp_reg(mode));
3462 if (is_Proj(cond)) {
3463 ir_node *cmp = get_Proj_pred(cond);
3465 ir_node *cmp_left = get_Cmp_left(cmp);
3466 ir_node *cmp_right = get_Cmp_right(cmp);
3467 pn_Cmp pnc = get_Proj_proj(cond);
3469 /* check for unsigned Doz first */
3470 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3471 is_Const_0(mux_false) && is_Sub(mux_true) &&
3472 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3473 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3474 return create_doz(node, cmp_left, cmp_right);
3475 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3476 is_Const_0(mux_true) && is_Sub(mux_false) &&
3477 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3478 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3479 return create_doz(node, cmp_left, cmp_right);
3484 flags = get_flags_node(cond, &pnc);
3486 if (is_Const(mux_true) && is_Const(mux_false)) {
3487 /* both are const, good */
3488 tarval *tv_true = get_Const_tarval(mux_true);
3489 tarval *tv_false = get_Const_tarval(mux_false);
3490 setcc_transform_t res;
3493 /* check if flags is a cmp node and we are the only user,
3494 i.e no other user yet */
3495 int permutate_allowed = 0;
3496 if (is_ia32_Cmp(flags) && get_irn_n_edges(flags) == 0) {
3497 /* yes, we can permutate its inputs */
3498 permutate_allowed = 1;
3500 find_const_transform(pnc, tv_true, tv_false, &res, 0);
3502 if (res.permutate_cmp_ins) {
3503 ia32_attr_t *attr = get_ia32_attr(flags);
3504 attr->data.ins_permuted ^= 1;
3506 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3509 switch (res.steps[step].transform) {
3511 imm = ia32_immediate_from_long(res.steps[step].val);
3512 new_node = new_bd_ia32_Add(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3514 case SETCC_TR_ADDxx:
3515 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3518 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3519 set_ia32_am_scale(new_node, res.steps[step].scale);
3520 set_ia32_am_offs_int(new_node, res.steps[step].val);
3522 case SETCC_TR_LEAxx:
3523 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3524 set_ia32_am_scale(new_node, res.steps[step].scale);
3525 set_ia32_am_offs_int(new_node, res.steps[step].val);
3528 imm = ia32_immediate_from_long(res.steps[step].scale);
3529 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3532 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3535 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3538 imm = ia32_immediate_from_long(res.steps[step].val);
3539 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3542 new_node = create_set_32bit(dbgi, new_block, flags, res.pnc, new_node);
3545 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3548 panic("unknown setcc transform");
3552 new_node = create_CMov(node, cond, flags, pnc);
3560 * Create a conversion from x87 state register to general purpose.
3562 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3564 ir_node *block = be_transform_node(get_nodes_block(node));
3565 ir_node *op = get_Conv_op(node);
3566 ir_node *new_op = be_transform_node(op);
3567 ir_graph *irg = current_ir_graph;
3568 dbg_info *dbgi = get_irn_dbg_info(node);
3569 ir_mode *mode = get_irn_mode(node);
3570 ir_node *fist, *load, *mem;
3572 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3573 set_irn_pinned(fist, op_pin_state_floats);
3574 set_ia32_use_frame(fist);
3575 set_ia32_op_type(fist, ia32_AddrModeD);
3577 assert(get_mode_size_bits(mode) <= 32);
3578 /* exception we can only store signed 32 bit integers, so for unsigned
3579 we store a 64bit (signed) integer and load the lower bits */
3580 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3581 set_ia32_ls_mode(fist, mode_Ls);
3583 set_ia32_ls_mode(fist, mode_Is);
3585 SET_IA32_ORIG_NODE(fist, node);
3588 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3590 set_irn_pinned(load, op_pin_state_floats);
3591 set_ia32_use_frame(load);
3592 set_ia32_op_type(load, ia32_AddrModeS);
3593 set_ia32_ls_mode(load, mode_Is);
3594 if (get_ia32_ls_mode(fist) == mode_Ls) {
3595 ia32_attr_t *attr = get_ia32_attr(load);
3596 attr->data.need_64bit_stackent = 1;
3598 ia32_attr_t *attr = get_ia32_attr(load);
3599 attr->data.need_32bit_stackent = 1;
3601 SET_IA32_ORIG_NODE(load, node);
3603 return new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
3607 * Creates a x87 strict Conv by placing a Store and a Load
3609 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3611 ir_node *block = get_nodes_block(node);
3612 ir_graph *irg = get_Block_irg(block);
3613 dbg_info *dbgi = get_irn_dbg_info(node);
3614 ir_node *frame = get_irg_frame(irg);
3615 ir_node *store, *load;
3618 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3619 set_ia32_use_frame(store);
3620 set_ia32_op_type(store, ia32_AddrModeD);
3621 SET_IA32_ORIG_NODE(store, node);
3623 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3624 set_ia32_use_frame(load);
3625 set_ia32_op_type(load, ia32_AddrModeS);
3626 SET_IA32_ORIG_NODE(load, node);
3628 new_node = new_r_Proj(block, load, mode_E, pn_ia32_vfld_res);
3632 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3633 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3635 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3637 func = get_mode_size_bits(mode) == 8 ?
3638 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3639 return func(dbgi, block, base, index, mem, val, mode);
3643 * Create a conversion from general purpose to x87 register
3645 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3647 ir_node *src_block = get_nodes_block(node);
3648 ir_node *block = be_transform_node(src_block);
3649 ir_graph *irg = get_Block_irg(block);
3650 dbg_info *dbgi = get_irn_dbg_info(node);
3651 ir_node *op = get_Conv_op(node);
3652 ir_node *new_op = NULL;
3654 ir_mode *store_mode;
3659 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3660 if (possible_int_mode_for_fp(src_mode)) {
3661 ia32_address_mode_t am;
3663 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3664 if (am.op_type == ia32_AddrModeS) {
3665 ia32_address_t *addr = &am.addr;
3667 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3668 new_node = new_r_Proj(block, fild, mode_vfp, pn_ia32_vfild_res);
3670 set_am_attributes(fild, &am);
3671 SET_IA32_ORIG_NODE(fild, node);
3673 fix_mem_proj(fild, &am);
3678 if (new_op == NULL) {
3679 new_op = be_transform_node(op);
3682 mode = get_irn_mode(op);
3684 /* first convert to 32 bit signed if necessary */
3685 if (get_mode_size_bits(src_mode) < 32) {
3686 if (!upper_bits_clean(new_op, src_mode)) {
3687 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3688 SET_IA32_ORIG_NODE(new_op, node);
3693 assert(get_mode_size_bits(mode) == 32);
3696 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3698 set_ia32_use_frame(store);
3699 set_ia32_op_type(store, ia32_AddrModeD);
3700 set_ia32_ls_mode(store, mode_Iu);
3702 /* exception for 32bit unsigned, do a 64bit spill+load */
3703 if (!mode_is_signed(mode)) {
3706 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3708 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3709 noreg_GP, nomem, zero_const);
3711 set_ia32_use_frame(zero_store);
3712 set_ia32_op_type(zero_store, ia32_AddrModeD);
3713 add_ia32_am_offs_int(zero_store, 4);
3714 set_ia32_ls_mode(zero_store, mode_Iu);
3719 store = new_rd_Sync(dbgi, block, 2, in);
3720 store_mode = mode_Ls;
3722 store_mode = mode_Is;
3726 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3728 set_ia32_use_frame(fild);
3729 set_ia32_op_type(fild, ia32_AddrModeS);
3730 set_ia32_ls_mode(fild, store_mode);
3732 new_node = new_r_Proj(block, fild, mode_vfp, pn_ia32_vfild_res);
3738 * Create a conversion from one integer mode into another one
3740 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3741 dbg_info *dbgi, ir_node *block, ir_node *op,
3744 ir_node *new_block = be_transform_node(block);
3746 ir_mode *smaller_mode;
3747 ia32_address_mode_t am;
3748 ia32_address_t *addr = &am.addr;
3751 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3752 smaller_mode = src_mode;
3754 smaller_mode = tgt_mode;
3757 #ifdef DEBUG_libfirm
3759 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3764 match_arguments(&am, block, NULL, op, NULL,
3765 match_am | match_8bit_am | match_16bit_am);
3767 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3768 /* unnecessary conv. in theory it shouldn't have been AM */
3769 assert(is_ia32_NoReg_GP(addr->base));
3770 assert(is_ia32_NoReg_GP(addr->index));
3771 assert(is_NoMem(addr->mem));
3772 assert(am.addr.offset == 0);
3773 assert(am.addr.symconst_ent == NULL);
3777 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3778 addr->mem, am.new_op2, smaller_mode);
3779 set_am_attributes(new_node, &am);
3780 /* match_arguments assume that out-mode = in-mode, this isn't true here
3782 set_ia32_ls_mode(new_node, smaller_mode);
3783 SET_IA32_ORIG_NODE(new_node, node);
3784 new_node = fix_mem_proj(new_node, &am);
3789 * Transforms a Conv node.
3791 * @return The created ia32 Conv node
3793 static ir_node *gen_Conv(ir_node *node)
3795 ir_node *block = get_nodes_block(node);
3796 ir_node *new_block = be_transform_node(block);
3797 ir_node *op = get_Conv_op(node);
3798 ir_node *new_op = NULL;
3799 dbg_info *dbgi = get_irn_dbg_info(node);
3800 ir_mode *src_mode = get_irn_mode(op);
3801 ir_mode *tgt_mode = get_irn_mode(node);
3802 int src_bits = get_mode_size_bits(src_mode);
3803 int tgt_bits = get_mode_size_bits(tgt_mode);
3804 ir_node *res = NULL;
3806 assert(!mode_is_int(src_mode) || src_bits <= 32);
3807 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3809 /* modeB -> X should already be lowered by the lower_mode_b pass */
3810 if (src_mode == mode_b) {
3811 panic("ConvB not lowered %+F", node);
3814 if (src_mode == tgt_mode) {
3815 if (get_Conv_strict(node)) {
3816 if (ia32_cg_config.use_sse2) {
3817 /* when we are in SSE mode, we can kill all strict no-op conversion */
3818 return be_transform_node(op);
3821 /* this should be optimized already, but who knows... */
3822 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3823 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3824 return be_transform_node(op);
3828 if (mode_is_float(src_mode)) {
3829 new_op = be_transform_node(op);
3830 /* we convert from float ... */
3831 if (mode_is_float(tgt_mode)) {
3833 if (ia32_cg_config.use_sse2) {
3834 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3835 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3837 set_ia32_ls_mode(res, tgt_mode);
3839 if (get_Conv_strict(node)) {
3840 /* if fp_no_float_fold is not set then we assume that we
3841 * don't have any float operations in a non
3842 * mode_float_arithmetic mode and can skip strict upconvs */
3843 if (src_bits < tgt_bits
3844 && !(get_irg_fp_model(current_ir_graph) & fp_no_float_fold)) {
3845 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3848 res = gen_x87_strict_conv(tgt_mode, new_op);
3849 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3853 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3858 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3859 if (ia32_cg_config.use_sse2) {
3860 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3862 set_ia32_ls_mode(res, src_mode);
3864 return gen_x87_fp_to_gp(node);
3868 /* we convert from int ... */
3869 if (mode_is_float(tgt_mode)) {
3871 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3872 if (ia32_cg_config.use_sse2) {
3873 new_op = be_transform_node(op);
3874 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3876 set_ia32_ls_mode(res, tgt_mode);
3878 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3879 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3880 res = gen_x87_gp_to_fp(node, src_mode);
3882 /* we need a strict-Conv, if the int mode has more bits than the
3884 if (float_mantissa < int_mantissa) {
3885 res = gen_x87_strict_conv(tgt_mode, res);
3886 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3890 } else if (tgt_mode == mode_b) {
3891 /* mode_b lowering already took care that we only have 0/1 values */
3892 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3893 src_mode, tgt_mode));
3894 return be_transform_node(op);
3897 if (src_bits == tgt_bits) {
3898 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3899 src_mode, tgt_mode));
3900 return be_transform_node(op);
3903 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3911 static ir_node *create_immediate_or_transform(ir_node *node,
3912 char immediate_constraint_type)
3914 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3915 if (new_node == NULL) {
3916 new_node = be_transform_node(node);
3922 * Transforms a FrameAddr into an ia32 Add.
3924 static ir_node *gen_be_FrameAddr(ir_node *node)
3926 ir_node *block = be_transform_node(get_nodes_block(node));
3927 ir_node *op = be_get_FrameAddr_frame(node);
3928 ir_node *new_op = be_transform_node(op);
3929 dbg_info *dbgi = get_irn_dbg_info(node);
3932 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3933 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3934 set_ia32_use_frame(new_node);
3936 SET_IA32_ORIG_NODE(new_node, node);
3942 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3944 static ir_node *gen_be_Return(ir_node *node)
3946 ir_graph *irg = current_ir_graph;
3947 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3948 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3949 ir_entity *ent = get_irg_entity(irg);
3950 ir_type *tp = get_entity_type(ent);
3955 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3956 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3958 int pn_ret_val, pn_ret_mem, arity, i;
3960 assert(ret_val != NULL);
3961 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3962 return be_duplicate_node(node);
3965 res_type = get_method_res_type(tp, 0);
3967 if (! is_Primitive_type(res_type)) {
3968 return be_duplicate_node(node);
3971 mode = get_type_mode(res_type);
3972 if (! mode_is_float(mode)) {
3973 return be_duplicate_node(node);
3976 assert(get_method_n_ress(tp) == 1);
3978 pn_ret_val = get_Proj_proj(ret_val);
3979 pn_ret_mem = get_Proj_proj(ret_mem);
3981 /* get the Barrier */
3982 barrier = get_Proj_pred(ret_val);
3984 /* get result input of the Barrier */
3985 ret_val = get_irn_n(barrier, pn_ret_val);
3986 new_ret_val = be_transform_node(ret_val);
3988 /* get memory input of the Barrier */
3989 ret_mem = get_irn_n(barrier, pn_ret_mem);
3990 new_ret_mem = be_transform_node(ret_mem);
3992 frame = get_irg_frame(irg);
3994 dbgi = get_irn_dbg_info(barrier);
3995 block = be_transform_node(get_nodes_block(barrier));
3997 /* store xmm0 onto stack */
3998 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
3999 new_ret_mem, new_ret_val);
4000 set_ia32_ls_mode(sse_store, mode);
4001 set_ia32_op_type(sse_store, ia32_AddrModeD);
4002 set_ia32_use_frame(sse_store);
4004 /* load into x87 register */
4005 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
4006 set_ia32_op_type(fld, ia32_AddrModeS);
4007 set_ia32_use_frame(fld);
4009 mproj = new_r_Proj(block, fld, mode_M, pn_ia32_vfld_M);
4010 fld = new_r_Proj(block, fld, mode_vfp, pn_ia32_vfld_res);
4012 /* create a new barrier */
4013 arity = get_irn_arity(barrier);
4014 in = ALLOCAN(ir_node*, arity);
4015 for (i = 0; i < arity; ++i) {
4018 if (i == pn_ret_val) {
4020 } else if (i == pn_ret_mem) {
4023 ir_node *in = get_irn_n(barrier, i);
4024 new_in = be_transform_node(in);
4029 new_barrier = new_ir_node(dbgi, irg, block,
4030 get_irn_op(barrier), get_irn_mode(barrier),
4032 copy_node_attr(barrier, new_barrier);
4033 be_duplicate_deps(barrier, new_barrier);
4034 be_set_transformed_node(barrier, new_barrier);
4036 /* transform normally */
4037 return be_duplicate_node(node);
4041 * Transform a be_AddSP into an ia32_SubSP.
4043 static ir_node *gen_be_AddSP(ir_node *node)
4045 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4046 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4048 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4049 match_am | match_immediate);
4053 * Transform a be_SubSP into an ia32_AddSP
4055 static ir_node *gen_be_SubSP(ir_node *node)
4057 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4058 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4060 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4061 match_am | match_immediate);
4065 * Change some phi modes
4067 static ir_node *gen_Phi(ir_node *node)
4069 const arch_register_req_t *req;
4070 ir_node *block = be_transform_node(get_nodes_block(node));
4071 ir_graph *irg = current_ir_graph;
4072 dbg_info *dbgi = get_irn_dbg_info(node);
4073 ir_mode *mode = get_irn_mode(node);
4076 if (ia32_mode_needs_gp_reg(mode)) {
4077 /* we shouldn't have any 64bit stuff around anymore */
4078 assert(get_mode_size_bits(mode) <= 32);
4079 /* all integer operations are on 32bit registers now */
4081 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4082 } else if (mode_is_float(mode)) {
4083 if (ia32_cg_config.use_sse2) {
4085 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4088 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4091 req = arch_no_register_req;
4094 /* phi nodes allow loops, so we use the old arguments for now
4095 * and fix this later */
4096 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4097 get_irn_in(node) + 1);
4098 copy_node_attr(node, phi);
4099 be_duplicate_deps(node, phi);
4101 arch_set_out_register_req(phi, 0, req);
4103 be_enqueue_preds(node);
4108 static ir_node *gen_Jmp(ir_node *node)
4110 ir_node *block = get_nodes_block(node);
4111 ir_node *new_block = be_transform_node(block);
4112 dbg_info *dbgi = get_irn_dbg_info(node);
4115 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4116 SET_IA32_ORIG_NODE(new_node, node);
4124 static ir_node *gen_IJmp(ir_node *node)
4126 ir_node *block = get_nodes_block(node);
4127 ir_node *new_block = be_transform_node(block);
4128 dbg_info *dbgi = get_irn_dbg_info(node);
4129 ir_node *op = get_IJmp_target(node);
4131 ia32_address_mode_t am;
4132 ia32_address_t *addr = &am.addr;
4134 assert(get_irn_mode(op) == mode_P);
4136 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4138 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4139 addr->mem, am.new_op2);
4140 set_am_attributes(new_node, &am);
4141 SET_IA32_ORIG_NODE(new_node, node);
4143 new_node = fix_mem_proj(new_node, &am);
4149 * Transform a Bound node.
4151 static ir_node *gen_Bound(ir_node *node)
4154 ir_node *lower = get_Bound_lower(node);
4155 dbg_info *dbgi = get_irn_dbg_info(node);
4157 if (is_Const_0(lower)) {
4158 /* typical case for Java */
4159 ir_node *sub, *res, *flags, *block;
4161 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
4162 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
4164 block = get_nodes_block(res);
4165 if (! is_Proj(res)) {
4167 set_irn_mode(sub, mode_T);
4168 res = new_rd_Proj(NULL, block, sub, mode_Iu, pn_ia32_res);
4170 sub = get_Proj_pred(res);
4172 flags = new_rd_Proj(NULL, block, sub, mode_Iu, pn_ia32_Sub_flags);
4173 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
4174 SET_IA32_ORIG_NODE(new_node, node);
4176 panic("generic Bound not supported in ia32 Backend");
4182 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4184 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4185 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4187 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
4188 match_immediate | match_mode_neutral);
4191 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4193 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4194 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4195 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
4199 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4201 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4202 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4203 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
4207 static ir_node *gen_ia32_l_Add(ir_node *node)
4209 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4210 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4211 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4212 match_commutative | match_am | match_immediate |
4213 match_mode_neutral);
4215 if (is_Proj(lowered)) {
4216 lowered = get_Proj_pred(lowered);
4218 assert(is_ia32_Add(lowered));
4219 set_irn_mode(lowered, mode_T);
4225 static ir_node *gen_ia32_l_Adc(ir_node *node)
4227 return gen_binop_flags(node, new_bd_ia32_Adc,
4228 match_commutative | match_am | match_immediate |
4229 match_mode_neutral);
4233 * Transforms a l_MulS into a "real" MulS node.
4235 * @return the created ia32 Mul node
4237 static ir_node *gen_ia32_l_Mul(ir_node *node)
4239 ir_node *left = get_binop_left(node);
4240 ir_node *right = get_binop_right(node);
4242 return gen_binop(node, left, right, new_bd_ia32_Mul,
4243 match_commutative | match_am | match_mode_neutral);
4247 * Transforms a l_IMulS into a "real" IMul1OPS node.
4249 * @return the created ia32 IMul1OP node
4251 static ir_node *gen_ia32_l_IMul(ir_node *node)
4253 ir_node *left = get_binop_left(node);
4254 ir_node *right = get_binop_right(node);
4256 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4257 match_commutative | match_am | match_mode_neutral);
4260 static ir_node *gen_ia32_l_Sub(ir_node *node)
4262 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4263 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4264 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4265 match_am | match_immediate | match_mode_neutral);
4267 if (is_Proj(lowered)) {
4268 lowered = get_Proj_pred(lowered);
4270 assert(is_ia32_Sub(lowered));
4271 set_irn_mode(lowered, mode_T);
4277 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4279 return gen_binop_flags(node, new_bd_ia32_Sbb,
4280 match_am | match_immediate | match_mode_neutral);
4284 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4285 * op1 - target to be shifted
4286 * op2 - contains bits to be shifted into target
4288 * Only op3 can be an immediate.
4290 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4291 ir_node *low, ir_node *count)
4293 ir_node *block = get_nodes_block(node);
4294 ir_node *new_block = be_transform_node(block);
4295 dbg_info *dbgi = get_irn_dbg_info(node);
4296 ir_node *new_high = be_transform_node(high);
4297 ir_node *new_low = be_transform_node(low);
4301 /* the shift amount can be any mode that is bigger than 5 bits, since all
4302 * other bits are ignored anyway */
4303 while (is_Conv(count) &&
4304 get_irn_n_edges(count) == 1 &&
4305 mode_is_int(get_irn_mode(count))) {
4306 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4307 count = get_Conv_op(count);
4309 new_count = create_immediate_or_transform(count, 0);
4311 if (is_ia32_l_ShlD(node)) {
4312 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4315 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4318 SET_IA32_ORIG_NODE(new_node, node);
4323 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4325 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4326 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4327 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4328 return gen_lowered_64bit_shifts(node, high, low, count);
4331 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4333 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4334 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4335 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4336 return gen_lowered_64bit_shifts(node, high, low, count);
4339 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4341 ir_node *src_block = get_nodes_block(node);
4342 ir_node *block = be_transform_node(src_block);
4343 ir_graph *irg = current_ir_graph;
4344 dbg_info *dbgi = get_irn_dbg_info(node);
4345 ir_node *frame = get_irg_frame(irg);
4346 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4347 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4348 ir_node *new_val_low = be_transform_node(val_low);
4349 ir_node *new_val_high = be_transform_node(val_high);
4351 ir_node *sync, *fild, *res;
4352 ir_node *store_low, *store_high;
4354 if (ia32_cg_config.use_sse2) {
4355 panic("ia32_l_LLtoFloat not implemented for SSE2");
4359 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4361 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4363 SET_IA32_ORIG_NODE(store_low, node);
4364 SET_IA32_ORIG_NODE(store_high, node);
4366 set_ia32_use_frame(store_low);
4367 set_ia32_use_frame(store_high);
4368 set_ia32_op_type(store_low, ia32_AddrModeD);
4369 set_ia32_op_type(store_high, ia32_AddrModeD);
4370 set_ia32_ls_mode(store_low, mode_Iu);
4371 set_ia32_ls_mode(store_high, mode_Is);
4372 add_ia32_am_offs_int(store_high, 4);
4376 sync = new_rd_Sync(dbgi, block, 2, in);
4379 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4381 set_ia32_use_frame(fild);
4382 set_ia32_op_type(fild, ia32_AddrModeS);
4383 set_ia32_ls_mode(fild, mode_Ls);
4385 SET_IA32_ORIG_NODE(fild, node);
4387 res = new_r_Proj(block, fild, mode_vfp, pn_ia32_vfild_res);
4389 if (! mode_is_signed(get_irn_mode(val_high))) {
4390 ia32_address_mode_t am;
4392 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4395 am.addr.base = noreg_GP;
4396 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4397 am.addr.mem = nomem;
4400 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4401 am.addr.use_frame = 0;
4402 am.addr.frame_entity = NULL;
4403 am.addr.symconst_sign = 0;
4404 am.ls_mode = mode_F;
4405 am.mem_proj = nomem;
4406 am.op_type = ia32_AddrModeS;
4408 am.new_op2 = ia32_new_NoReg_vfp(env_cg);
4409 am.pinned = op_pin_state_floats;
4411 am.ins_permuted = 0;
4413 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4414 am.new_op1, am.new_op2, get_fpcw());
4415 set_am_attributes(fadd, &am);
4417 set_irn_mode(fadd, mode_T);
4418 res = new_rd_Proj(NULL, block, fadd, mode_vfp, pn_ia32_res);
4423 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4425 ir_node *src_block = get_nodes_block(node);
4426 ir_node *block = be_transform_node(src_block);
4427 ir_graph *irg = get_Block_irg(block);
4428 dbg_info *dbgi = get_irn_dbg_info(node);
4429 ir_node *frame = get_irg_frame(irg);
4430 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4431 ir_node *new_val = be_transform_node(val);
4432 ir_node *fist, *mem;
4434 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4435 SET_IA32_ORIG_NODE(fist, node);
4436 set_ia32_use_frame(fist);
4437 set_ia32_op_type(fist, ia32_AddrModeD);
4438 set_ia32_ls_mode(fist, mode_Ls);
4444 * the BAD transformer.
4446 static ir_node *bad_transform(ir_node *node)
4448 panic("No transform function for %+F available.", node);
4452 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4454 ir_node *block = be_transform_node(get_nodes_block(node));
4455 ir_graph *irg = get_Block_irg(block);
4456 ir_node *pred = get_Proj_pred(node);
4457 ir_node *new_pred = be_transform_node(pred);
4458 ir_node *frame = get_irg_frame(irg);
4459 dbg_info *dbgi = get_irn_dbg_info(node);
4460 long pn = get_Proj_proj(node);
4465 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4466 SET_IA32_ORIG_NODE(load, node);
4467 set_ia32_use_frame(load);
4468 set_ia32_op_type(load, ia32_AddrModeS);
4469 set_ia32_ls_mode(load, mode_Iu);
4470 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4471 * 32 bit from it with this particular load */
4472 attr = get_ia32_attr(load);
4473 attr->data.need_64bit_stackent = 1;
4475 if (pn == pn_ia32_l_FloattoLL_res_high) {
4476 add_ia32_am_offs_int(load, 4);
4478 assert(pn == pn_ia32_l_FloattoLL_res_low);
4481 proj = new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
4487 * Transform the Projs of an AddSP.
4489 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4491 ir_node *block = be_transform_node(get_nodes_block(node));
4492 ir_node *pred = get_Proj_pred(node);
4493 ir_node *new_pred = be_transform_node(pred);
4494 dbg_info *dbgi = get_irn_dbg_info(node);
4495 long proj = get_Proj_proj(node);
4497 if (proj == pn_be_AddSP_sp) {
4498 ir_node *res = new_rd_Proj(dbgi, block, new_pred, mode_Iu,
4499 pn_ia32_SubSP_stack);
4500 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4502 } else if (proj == pn_be_AddSP_res) {
4503 return new_rd_Proj(dbgi, block, new_pred, mode_Iu,
4504 pn_ia32_SubSP_addr);
4505 } else if (proj == pn_be_AddSP_M) {
4506 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_SubSP_M);
4509 panic("No idea how to transform proj->AddSP");
4513 * Transform the Projs of a SubSP.
4515 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4517 ir_node *block = be_transform_node(get_nodes_block(node));
4518 ir_node *pred = get_Proj_pred(node);
4519 ir_node *new_pred = be_transform_node(pred);
4520 dbg_info *dbgi = get_irn_dbg_info(node);
4521 long proj = get_Proj_proj(node);
4523 if (proj == pn_be_SubSP_sp) {
4524 ir_node *res = new_rd_Proj(dbgi, block, new_pred, mode_Iu,
4525 pn_ia32_AddSP_stack);
4526 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4528 } else if (proj == pn_be_SubSP_M) {
4529 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_AddSP_M);
4532 panic("No idea how to transform proj->SubSP");
4536 * Transform and renumber the Projs from a Load.
4538 static ir_node *gen_Proj_Load(ir_node *node)
4541 ir_node *block = be_transform_node(get_nodes_block(node));
4542 ir_node *pred = get_Proj_pred(node);
4543 dbg_info *dbgi = get_irn_dbg_info(node);
4544 long proj = get_Proj_proj(node);
4546 /* loads might be part of source address mode matches, so we don't
4547 * transform the ProjMs yet (with the exception of loads whose result is
4550 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4552 ir_node *old_block = get_nodes_block(node);
4554 /* this is needed, because sometimes we have loops that are only
4555 reachable through the ProjM */
4556 be_enqueue_preds(node);
4557 /* do it in 2 steps, to silence firm verifier */
4558 res = new_rd_Proj(dbgi, old_block, pred, mode_M, pn_Load_M);
4559 set_Proj_proj(res, pn_ia32_mem);
4563 /* renumber the proj */
4564 new_pred = be_transform_node(pred);
4565 if (is_ia32_Load(new_pred)) {
4568 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Load_res);
4570 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Load_M);
4571 case pn_Load_X_regular:
4572 return new_rd_Jmp(dbgi, block);
4573 case pn_Load_X_except:
4574 /* This Load might raise an exception. Mark it. */
4575 set_ia32_exc_label(new_pred, 1);
4576 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4580 } else if (is_ia32_Conv_I2I(new_pred) ||
4581 is_ia32_Conv_I2I8Bit(new_pred)) {
4582 set_irn_mode(new_pred, mode_T);
4583 if (proj == pn_Load_res) {
4584 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_res);
4585 } else if (proj == pn_Load_M) {
4586 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_mem);
4588 } else if (is_ia32_xLoad(new_pred)) {
4591 return new_rd_Proj(dbgi, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4593 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_xLoad_M);
4594 case pn_Load_X_regular:
4595 return new_rd_Jmp(dbgi, block);
4596 case pn_Load_X_except:
4597 /* This Load might raise an exception. Mark it. */
4598 set_ia32_exc_label(new_pred, 1);
4599 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4603 } else if (is_ia32_vfld(new_pred)) {
4606 return new_rd_Proj(dbgi, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4608 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_vfld_M);
4609 case pn_Load_X_regular:
4610 return new_rd_Jmp(dbgi, block);
4611 case pn_Load_X_except:
4612 /* This Load might raise an exception. Mark it. */
4613 set_ia32_exc_label(new_pred, 1);
4614 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_vfld_X_exc);
4619 /* can happen for ProJMs when source address mode happened for the
4622 /* however it should not be the result proj, as that would mean the
4623 load had multiple users and should not have been used for
4625 if (proj != pn_Load_M) {
4626 panic("internal error: transformed node not a Load");
4628 return new_rd_Proj(dbgi, block, new_pred, mode_M, 1);
4631 panic("No idea how to transform proj");
4635 * Transform and renumber the Projs from a DivMod like instruction.
4637 static ir_node *gen_Proj_DivMod(ir_node *node)
4639 ir_node *block = be_transform_node(get_nodes_block(node));
4640 ir_node *pred = get_Proj_pred(node);
4641 ir_node *new_pred = be_transform_node(pred);
4642 dbg_info *dbgi = get_irn_dbg_info(node);
4643 long proj = get_Proj_proj(node);
4645 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4647 switch (get_irn_opcode(pred)) {
4651 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Div_M);
4653 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4654 case pn_Div_X_regular:
4655 return new_rd_Jmp(dbgi, block);
4656 case pn_Div_X_except:
4657 set_ia32_exc_label(new_pred, 1);
4658 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4666 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Div_M);
4668 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4669 case pn_Mod_X_except:
4670 set_ia32_exc_label(new_pred, 1);
4671 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4679 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_Div_M);
4680 case pn_DivMod_res_div:
4681 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4682 case pn_DivMod_res_mod:
4683 return new_rd_Proj(dbgi, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4684 case pn_DivMod_X_regular:
4685 return new_rd_Jmp(dbgi, block);
4686 case pn_DivMod_X_except:
4687 set_ia32_exc_label(new_pred, 1);
4688 return new_rd_Proj(dbgi, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4697 panic("No idea how to transform proj->DivMod");
4701 * Transform and renumber the Projs from a CopyB.
4703 static ir_node *gen_Proj_CopyB(ir_node *node)
4705 ir_node *block = be_transform_node(get_nodes_block(node));
4706 ir_node *pred = get_Proj_pred(node);
4707 ir_node *new_pred = be_transform_node(pred);
4708 dbg_info *dbgi = get_irn_dbg_info(node);
4709 long proj = get_Proj_proj(node);
4712 case pn_CopyB_M_regular:
4713 if (is_ia32_CopyB_i(new_pred)) {
4714 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4715 } else if (is_ia32_CopyB(new_pred)) {
4716 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_CopyB_M);
4723 panic("No idea how to transform proj->CopyB");
4727 * Transform and renumber the Projs from a Quot.
4729 static ir_node *gen_Proj_Quot(ir_node *node)
4731 ir_node *block = be_transform_node(get_nodes_block(node));
4732 ir_node *pred = get_Proj_pred(node);
4733 ir_node *new_pred = be_transform_node(pred);
4734 dbg_info *dbgi = get_irn_dbg_info(node);
4735 long proj = get_Proj_proj(node);
4739 if (is_ia32_xDiv(new_pred)) {
4740 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_xDiv_M);
4741 } else if (is_ia32_vfdiv(new_pred)) {
4742 return new_rd_Proj(dbgi, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4746 if (is_ia32_xDiv(new_pred)) {
4747 return new_rd_Proj(dbgi, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4748 } else if (is_ia32_vfdiv(new_pred)) {
4749 return new_rd_Proj(dbgi, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4752 case pn_Quot_X_regular:
4753 case pn_Quot_X_except:
4758 panic("No idea how to transform proj->Quot");
4761 static ir_node *gen_be_Call(ir_node *node)
4763 dbg_info *const dbgi = get_irn_dbg_info(node);
4764 ir_node *const src_block = get_nodes_block(node);
4765 ir_node *const block = be_transform_node(src_block);
4766 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4767 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4768 ir_node *const sp = be_transform_node(src_sp);
4769 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4770 ia32_address_mode_t am;
4771 ia32_address_t *const addr = &am.addr;
4776 ir_node * eax = noreg_GP;
4777 ir_node * ecx = noreg_GP;
4778 ir_node * edx = noreg_GP;
4779 unsigned const pop = be_Call_get_pop(node);
4780 ir_type *const call_tp = be_Call_get_type(node);
4781 int old_no_pic_adjust;
4783 /* Run the x87 simulator if the call returns a float value */
4784 if (get_method_n_ress(call_tp) > 0) {
4785 ir_type *const res_type = get_method_res_type(call_tp, 0);
4786 ir_mode *const res_mode = get_type_mode(res_type);
4788 if (res_mode != NULL && mode_is_float(res_mode)) {
4789 env_cg->do_x87_sim = 1;
4793 /* We do not want be_Call direct calls */
4794 assert(be_Call_get_entity(node) == NULL);
4796 /* special case for PIC trampoline calls */
4797 old_no_pic_adjust = no_pic_adjust;
4798 no_pic_adjust = env_cg->birg->main_env->options->pic;
4800 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4801 match_am | match_immediate);
4803 no_pic_adjust = old_no_pic_adjust;
4805 i = get_irn_arity(node) - 1;
4806 fpcw = be_transform_node(get_irn_n(node, i--));
4807 for (; i >= be_pos_Call_first_arg; --i) {
4808 arch_register_req_t const *const req = arch_get_register_req(node, i);
4809 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4811 assert(req->type == arch_register_req_type_limited);
4812 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4814 switch (*req->limited) {
4815 case 1 << REG_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4816 case 1 << REG_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4817 case 1 << REG_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4818 default: panic("Invalid GP register for register parameter");
4822 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4823 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4824 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4825 set_am_attributes(call, &am);
4826 call = fix_mem_proj(call, &am);
4828 if (get_irn_pinned(node) == op_pin_state_pinned)
4829 set_irn_pinned(call, op_pin_state_pinned);
4831 SET_IA32_ORIG_NODE(call, node);
4833 if (ia32_cg_config.use_sse2) {
4834 /* remember this call for post-processing */
4835 ARR_APP1(ir_node *, call_list, call);
4836 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4843 * Transform Builtin trap
4845 static ir_node *gen_trap(ir_node *node) {
4846 dbg_info *dbgi = get_irn_dbg_info(node);
4847 ir_node *block = be_transform_node(get_nodes_block(node));
4848 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4850 return new_bd_ia32_UD2(dbgi, block, mem);
4854 * Transform Builtin debugbreak
4856 static ir_node *gen_debugbreak(ir_node *node) {
4857 dbg_info *dbgi = get_irn_dbg_info(node);
4858 ir_node *block = be_transform_node(get_nodes_block(node));
4859 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4861 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4865 * Transform Builtin return_address
4867 static ir_node *gen_return_address(ir_node *node) {
4868 ir_node *param = get_Builtin_param(node, 0);
4869 ir_node *frame = get_Builtin_param(node, 1);
4870 dbg_info *dbgi = get_irn_dbg_info(node);
4871 tarval *tv = get_Const_tarval(param);
4872 unsigned long value = get_tarval_long(tv);
4874 ir_node *block = be_transform_node(get_nodes_block(node));
4875 ir_node *ptr = be_transform_node(frame);
4879 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4880 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4881 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4884 /* load the return address from this frame */
4885 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4887 set_irn_pinned(load, get_irn_pinned(node));
4888 set_ia32_op_type(load, ia32_AddrModeS);
4889 set_ia32_ls_mode(load, mode_Iu);
4891 set_ia32_am_offs_int(load, 0);
4892 set_ia32_use_frame(load);
4893 set_ia32_frame_ent(load, ia32_get_return_address_entity());
4895 if (get_irn_pinned(node) == op_pin_state_floats) {
4896 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
4897 && pn_ia32_vfld_res == pn_ia32_Load_res
4898 && pn_ia32_Load_res == pn_ia32_res);
4899 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4902 SET_IA32_ORIG_NODE(load, node);
4903 return new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
4907 * Transform Builtin frame_address
4909 static ir_node *gen_frame_address(ir_node *node) {
4910 ir_node *param = get_Builtin_param(node, 0);
4911 ir_node *frame = get_Builtin_param(node, 1);
4912 dbg_info *dbgi = get_irn_dbg_info(node);
4913 tarval *tv = get_Const_tarval(param);
4914 unsigned long value = get_tarval_long(tv);
4916 ir_node *block = be_transform_node(get_nodes_block(node));
4917 ir_node *ptr = be_transform_node(frame);
4922 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4923 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4924 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4927 /* load the frame address from this frame */
4928 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4930 set_irn_pinned(load, get_irn_pinned(node));
4931 set_ia32_op_type(load, ia32_AddrModeS);
4932 set_ia32_ls_mode(load, mode_Iu);
4934 ent = ia32_get_frame_address_entity();
4936 set_ia32_am_offs_int(load, 0);
4937 set_ia32_use_frame(load);
4938 set_ia32_frame_ent(load, ent);
4940 /* will fail anyway, but gcc does this: */
4941 set_ia32_am_offs_int(load, 0);
4944 if (get_irn_pinned(node) == op_pin_state_floats) {
4945 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
4946 && pn_ia32_vfld_res == pn_ia32_Load_res
4947 && pn_ia32_Load_res == pn_ia32_res);
4948 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4951 SET_IA32_ORIG_NODE(load, node);
4952 return new_r_Proj(block, load, mode_Iu, pn_ia32_Load_res);
4956 * Transform Builtin frame_address
4958 static ir_node *gen_prefetch(ir_node *node) {
4960 ir_node *ptr, *block, *mem, *base, *index;
4961 ir_node *param, *new_node;
4964 ia32_address_t addr;
4966 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4967 /* no prefetch at all, route memory */
4968 return be_transform_node(get_Builtin_mem(node));
4971 param = get_Builtin_param(node, 1);
4972 tv = get_Const_tarval(param);
4973 rw = get_tarval_long(tv);
4975 /* construct load address */
4976 memset(&addr, 0, sizeof(addr));
4977 ptr = get_Builtin_param(node, 0);
4978 ia32_create_address_mode(&addr, ptr, 0);
4985 base = be_transform_node(base);
4988 if (index == NULL) {
4991 index = be_transform_node(index);
4994 dbgi = get_irn_dbg_info(node);
4995 block = be_transform_node(get_nodes_block(node));
4996 mem = be_transform_node(get_Builtin_mem(node));
4998 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4999 /* we have 3DNow!, this was already checked above */
5000 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
5001 } else if (ia32_cg_config.use_sse_prefetch) {
5002 /* note: rw == 1 is IGNORED in that case */
5003 param = get_Builtin_param(node, 2);
5004 tv = get_Const_tarval(param);
5005 locality = get_tarval_long(tv);
5007 /* SSE style prefetch */
5010 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
5013 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
5016 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
5019 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
5023 assert(ia32_cg_config.use_3dnow_prefetch);
5024 /* 3DNow! style prefetch */
5025 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
5028 set_irn_pinned(new_node, get_irn_pinned(node));
5029 set_ia32_op_type(new_node, ia32_AddrModeS);
5030 set_ia32_ls_mode(new_node, mode_Bu);
5031 set_address(new_node, &addr);
5033 SET_IA32_ORIG_NODE(new_node, node);
5035 be_dep_on_frame(new_node);
5036 return new_r_Proj(block, new_node, mode_M, pn_ia32_Prefetch_M);
5040 * Transform bsf like node
5042 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
5044 ir_node *param = get_Builtin_param(node, 0);
5045 dbg_info *dbgi = get_irn_dbg_info(node);
5047 ir_node *block = get_nodes_block(node);
5048 ir_node *new_block = be_transform_node(block);
5050 ia32_address_mode_t am;
5051 ia32_address_t *addr = &am.addr;
5054 match_arguments(&am, block, NULL, param, NULL, match_am);
5056 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5057 set_am_attributes(cnt, &am);
5058 set_ia32_ls_mode(cnt, get_irn_mode(param));
5060 SET_IA32_ORIG_NODE(cnt, node);
5061 return fix_mem_proj(cnt, &am);
5065 * Transform builtin ffs.
5067 static ir_node *gen_ffs(ir_node *node)
5069 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
5070 ir_node *real = skip_Proj(bsf);
5071 dbg_info *dbgi = get_irn_dbg_info(real);
5072 ir_node *block = get_nodes_block(real);
5073 ir_node *flag, *set, *conv, *neg, *or;
5076 if (get_irn_mode(real) != mode_T) {
5077 set_irn_mode(real, mode_T);
5078 bsf = new_r_Proj(block, real, mode_Iu, pn_ia32_res);
5081 flag = new_r_Proj(block, real, mode_b, pn_ia32_flags);
5084 set = new_bd_ia32_Setcc(dbgi, block, flag, pn_Cmp_Eq);
5085 SET_IA32_ORIG_NODE(set, node);
5088 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
5089 SET_IA32_ORIG_NODE(conv, node);
5092 neg = new_bd_ia32_Neg(dbgi, block, conv);
5095 or = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5096 set_ia32_commutative(or);
5099 return new_bd_ia32_Add(dbgi, block, noreg_GP, noreg_GP, nomem, or, ia32_create_Immediate(NULL, 0, 1));
5103 * Transform builtin clz.
5105 static ir_node *gen_clz(ir_node *node)
5107 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
5108 ir_node *real = skip_Proj(bsr);
5109 dbg_info *dbgi = get_irn_dbg_info(real);
5110 ir_node *block = get_nodes_block(real);
5111 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
5113 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5117 * Transform builtin ctz.
5119 static ir_node *gen_ctz(ir_node *node)
5121 return gen_unop_AM(node, new_bd_ia32_Bsf);
5125 * Transform builtin parity.
5127 static ir_node *gen_parity(ir_node *node)
5129 ir_node *param = get_Builtin_param(node, 0);
5130 dbg_info *dbgi = get_irn_dbg_info(node);
5132 ir_node *block = get_nodes_block(node);
5134 ir_node *new_block = be_transform_node(block);
5135 ir_node *imm, *cmp, *new_node;
5137 ia32_address_mode_t am;
5138 ia32_address_t *addr = &am.addr;
5142 match_arguments(&am, block, NULL, param, NULL, match_am);
5143 imm = ia32_create_Immediate(NULL, 0, 0);
5144 cmp = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
5145 addr->mem, imm, am.new_op2, am.ins_permuted, 0);
5146 set_am_attributes(cmp, &am);
5147 set_ia32_ls_mode(cmp, mode_Iu);
5149 SET_IA32_ORIG_NODE(cmp, node);
5151 cmp = fix_mem_proj(cmp, &am);
5154 new_node = new_bd_ia32_Setcc(dbgi, new_block, cmp, ia32_pn_Cmp_parity);
5155 SET_IA32_ORIG_NODE(new_node, node);
5158 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5159 nomem, new_node, mode_Bu);
5160 SET_IA32_ORIG_NODE(new_node, node);
5165 * Transform builtin popcount
5167 static ir_node *gen_popcount(ir_node *node) {
5168 ir_node *param = get_Builtin_param(node, 0);
5169 dbg_info *dbgi = get_irn_dbg_info(node);
5171 ir_node *block = get_nodes_block(node);
5172 ir_node *new_block = be_transform_node(block);
5175 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5177 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5178 if (ia32_cg_config.use_popcnt) {
5179 ia32_address_mode_t am;
5180 ia32_address_t *addr = &am.addr;
5183 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5185 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5186 set_am_attributes(cnt, &am);
5187 set_ia32_ls_mode(cnt, get_irn_mode(param));
5189 SET_IA32_ORIG_NODE(cnt, node);
5190 return fix_mem_proj(cnt, &am);
5193 new_param = be_transform_node(param);
5195 /* do the standard popcount algo */
5197 /* m1 = x & 0x55555555 */
5198 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5199 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5202 simm = ia32_create_Immediate(NULL, 0, 1);
5203 s1 = new_bd_ia32_Shl(dbgi, new_block, new_param, simm);
5205 /* m2 = s1 & 0x55555555 */
5206 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5209 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5211 /* m4 = m3 & 0x33333333 */
5212 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5213 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5216 simm = ia32_create_Immediate(NULL, 0, 2);
5217 s2 = new_bd_ia32_Shl(dbgi, new_block, m3, simm);
5219 /* m5 = s2 & 0x33333333 */
5220 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5223 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5225 /* m7 = m6 & 0x0F0F0F0F */
5226 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5227 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5230 simm = ia32_create_Immediate(NULL, 0, 4);
5231 s3 = new_bd_ia32_Shl(dbgi, new_block, m6, simm);
5233 /* m8 = s3 & 0x0F0F0F0F */
5234 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5237 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5239 /* m10 = m9 & 0x00FF00FF */
5240 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5241 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5244 simm = ia32_create_Immediate(NULL, 0, 8);
5245 s4 = new_bd_ia32_Shl(dbgi, new_block, m9, simm);
5247 /* m11 = s4 & 0x00FF00FF */
5248 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5250 /* m12 = m10 + m11 */
5251 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5253 /* m13 = m12 & 0x0000FFFF */
5254 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5255 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5257 /* s5 = m12 >> 16 */
5258 simm = ia32_create_Immediate(NULL, 0, 16);
5259 s5 = new_bd_ia32_Shl(dbgi, new_block, m12, simm);
5261 /* res = m13 + s5 */
5262 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5266 * Transform builtin byte swap.
5268 static ir_node *gen_bswap(ir_node *node) {
5269 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5270 dbg_info *dbgi = get_irn_dbg_info(node);
5272 ir_node *block = get_nodes_block(node);
5273 ir_node *new_block = be_transform_node(block);
5274 ir_mode *mode = get_irn_mode(param);
5275 unsigned size = get_mode_size_bits(mode);
5276 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5280 if (ia32_cg_config.use_i486) {
5281 /* swap available */
5282 return new_bd_ia32_Bswap(dbgi, new_block, param);
5284 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5285 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5287 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5288 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5290 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5292 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5293 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5295 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5296 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5299 /* swap16 always available */
5300 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5303 panic("Invalid bswap size (%d)", size);
5308 * Transform builtin outport.
5310 static ir_node *gen_outport(ir_node *node) {
5311 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5312 ir_node *oldv = get_Builtin_param(node, 1);
5313 ir_mode *mode = get_irn_mode(oldv);
5314 ir_node *value = be_transform_node(oldv);
5315 ir_node *block = be_transform_node(get_nodes_block(node));
5316 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5317 dbg_info *dbgi = get_irn_dbg_info(node);
5319 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5320 set_ia32_ls_mode(res, mode);
5325 * Transform builtin inport.
5327 static ir_node *gen_inport(ir_node *node) {
5328 ir_type *tp = get_Builtin_type(node);
5329 ir_type *rstp = get_method_res_type(tp, 0);
5330 ir_mode *mode = get_type_mode(rstp);
5331 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5332 ir_node *block = be_transform_node(get_nodes_block(node));
5333 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5334 dbg_info *dbgi = get_irn_dbg_info(node);
5336 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5337 set_ia32_ls_mode(res, mode);
5339 /* check for missing Result Proj */
5344 * Transform a builtin inner trampoline
5346 static ir_node *gen_inner_trampoline(ir_node *node) {
5347 ir_node *ptr = get_Builtin_param(node, 0);
5348 ir_node *callee = get_Builtin_param(node, 1);
5349 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5350 ir_node *mem = get_Builtin_mem(node);
5351 ir_node *block = get_nodes_block(node);
5352 ir_node *new_block = be_transform_node(block);
5356 ir_node *trampoline;
5358 dbg_info *dbgi = get_irn_dbg_info(node);
5359 ia32_address_t addr;
5361 /* construct store address */
5362 memset(&addr, 0, sizeof(addr));
5363 ia32_create_address_mode(&addr, ptr, 0);
5365 if (addr.base == NULL) {
5366 addr.base = noreg_GP;
5368 addr.base = be_transform_node(addr.base);
5371 if (addr.index == NULL) {
5372 addr.index = noreg_GP;
5374 addr.index = be_transform_node(addr.index);
5376 addr.mem = be_transform_node(mem);
5378 /* mov ecx, <env> */
5379 val = ia32_create_Immediate(NULL, 0, 0xB9);
5380 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5381 addr.index, addr.mem, val);
5382 set_irn_pinned(store, get_irn_pinned(node));
5383 set_ia32_op_type(store, ia32_AddrModeD);
5384 set_ia32_ls_mode(store, mode_Bu);
5385 set_address(store, &addr);
5389 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5390 addr.index, addr.mem, env);
5391 set_irn_pinned(store, get_irn_pinned(node));
5392 set_ia32_op_type(store, ia32_AddrModeD);
5393 set_ia32_ls_mode(store, mode_Iu);
5394 set_address(store, &addr);
5398 /* jmp rel <callee> */
5399 val = ia32_create_Immediate(NULL, 0, 0xE9);
5400 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5401 addr.index, addr.mem, val);
5402 set_irn_pinned(store, get_irn_pinned(node));
5403 set_ia32_op_type(store, ia32_AddrModeD);
5404 set_ia32_ls_mode(store, mode_Bu);
5405 set_address(store, &addr);
5409 trampoline = be_transform_node(ptr);
5411 /* the callee is typically an immediate */
5412 if (is_SymConst(callee)) {
5413 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5415 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), ia32_create_Immediate(NULL, 0, -10));
5417 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5419 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5420 addr.index, addr.mem, rel);
5421 set_irn_pinned(store, get_irn_pinned(node));
5422 set_ia32_op_type(store, ia32_AddrModeD);
5423 set_ia32_ls_mode(store, mode_Iu);
5424 set_address(store, &addr);
5429 return new_r_Tuple(new_block, 2, in);
5433 * Transform Builtin node.
5435 static ir_node *gen_Builtin(ir_node *node) {
5436 ir_builtin_kind kind = get_Builtin_kind(node);
5440 return gen_trap(node);
5441 case ir_bk_debugbreak:
5442 return gen_debugbreak(node);
5443 case ir_bk_return_address:
5444 return gen_return_address(node);
5445 case ir_bk_frame_address:
5446 return gen_frame_address(node);
5447 case ir_bk_prefetch:
5448 return gen_prefetch(node);
5450 return gen_ffs(node);
5452 return gen_clz(node);
5454 return gen_ctz(node);
5456 return gen_parity(node);
5457 case ir_bk_popcount:
5458 return gen_popcount(node);
5460 return gen_bswap(node);
5462 return gen_outport(node);
5464 return gen_inport(node);
5465 case ir_bk_inner_trampoline:
5466 return gen_inner_trampoline(node);
5468 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5472 * Transform Proj(Builtin) node.
5474 static ir_node *gen_Proj_Builtin(ir_node *proj) {
5475 ir_node *node = get_Proj_pred(proj);
5476 ir_node *new_node = be_transform_node(node);
5477 ir_builtin_kind kind = get_Builtin_kind(node);
5480 case ir_bk_return_address:
5481 case ir_bk_frame_address:
5486 case ir_bk_popcount:
5488 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5491 case ir_bk_debugbreak:
5492 case ir_bk_prefetch:
5494 assert(get_Proj_proj(proj) == pn_Builtin_M);
5497 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5498 return new_r_Proj(get_nodes_block(new_node),
5499 new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5501 assert(get_Proj_proj(proj) == pn_Builtin_M);
5502 return new_r_Proj(get_nodes_block(new_node),
5503 new_node, mode_M, pn_ia32_Inport_M);
5505 case ir_bk_inner_trampoline:
5506 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5507 return get_Tuple_pred(new_node, 1);
5509 assert(get_Proj_proj(proj) == pn_Builtin_M);
5510 return get_Tuple_pred(new_node, 0);
5513 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5516 static ir_node *gen_be_IncSP(ir_node *node)
5518 ir_node *res = be_duplicate_node(node);
5519 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5525 * Transform the Projs from a be_Call.
5527 static ir_node *gen_Proj_be_Call(ir_node *node)
5529 ir_node *block = be_transform_node(get_nodes_block(node));
5530 ir_node *call = get_Proj_pred(node);
5531 ir_node *new_call = be_transform_node(call);
5532 dbg_info *dbgi = get_irn_dbg_info(node);
5533 long proj = get_Proj_proj(node);
5534 ir_mode *mode = get_irn_mode(node);
5537 if (proj == pn_be_Call_M_regular) {
5538 return new_rd_Proj(dbgi, block, new_call, mode_M, n_ia32_Call_mem);
5540 /* transform call modes */
5541 if (mode_is_data(mode)) {
5542 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5546 /* Map from be_Call to ia32_Call proj number */
5547 if (proj == pn_be_Call_sp) {
5548 proj = pn_ia32_Call_stack;
5549 } else if (proj == pn_be_Call_M_regular) {
5550 proj = pn_ia32_Call_M;
5552 arch_register_req_t const *const req = arch_get_register_req_out(node);
5553 int const n_outs = arch_irn_get_n_outs(new_call);
5556 assert(proj >= pn_be_Call_first_res);
5557 assert(req->type & arch_register_req_type_limited);
5559 for (i = 0; i < n_outs; ++i) {
5560 arch_register_req_t const *const new_req
5561 = arch_get_out_register_req(new_call, i);
5563 if (!(new_req->type & arch_register_req_type_limited) ||
5564 new_req->cls != req->cls ||
5565 *new_req->limited != *req->limited)
5574 res = new_rd_Proj(dbgi, block, new_call, mode, proj);
5576 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5578 case pn_ia32_Call_stack:
5579 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
5582 case pn_ia32_Call_fpcw:
5583 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
5591 * Transform the Projs from a Cmp.
5593 static ir_node *gen_Proj_Cmp(ir_node *node)
5595 /* this probably means not all mode_b nodes were lowered... */
5596 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5601 * Transform the Projs from a Bound.
5603 static ir_node *gen_Proj_Bound(ir_node *node)
5605 ir_node *new_node, *block;
5606 ir_node *pred = get_Proj_pred(node);
5608 switch (get_Proj_proj(node)) {
5610 return be_transform_node(get_Bound_mem(pred));
5611 case pn_Bound_X_regular:
5612 new_node = be_transform_node(pred);
5613 block = get_nodes_block(new_node);
5614 return new_r_Proj(block, new_node, mode_X, pn_ia32_Jcc_true);
5615 case pn_Bound_X_except:
5616 new_node = be_transform_node(pred);
5617 block = get_nodes_block(new_node);
5618 return new_r_Proj(block, new_node, mode_X, pn_ia32_Jcc_false);
5620 return be_transform_node(get_Bound_index(pred));
5622 panic("unsupported Proj from Bound");
5626 static ir_node *gen_Proj_ASM(ir_node *node)
5628 ir_mode *mode = get_irn_mode(node);
5629 ir_node *pred = get_Proj_pred(node);
5630 ir_node *new_pred = be_transform_node(pred);
5631 ir_node *block = get_nodes_block(new_pred);
5632 long pos = get_Proj_proj(node);
5634 if (mode == mode_M) {
5635 pos = arch_irn_get_n_outs(new_pred)-1;
5636 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5638 } else if (mode_is_float(mode)) {
5641 panic("unexpected proj mode at ASM");
5644 return new_r_Proj(block, new_pred, mode, pos);
5648 * Transform and potentially renumber Proj nodes.
5650 static ir_node *gen_Proj(ir_node *node)
5652 ir_node *pred = get_Proj_pred(node);
5655 switch (get_irn_opcode(pred)) {
5657 proj = get_Proj_proj(node);
5658 if (proj == pn_Store_M) {
5659 return be_transform_node(pred);
5661 panic("No idea how to transform proj->Store");
5664 return gen_Proj_Load(node);
5666 return gen_Proj_ASM(node);
5668 return gen_Proj_Builtin(node);
5672 return gen_Proj_DivMod(node);
5674 return gen_Proj_CopyB(node);
5676 return gen_Proj_Quot(node);
5678 return gen_Proj_be_SubSP(node);
5680 return gen_Proj_be_AddSP(node);
5682 return gen_Proj_be_Call(node);
5684 return gen_Proj_Cmp(node);
5686 return gen_Proj_Bound(node);
5688 proj = get_Proj_proj(node);
5690 case pn_Start_X_initial_exec: {
5691 ir_node *block = get_nodes_block(pred);
5692 ir_node *new_block = be_transform_node(block);
5693 dbg_info *dbgi = get_irn_dbg_info(node);
5694 /* we exchange the ProjX with a jump */
5695 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5700 case pn_Start_P_tls:
5701 return gen_Proj_tls(node);
5706 if (is_ia32_l_FloattoLL(pred)) {
5707 return gen_Proj_l_FloattoLL(node);
5709 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5713 ir_mode *mode = get_irn_mode(node);
5714 if (ia32_mode_needs_gp_reg(mode)) {
5715 ir_node *new_pred = be_transform_node(pred);
5716 ir_node *block = be_transform_node(get_nodes_block(node));
5717 ir_node *new_proj = new_r_Proj(block, new_pred,
5718 mode_Iu, get_Proj_proj(node));
5719 new_proj->node_nr = node->node_nr;
5724 return be_duplicate_node(node);
5728 * Enters all transform functions into the generic pointer
5730 static void register_transformers(void)
5732 /* first clear the generic function pointer for all ops */
5733 clear_irp_opcodes_generic_func();
5735 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5736 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
5776 /* transform ops from intrinsic lowering */
5788 GEN(ia32_l_LLtoFloat);
5789 GEN(ia32_l_FloattoLL);
5795 /* we should never see these nodes */
5810 /* handle builtins */
5813 /* handle generic backend nodes */
5827 * Pre-transform all unknown and noreg nodes.
5829 static void ia32_pretransform_node(void)
5831 ia32_code_gen_t *cg = env_cg;
5833 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
5834 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5835 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5836 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
5837 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
5838 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
5840 nomem = get_irg_no_mem(current_ir_graph);
5841 noreg_GP = ia32_new_NoReg_gp(cg);
5847 * Walker, checks if all ia32 nodes producing more than one result have their
5848 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
5850 static void add_missing_keep_walker(ir_node *node, void *data)
5853 unsigned found_projs = 0;
5854 const ir_edge_t *edge;
5855 ir_mode *mode = get_irn_mode(node);
5860 if (!is_ia32_irn(node))
5863 n_outs = arch_irn_get_n_outs(node);
5866 if (is_ia32_SwitchJmp(node))
5869 assert(n_outs < (int) sizeof(unsigned) * 8);
5870 foreach_out_edge(node, edge) {
5871 ir_node *proj = get_edge_src_irn(edge);
5874 /* The node could be kept */
5878 if (get_irn_mode(proj) == mode_M)
5881 pn = get_Proj_proj(proj);
5882 assert(pn < n_outs);
5883 found_projs |= 1 << pn;
5887 /* are keeps missing? */
5889 for (i = 0; i < n_outs; ++i) {
5892 const arch_register_req_t *req;
5893 const arch_register_class_t *cls;
5895 if (found_projs & (1 << i)) {
5899 req = arch_get_out_register_req(node, i);
5904 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
5908 block = get_nodes_block(node);
5909 in[0] = new_r_Proj(block, node, arch_register_class_mode(cls), i);
5910 if (last_keep != NULL) {
5911 be_Keep_add_node(last_keep, cls, in[0]);
5913 last_keep = be_new_Keep(block, 1, in);
5914 if (sched_is_scheduled(node)) {
5915 sched_add_after(node, last_keep);
5922 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5925 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5927 ir_graph *irg = be_get_birg_irg(cg->birg);
5928 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5932 * Post-process all calls if we are in SSE mode.
5933 * The ABI requires that the results are in st0, copy them
5934 * to a xmm register.
5936 static void postprocess_fp_call_results(void) {
5939 for (i = ARR_LEN(call_list) - 1; i >= 0; --i) {
5940 ir_node *call = call_list[i];
5941 ir_type *mtp = call_types[i];
5944 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5945 ir_type *res_tp = get_method_res_type(mtp, j);
5946 ir_node *res, *new_res;
5947 const ir_edge_t *edge, *next;
5950 if (! is_atomic_type(res_tp)) {
5951 /* no floating point return */
5954 mode = get_type_mode(res_tp);
5955 if (! mode_is_float(mode)) {
5956 /* no floating point return */
5960 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5963 /* now patch the users */
5964 foreach_out_edge_safe(res, edge, next) {
5965 ir_node *succ = get_edge_src_irn(edge);
5968 if (be_is_Keep(succ))
5971 if (is_ia32_xStore(succ)) {
5972 /* an xStore can be patched into an vfst */
5973 dbg_info *db = get_irn_dbg_info(succ);
5974 ir_node *block = get_nodes_block(succ);
5975 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5976 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5977 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5978 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5979 ir_mode *mode = get_ia32_ls_mode(succ);
5981 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5982 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5983 if (is_ia32_use_frame(succ))
5984 set_ia32_use_frame(st);
5985 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5986 set_irn_pinned(st, get_irn_pinned(succ));
5987 set_ia32_op_type(st, ia32_AddrModeD);
5991 if (new_res == NULL) {
5992 dbg_info *db = get_irn_dbg_info(call);
5993 ir_node *block = get_nodes_block(call);
5994 ir_node *frame = get_irg_frame(current_ir_graph);
5995 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5996 ir_node *call_mem = new_r_Proj(block, call, mode_M, pn_ia32_Call_M);
5997 ir_node *vfst, *xld, *new_mem;
5999 /* store st(0) on stack */
6000 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
6001 set_ia32_op_type(vfst, ia32_AddrModeD);
6002 set_ia32_use_frame(vfst);
6004 /* load into SSE register */
6005 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
6006 set_ia32_op_type(xld, ia32_AddrModeS);
6007 set_ia32_use_frame(xld);
6009 new_res = new_r_Proj(block, xld, mode, pn_ia32_xLoad_res);
6010 new_mem = new_r_Proj(block, xld, mode_M, pn_ia32_xLoad_M);
6012 if (old_mem != NULL) {
6013 edges_reroute(old_mem, new_mem, current_ir_graph);
6017 set_irn_n(succ, get_edge_src_pos(edge), new_res);
6024 /* do the transformation */
6025 void ia32_transform_graph(ia32_code_gen_t *cg)
6029 register_transformers();
6031 initial_fpcw = NULL;
6034 be_timer_push(T_HEIGHTS);
6035 heights = heights_new(cg->irg);
6036 be_timer_pop(T_HEIGHTS);
6037 ia32_calculate_non_address_mode_nodes(cg->birg);
6039 /* the transform phase is not safe for CSE (yet) because several nodes get
6040 * attributes set after their creation */
6041 cse_last = get_opt_cse();
6044 call_list = NEW_ARR_F(ir_node *, 0);
6045 call_types = NEW_ARR_F(ir_type *, 0);
6046 be_transform_graph(cg->birg, ia32_pretransform_node);
6048 if (ia32_cg_config.use_sse2)
6049 postprocess_fp_call_results();
6050 DEL_ARR_F(call_types);
6051 DEL_ARR_F(call_list);
6053 set_opt_cse(cse_last);
6055 ia32_free_non_address_mode_nodes();
6056 heights_free(heights);
6060 void ia32_init_transform(void)
6062 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");