2 * Copyright (C) 1995-2011 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"
50 #include "../benode.h"
51 #include "../besched.h"
53 #include "../beutil.h"
55 #include "../betranshlp.h"
58 #include "bearch_ia32_t.h"
59 #include "ia32_common_transform.h"
60 #include "ia32_nodes_attr.h"
61 #include "ia32_transform.h"
62 #include "ia32_new_nodes.h"
63 #include "ia32_dbg_stat.h"
64 #include "ia32_optimize.h"
65 #include "ia32_util.h"
66 #include "ia32_address_mode.h"
67 #include "ia32_architecture.h"
69 #include "gen_ia32_regalloc_if.h"
71 /* define this to construct SSE constants instead of load them */
72 #undef CONSTRUCT_SSE_CONST
75 #define SFP_SIGN "0x80000000"
76 #define DFP_SIGN "0x8000000000000000"
77 #define SFP_ABS "0x7FFFFFFF"
78 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
79 #define DFP_INTMAX "9223372036854775807"
80 #define ULL_BIAS "18446744073709551616"
82 #define ENT_SFP_SIGN "C_ia32_sfp_sign"
83 #define ENT_DFP_SIGN "C_ia32_dfp_sign"
84 #define ENT_SFP_ABS "C_ia32_sfp_abs"
85 #define ENT_DFP_ABS "C_ia32_dfp_abs"
86 #define ENT_ULL_BIAS "C_ia32_ull_bias"
88 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
89 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
91 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
93 static ir_node *initial_fpcw = NULL;
94 int ia32_no_pic_adjust;
96 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
97 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
100 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
101 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
104 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
105 ir_node *op1, ir_node *op2);
107 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
108 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
110 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
111 ir_node *base, ir_node *index, ir_node *mem);
113 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
114 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
117 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
119 static ir_node *create_immediate_or_transform(ir_node *node,
120 char immediate_constraint_type);
122 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
123 dbg_info *dbgi, ir_node *block,
124 ir_node *op, ir_node *orig_node);
126 /* its enough to have those once */
127 static ir_node *nomem, *noreg_GP;
129 /** a list to postprocess all calls */
130 static ir_node **call_list;
131 static ir_type **call_types;
133 /** Return non-zero is a node represents the 0 constant. */
134 static bool is_Const_0(ir_node *node)
136 return is_Const(node) && is_Const_null(node);
139 /** Return non-zero is a node represents the 1 constant. */
140 static bool is_Const_1(ir_node *node)
142 return is_Const(node) && is_Const_one(node);
145 /** Return non-zero is a node represents the -1 constant. */
146 static bool is_Const_Minus_1(ir_node *node)
148 return is_Const(node) && is_Const_all_one(node);
152 * returns true if constant can be created with a simple float command
154 static bool is_simple_x87_Const(ir_node *node)
156 ir_tarval *tv = get_Const_tarval(node);
157 if (tarval_is_null(tv) || tarval_is_one(tv))
160 /* TODO: match all the other float constants */
165 * returns true if constant can be created with a simple float command
167 static bool is_simple_sse_Const(ir_node *node)
169 ir_tarval *tv = get_Const_tarval(node);
170 ir_mode *mode = get_tarval_mode(tv);
175 if (tarval_is_null(tv)
176 #ifdef CONSTRUCT_SSE_CONST
181 #ifdef CONSTRUCT_SSE_CONST
182 if (mode == mode_D) {
183 unsigned val = get_tarval_sub_bits(tv, 0) |
184 (get_tarval_sub_bits(tv, 1) << 8) |
185 (get_tarval_sub_bits(tv, 2) << 16) |
186 (get_tarval_sub_bits(tv, 3) << 24);
188 /* lower 32bit are zero, really a 32bit constant */
191 #endif /* CONSTRUCT_SSE_CONST */
192 /* TODO: match all the other float constants */
197 * return NoREG or pic_base in case of PIC.
198 * This is necessary as base address for newly created symbols
200 static ir_node *get_symconst_base(void)
202 ir_graph *irg = current_ir_graph;
204 if (be_get_irg_options(irg)->pic) {
205 const arch_env_t *arch_env = be_get_irg_arch_env(irg);
206 return arch_env->impl->get_pic_base(irg);
213 * Transforms a Const.
215 static ir_node *gen_Const(ir_node *node)
217 ir_node *old_block = get_nodes_block(node);
218 ir_node *block = be_transform_node(old_block);
219 dbg_info *dbgi = get_irn_dbg_info(node);
220 ir_mode *mode = get_irn_mode(node);
222 assert(is_Const(node));
224 if (mode_is_float(mode)) {
230 if (ia32_cg_config.use_sse2) {
231 ir_tarval *tv = get_Const_tarval(node);
232 if (tarval_is_null(tv)) {
233 load = new_bd_ia32_xZero(dbgi, block);
234 set_ia32_ls_mode(load, mode);
236 #ifdef CONSTRUCT_SSE_CONST
237 } else if (tarval_is_one(tv)) {
238 int cnst = mode == mode_F ? 26 : 55;
239 ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
240 ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
241 ir_node *pslld, *psrld;
243 load = new_bd_ia32_xAllOnes(dbgi, block);
244 set_ia32_ls_mode(load, mode);
245 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
246 set_ia32_ls_mode(pslld, mode);
247 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
248 set_ia32_ls_mode(psrld, mode);
250 #endif /* CONSTRUCT_SSE_CONST */
251 } else if (mode == mode_F) {
252 /* we can place any 32bit constant by using a movd gp, sse */
253 unsigned val = get_tarval_sub_bits(tv, 0) |
254 (get_tarval_sub_bits(tv, 1) << 8) |
255 (get_tarval_sub_bits(tv, 2) << 16) |
256 (get_tarval_sub_bits(tv, 3) << 24);
257 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
258 load = new_bd_ia32_xMovd(dbgi, block, cnst);
259 set_ia32_ls_mode(load, mode);
262 #ifdef CONSTRUCT_SSE_CONST
263 if (mode == mode_D) {
264 unsigned val = get_tarval_sub_bits(tv, 0) |
265 (get_tarval_sub_bits(tv, 1) << 8) |
266 (get_tarval_sub_bits(tv, 2) << 16) |
267 (get_tarval_sub_bits(tv, 3) << 24);
269 ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
270 ir_node *cnst, *psllq;
272 /* fine, lower 32bit are zero, produce 32bit value */
273 val = get_tarval_sub_bits(tv, 4) |
274 (get_tarval_sub_bits(tv, 5) << 8) |
275 (get_tarval_sub_bits(tv, 6) << 16) |
276 (get_tarval_sub_bits(tv, 7) << 24);
277 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
278 load = new_bd_ia32_xMovd(dbgi, block, cnst);
279 set_ia32_ls_mode(load, mode);
280 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
281 set_ia32_ls_mode(psllq, mode);
286 #endif /* CONSTRUCT_SSE_CONST */
287 floatent = ia32_create_float_const_entity(node);
289 base = get_symconst_base();
290 load = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
292 set_ia32_op_type(load, ia32_AddrModeS);
293 set_ia32_am_sc(load, floatent);
294 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
295 res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
298 if (is_Const_null(node)) {
299 load = new_bd_ia32_vfldz(dbgi, block);
301 set_ia32_ls_mode(load, mode);
302 } else if (is_Const_one(node)) {
303 load = new_bd_ia32_vfld1(dbgi, block);
305 set_ia32_ls_mode(load, mode);
310 floatent = ia32_create_float_const_entity(node);
311 /* create_float_const_ent is smart and sometimes creates
313 ls_mode = get_type_mode(get_entity_type(floatent));
314 base = get_symconst_base();
315 load = new_bd_ia32_vfld(dbgi, block, base, noreg_GP, nomem,
317 set_ia32_op_type(load, ia32_AddrModeS);
318 set_ia32_am_sc(load, floatent);
319 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
320 res = new_r_Proj(load, mode_vfp, pn_ia32_vfld_res);
323 #ifdef CONSTRUCT_SSE_CONST
325 #endif /* CONSTRUCT_SSE_CONST */
326 SET_IA32_ORIG_NODE(load, node);
328 } else { /* non-float mode */
330 ir_tarval *tv = get_Const_tarval(node);
333 tv = tarval_convert_to(tv, mode_Iu);
335 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
337 panic("couldn't convert constant tarval (%+F)", node);
339 val = get_tarval_long(tv);
341 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
342 SET_IA32_ORIG_NODE(cnst, node);
349 * Transforms a SymConst.
351 static ir_node *gen_SymConst(ir_node *node)
353 ir_node *old_block = get_nodes_block(node);
354 ir_node *block = be_transform_node(old_block);
355 dbg_info *dbgi = get_irn_dbg_info(node);
356 ir_mode *mode = get_irn_mode(node);
359 if (mode_is_float(mode)) {
360 if (ia32_cg_config.use_sse2)
361 cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
363 cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
364 set_ia32_am_sc(cnst, get_SymConst_entity(node));
365 set_ia32_use_frame(cnst);
369 if (get_SymConst_kind(node) != symconst_addr_ent) {
370 panic("backend only support symconst_addr_ent (at %+F)", node);
372 entity = get_SymConst_entity(node);
373 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
376 SET_IA32_ORIG_NODE(cnst, node);
382 * Create a float type for the given mode and cache it.
384 * @param mode the mode for the float type (might be integer mode for SSE2 types)
385 * @param align alignment
387 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
393 if (mode == mode_Iu) {
394 static ir_type *int_Iu[16] = {NULL, };
396 if (int_Iu[align] == NULL) {
397 int_Iu[align] = tp = new_type_primitive(mode);
398 /* set the specified alignment */
399 set_type_alignment_bytes(tp, align);
401 return int_Iu[align];
402 } else if (mode == mode_Lu) {
403 static ir_type *int_Lu[16] = {NULL, };
405 if (int_Lu[align] == NULL) {
406 int_Lu[align] = tp = new_type_primitive(mode);
407 /* set the specified alignment */
408 set_type_alignment_bytes(tp, align);
410 return int_Lu[align];
411 } else if (mode == mode_F) {
412 static ir_type *float_F[16] = {NULL, };
414 if (float_F[align] == NULL) {
415 float_F[align] = tp = new_type_primitive(mode);
416 /* set the specified alignment */
417 set_type_alignment_bytes(tp, align);
419 return float_F[align];
420 } else if (mode == mode_D) {
421 static ir_type *float_D[16] = {NULL, };
423 if (float_D[align] == NULL) {
424 float_D[align] = tp = new_type_primitive(mode);
425 /* set the specified alignment */
426 set_type_alignment_bytes(tp, align);
428 return float_D[align];
430 static ir_type *float_E[16] = {NULL, };
432 if (float_E[align] == NULL) {
433 float_E[align] = tp = new_type_primitive(mode);
434 /* set the specified alignment */
435 set_type_alignment_bytes(tp, align);
437 return float_E[align];
442 * Create a float[2] array type for the given atomic type.
444 * @param tp the atomic type
446 static ir_type *ia32_create_float_array(ir_type *tp)
448 ir_mode *mode = get_type_mode(tp);
449 unsigned align = get_type_alignment_bytes(tp);
454 if (mode == mode_F) {
455 static ir_type *float_F[16] = {NULL, };
457 if (float_F[align] != NULL)
458 return float_F[align];
459 arr = float_F[align] = new_type_array(1, tp);
460 } else if (mode == mode_D) {
461 static ir_type *float_D[16] = {NULL, };
463 if (float_D[align] != NULL)
464 return float_D[align];
465 arr = float_D[align] = new_type_array(1, tp);
467 static ir_type *float_E[16] = {NULL, };
469 if (float_E[align] != NULL)
470 return float_E[align];
471 arr = float_E[align] = new_type_array(1, tp);
473 set_type_alignment_bytes(arr, align);
474 set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
475 set_type_state(arr, layout_fixed);
479 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
480 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
482 static const struct {
483 const char *ent_name;
484 const char *cnst_str;
487 } names [ia32_known_const_max] = {
488 { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
489 { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
490 { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
491 { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
492 { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
494 static ir_entity *ent_cache[ia32_known_const_max];
496 const char *ent_name, *cnst_str;
502 ent_name = names[kct].ent_name;
503 if (! ent_cache[kct]) {
504 cnst_str = names[kct].cnst_str;
506 switch (names[kct].mode) {
507 case 0: mode = mode_Iu; break;
508 case 1: mode = mode_Lu; break;
509 default: mode = mode_F; break;
511 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
512 tp = ia32_create_float_type(mode, names[kct].align);
514 if (kct == ia32_ULLBIAS)
515 tp = ia32_create_float_array(tp);
516 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
518 set_entity_ld_ident(ent, get_entity_ident(ent));
519 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
520 set_entity_visibility(ent, ir_visibility_private);
522 if (kct == ia32_ULLBIAS) {
523 ir_initializer_t *initializer = create_initializer_compound(2);
525 set_initializer_compound_value(initializer, 0,
526 create_initializer_tarval(get_mode_null(mode)));
527 set_initializer_compound_value(initializer, 1,
528 create_initializer_tarval(tv));
530 set_entity_initializer(ent, initializer);
532 set_entity_initializer(ent, create_initializer_tarval(tv));
535 /* cache the entry */
536 ent_cache[kct] = ent;
539 return ent_cache[kct];
543 * return true if the node is a Proj(Load) and could be used in source address
544 * mode for another node. Will return only true if the @p other node is not
545 * dependent on the memory of the Load (for binary operations use the other
546 * input here, for unary operations use NULL).
548 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
549 ir_node *other, ir_node *other2, match_flags_t flags)
554 /* float constants are always available */
555 if (is_Const(node)) {
556 ir_mode *mode = get_irn_mode(node);
557 if (mode_is_float(mode)) {
558 if (ia32_cg_config.use_sse2) {
559 if (is_simple_sse_Const(node))
562 if (is_simple_x87_Const(node))
565 if (get_irn_n_edges(node) > 1)
573 load = get_Proj_pred(node);
574 pn = get_Proj_proj(node);
575 if (!is_Load(load) || pn != pn_Load_res)
577 if (get_nodes_block(load) != block)
579 /* we only use address mode if we're the only user of the load */
580 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
582 /* in some edge cases with address mode we might reach the load normally
583 * and through some AM sequence, if it is already materialized then we
584 * can't create an AM node from it */
585 if (be_is_transformed(node))
588 /* don't do AM if other node inputs depend on the load (via mem-proj) */
589 if (other != NULL && ia32_prevents_AM(block, load, other))
592 if (other2 != NULL && ia32_prevents_AM(block, load, other2))
598 typedef struct ia32_address_mode_t ia32_address_mode_t;
599 struct ia32_address_mode_t {
604 ia32_op_type_t op_type;
608 unsigned commutative : 1;
609 unsigned ins_permuted : 1;
612 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
614 /* construct load address */
615 memset(addr, 0, sizeof(addr[0]));
616 ia32_create_address_mode(addr, ptr, ia32_create_am_normal);
618 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
619 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
620 addr->mem = be_transform_node(mem);
623 static void build_address(ia32_address_mode_t *am, ir_node *node,
624 ia32_create_am_flags_t flags)
626 ia32_address_t *addr = &am->addr;
632 /* floating point immediates */
633 if (is_Const(node)) {
634 ir_entity *entity = ia32_create_float_const_entity(node);
635 addr->base = get_symconst_base();
636 addr->index = noreg_GP;
638 addr->symconst_ent = entity;
640 am->ls_mode = get_type_mode(get_entity_type(entity));
641 am->pinned = op_pin_state_floats;
645 load = get_Proj_pred(node);
646 ptr = get_Load_ptr(load);
647 mem = get_Load_mem(load);
648 new_mem = be_transform_node(mem);
649 am->pinned = get_irn_pinned(load);
650 am->ls_mode = get_Load_mode(load);
651 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
654 /* construct load address */
655 ia32_create_address_mode(addr, ptr, flags);
657 addr->base = addr->base ? be_transform_node(addr->base) : noreg_GP;
658 addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
662 static void set_address(ir_node *node, const ia32_address_t *addr)
664 set_ia32_am_scale(node, addr->scale);
665 set_ia32_am_sc(node, addr->symconst_ent);
666 set_ia32_am_offs_int(node, addr->offset);
667 if (addr->symconst_sign)
668 set_ia32_am_sc_sign(node);
670 set_ia32_use_frame(node);
671 set_ia32_frame_ent(node, addr->frame_entity);
675 * Apply attributes of a given address mode to a node.
677 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
679 set_address(node, &am->addr);
681 set_ia32_op_type(node, am->op_type);
682 set_ia32_ls_mode(node, am->ls_mode);
683 if (am->pinned == op_pin_state_pinned) {
684 /* beware: some nodes are already pinned and did not allow to change the state */
685 if (get_irn_pinned(node) != op_pin_state_pinned)
686 set_irn_pinned(node, op_pin_state_pinned);
689 set_ia32_commutative(node);
693 * Check, if a given node is a Down-Conv, ie. a integer Conv
694 * from a mode with a mode with more bits to a mode with lesser bits.
695 * Moreover, we return only true if the node has not more than 1 user.
697 * @param node the node
698 * @return non-zero if node is a Down-Conv
700 static int is_downconv(const ir_node *node)
708 /* we only want to skip the conv when we're the only user
709 * (because this test is used in the context of address-mode selection
710 * and we don't want to use address mode for multiple users) */
711 if (get_irn_n_edges(node) > 1)
714 src_mode = get_irn_mode(get_Conv_op(node));
715 dest_mode = get_irn_mode(node);
717 ia32_mode_needs_gp_reg(src_mode) &&
718 ia32_mode_needs_gp_reg(dest_mode) &&
719 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
722 /** Skip all Down-Conv's on a given node and return the resulting node. */
723 ir_node *ia32_skip_downconv(ir_node *node)
725 while (is_downconv(node))
726 node = get_Conv_op(node);
731 static bool is_sameconv(ir_node *node)
739 /* we only want to skip the conv when we're the only user
740 * (because this test is used in the context of address-mode selection
741 * and we don't want to use address mode for multiple users) */
742 if (get_irn_n_edges(node) > 1)
745 src_mode = get_irn_mode(get_Conv_op(node));
746 dest_mode = get_irn_mode(node);
748 ia32_mode_needs_gp_reg(src_mode) &&
749 ia32_mode_needs_gp_reg(dest_mode) &&
750 get_mode_size_bits(dest_mode) == get_mode_size_bits(src_mode);
753 /** Skip all signedness convs */
754 static ir_node *ia32_skip_sameconv(ir_node *node)
756 while (is_sameconv(node))
757 node = get_Conv_op(node);
762 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
764 ir_mode *mode = get_irn_mode(node);
769 if (mode_is_signed(mode)) {
774 block = get_nodes_block(node);
775 dbgi = get_irn_dbg_info(node);
777 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
781 * matches operands of a node into ia32 addressing/operand modes. This covers
782 * usage of source address mode, immediates, operations with non 32-bit modes,
784 * The resulting data is filled into the @p am struct. block is the block
785 * of the node whose arguments are matched. op1, op2 are the first and second
786 * input that are matched (op1 may be NULL). other_op is another unrelated
787 * input that is not matched! but which is needed sometimes to check if AM
788 * for op1/op2 is legal.
789 * @p flags describes the supported modes of the operation in detail.
791 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
792 ir_node *op1, ir_node *op2, ir_node *other_op,
795 ia32_address_t *addr = &am->addr;
796 ir_mode *mode = get_irn_mode(op2);
797 int mode_bits = get_mode_size_bits(mode);
798 ir_node *new_op1, *new_op2;
800 unsigned commutative;
801 int use_am_and_immediates;
804 memset(am, 0, sizeof(am[0]));
806 commutative = (flags & match_commutative) != 0;
807 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
808 use_am = (flags & match_am) != 0;
809 use_immediate = (flags & match_immediate) != 0;
810 assert(!use_am_and_immediates || use_immediate);
813 assert(!commutative || op1 != NULL);
814 assert(use_am || !(flags & match_8bit_am));
815 assert(use_am || !(flags & match_16bit_am));
817 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
818 (mode_bits == 16 && !(flags & match_16bit_am))) {
822 /* we can simply skip downconvs for mode neutral nodes: the upper bits
823 * can be random for these operations */
824 if (flags & match_mode_neutral) {
825 op2 = ia32_skip_downconv(op2);
827 op1 = ia32_skip_downconv(op1);
830 op2 = ia32_skip_sameconv(op2);
832 op1 = ia32_skip_sameconv(op1);
836 /* match immediates. firm nodes are normalized: constants are always on the
839 if (!(flags & match_try_am) && use_immediate) {
840 new_op2 = ia32_try_create_Immediate(op2, 0);
843 if (new_op2 == NULL &&
844 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
845 build_address(am, op2, ia32_create_am_normal);
846 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
847 if (mode_is_float(mode)) {
848 new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
852 am->op_type = ia32_AddrModeS;
853 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
855 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
857 build_address(am, op1, ia32_create_am_normal);
859 if (mode_is_float(mode)) {
860 noreg = ia32_new_NoReg_vfp(current_ir_graph);
865 if (new_op2 != NULL) {
868 new_op1 = be_transform_node(op2);
870 am->ins_permuted = true;
872 am->op_type = ia32_AddrModeS;
875 am->op_type = ia32_Normal;
877 if (flags & match_try_am) {
883 mode = get_irn_mode(op2);
884 if (flags & match_upconv_32 && get_mode_size_bits(mode) != 32) {
885 new_op1 = (op1 == NULL ? NULL : create_upconv(op1, NULL));
887 new_op2 = create_upconv(op2, NULL);
888 am->ls_mode = mode_Iu;
890 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
892 new_op2 = be_transform_node(op2);
893 am->ls_mode = (flags & match_mode_neutral) ? mode_Iu : mode;
896 if (addr->base == NULL)
897 addr->base = noreg_GP;
898 if (addr->index == NULL)
899 addr->index = noreg_GP;
900 if (addr->mem == NULL)
903 am->new_op1 = new_op1;
904 am->new_op2 = new_op2;
905 am->commutative = commutative;
909 * "Fixes" a node that uses address mode by turning it into mode_T
910 * and returning a pn_ia32_res Proj.
912 * @param node the node
913 * @param am its address mode
915 * @return a Proj(pn_ia32_res) if a memory address mode is used,
918 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
923 if (am->mem_proj == NULL)
926 /* we have to create a mode_T so the old MemProj can attach to us */
927 mode = get_irn_mode(node);
928 load = get_Proj_pred(am->mem_proj);
930 be_set_transformed_node(load, node);
932 if (mode != mode_T) {
933 set_irn_mode(node, mode_T);
934 return new_rd_Proj(NULL, node, mode, pn_ia32_res);
941 * Construct a standard binary operation, set AM and immediate if required.
943 * @param node The original node for which the binop is created
944 * @param op1 The first operand
945 * @param op2 The second operand
946 * @param func The node constructor function
947 * @return The constructed ia32 node.
949 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
950 construct_binop_func *func, match_flags_t flags)
953 ir_node *block, *new_block, *new_node;
954 ia32_address_mode_t am;
955 ia32_address_t *addr = &am.addr;
957 block = get_nodes_block(node);
958 match_arguments(&am, block, op1, op2, NULL, flags);
960 dbgi = get_irn_dbg_info(node);
961 new_block = be_transform_node(block);
962 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
963 am.new_op1, am.new_op2);
964 set_am_attributes(new_node, &am);
965 /* we can't use source address mode anymore when using immediates */
966 if (!(flags & match_am_and_immediates) &&
967 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
968 set_ia32_am_support(new_node, ia32_am_none);
969 SET_IA32_ORIG_NODE(new_node, node);
971 new_node = fix_mem_proj(new_node, &am);
977 * Generic names for the inputs of an ia32 binary op.
980 n_ia32_l_binop_left, /**< ia32 left input */
981 n_ia32_l_binop_right, /**< ia32 right input */
982 n_ia32_l_binop_eflags /**< ia32 eflags input */
984 COMPILETIME_ASSERT((int)n_ia32_l_binop_left == (int)n_ia32_l_Adc_left, n_Adc_left)
985 COMPILETIME_ASSERT((int)n_ia32_l_binop_right == (int)n_ia32_l_Adc_right, n_Adc_right)
986 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Adc_eflags, n_Adc_eflags)
987 COMPILETIME_ASSERT((int)n_ia32_l_binop_left == (int)n_ia32_l_Sbb_minuend, n_Sbb_minuend)
988 COMPILETIME_ASSERT((int)n_ia32_l_binop_right == (int)n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
989 COMPILETIME_ASSERT((int)n_ia32_l_binop_eflags == (int)n_ia32_l_Sbb_eflags, n_Sbb_eflags)
992 * Construct a binary operation which also consumes the eflags.
994 * @param node The node to transform
995 * @param func The node constructor function
996 * @param flags The match flags
997 * @return The constructor ia32 node
999 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
1000 match_flags_t flags)
1002 ir_node *src_block = get_nodes_block(node);
1003 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
1004 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
1005 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
1007 ir_node *block, *new_node, *new_eflags;
1008 ia32_address_mode_t am;
1009 ia32_address_t *addr = &am.addr;
1011 match_arguments(&am, src_block, op1, op2, eflags, flags);
1013 dbgi = get_irn_dbg_info(node);
1014 block = be_transform_node(src_block);
1015 new_eflags = be_transform_node(eflags);
1016 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
1017 am.new_op1, am.new_op2, new_eflags);
1018 set_am_attributes(new_node, &am);
1019 /* we can't use source address mode anymore when using immediates */
1020 if (!(flags & match_am_and_immediates) &&
1021 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
1022 set_ia32_am_support(new_node, ia32_am_none);
1023 SET_IA32_ORIG_NODE(new_node, node);
1025 new_node = fix_mem_proj(new_node, &am);
1030 static ir_node *get_fpcw(void)
1033 if (initial_fpcw != NULL)
1034 return initial_fpcw;
1036 fpcw = be_abi_get_ignore_irn(be_get_irg_abi(current_ir_graph),
1037 &ia32_registers[REG_FPCW]);
1038 initial_fpcw = be_transform_node(fpcw);
1040 return initial_fpcw;
1044 * Construct a standard binary operation, set AM and immediate if required.
1046 * @param op1 The first operand
1047 * @param op2 The second operand
1048 * @param func The node constructor function
1049 * @return The constructed ia32 node.
1051 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1052 construct_binop_float_func *func)
1054 ir_mode *mode = get_irn_mode(node);
1056 ir_node *block, *new_block, *new_node;
1057 ia32_address_mode_t am;
1058 ia32_address_t *addr = &am.addr;
1059 ia32_x87_attr_t *attr;
1060 /* All operations are considered commutative, because there are reverse
1062 match_flags_t flags = match_commutative;
1064 /* happens for div nodes... */
1065 if (mode == mode_T) {
1067 mode = get_Div_resmode(node);
1069 panic("can't determine mode");
1072 /* cannot use address mode with long double on x87 */
1073 if (get_mode_size_bits(mode) <= 64)
1076 block = get_nodes_block(node);
1077 match_arguments(&am, block, op1, op2, NULL, flags);
1079 dbgi = get_irn_dbg_info(node);
1080 new_block = be_transform_node(block);
1081 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
1082 am.new_op1, am.new_op2, get_fpcw());
1083 set_am_attributes(new_node, &am);
1085 attr = get_ia32_x87_attr(new_node);
1086 attr->attr.data.ins_permuted = am.ins_permuted;
1088 SET_IA32_ORIG_NODE(new_node, node);
1090 new_node = fix_mem_proj(new_node, &am);
1096 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1098 * @param op1 The first operand
1099 * @param op2 The second operand
1100 * @param func The node constructor function
1101 * @return The constructed ia32 node.
1103 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1104 construct_shift_func *func,
1105 match_flags_t flags)
1108 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1110 assert(! mode_is_float(get_irn_mode(node)));
1111 assert(flags & match_immediate);
1112 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1114 if (flags & match_mode_neutral) {
1115 op1 = ia32_skip_downconv(op1);
1116 new_op1 = be_transform_node(op1);
1117 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1118 new_op1 = create_upconv(op1, node);
1120 new_op1 = be_transform_node(op1);
1123 /* the shift amount can be any mode that is bigger than 5 bits, since all
1124 * other bits are ignored anyway */
1125 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1126 ir_node *const op = get_Conv_op(op2);
1127 if (mode_is_float(get_irn_mode(op)))
1130 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1132 new_op2 = create_immediate_or_transform(op2, 0);
1134 dbgi = get_irn_dbg_info(node);
1135 block = get_nodes_block(node);
1136 new_block = be_transform_node(block);
1137 new_node = func(dbgi, new_block, new_op1, new_op2);
1138 SET_IA32_ORIG_NODE(new_node, node);
1140 /* lowered shift instruction may have a dependency operand, handle it here */
1141 if (get_irn_arity(node) == 3) {
1142 /* we have a dependency */
1143 ir_node* dep = get_irn_n(node, 2);
1144 if (get_irn_n_edges(dep) > 1) {
1145 /* ... which has at least one user other than 'node' */
1146 ir_node *new_dep = be_transform_node(dep);
1147 add_irn_dep(new_node, new_dep);
1156 * Construct a standard unary operation, set AM and immediate if required.
1158 * @param op The operand
1159 * @param func The node constructor function
1160 * @return The constructed ia32 node.
1162 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1163 match_flags_t flags)
1166 ir_node *block, *new_block, *new_op, *new_node;
1168 assert(flags == 0 || flags == match_mode_neutral);
1169 if (flags & match_mode_neutral) {
1170 op = ia32_skip_downconv(op);
1173 new_op = be_transform_node(op);
1174 dbgi = get_irn_dbg_info(node);
1175 block = get_nodes_block(node);
1176 new_block = be_transform_node(block);
1177 new_node = func(dbgi, new_block, new_op);
1179 SET_IA32_ORIG_NODE(new_node, node);
1184 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1185 ia32_address_t *addr)
1187 ir_node *base, *index, *res;
1193 base = be_transform_node(base);
1196 index = addr->index;
1197 if (index == NULL) {
1200 index = be_transform_node(index);
1203 res = new_bd_ia32_Lea(dbgi, block, base, index);
1204 set_address(res, addr);
1210 * Returns non-zero if a given address mode has a symbolic or
1211 * numerical offset != 0.
1213 static int am_has_immediates(const ia32_address_t *addr)
1215 return addr->offset != 0 || addr->symconst_ent != NULL
1216 || addr->frame_entity || addr->use_frame;
1220 * Creates an ia32 Add.
1222 * @return the created ia32 Add node
1224 static ir_node *gen_Add(ir_node *node)
1226 ir_mode *mode = get_irn_mode(node);
1227 ir_node *op1 = get_Add_left(node);
1228 ir_node *op2 = get_Add_right(node);
1230 ir_node *block, *new_block, *new_node, *add_immediate_op;
1231 ia32_address_t addr;
1232 ia32_address_mode_t am;
1234 if (mode_is_float(mode)) {
1235 if (ia32_cg_config.use_sse2)
1236 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1237 match_commutative | match_am);
1239 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1242 ia32_mark_non_am(node);
1244 op2 = ia32_skip_downconv(op2);
1245 op1 = ia32_skip_downconv(op1);
1249 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1250 * 1. Add with immediate -> Lea
1251 * 2. Add with possible source address mode -> Add
1252 * 3. Otherwise -> Lea
1254 memset(&addr, 0, sizeof(addr));
1255 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1256 add_immediate_op = NULL;
1258 dbgi = get_irn_dbg_info(node);
1259 block = get_nodes_block(node);
1260 new_block = be_transform_node(block);
1263 if (addr.base == NULL && addr.index == NULL) {
1264 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1265 addr.symconst_sign, 0, addr.offset);
1266 SET_IA32_ORIG_NODE(new_node, node);
1269 /* add with immediate? */
1270 if (addr.index == NULL) {
1271 add_immediate_op = addr.base;
1272 } else if (addr.base == NULL && addr.scale == 0) {
1273 add_immediate_op = addr.index;
1276 if (add_immediate_op != NULL) {
1277 if (!am_has_immediates(&addr)) {
1278 #ifdef DEBUG_libfirm
1279 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1282 return be_transform_node(add_immediate_op);
1285 new_node = create_lea_from_address(dbgi, new_block, &addr);
1286 SET_IA32_ORIG_NODE(new_node, node);
1290 /* test if we can use source address mode */
1291 match_arguments(&am, block, op1, op2, NULL, match_commutative
1292 | match_mode_neutral | match_am | match_immediate | match_try_am);
1294 /* construct an Add with source address mode */
1295 if (am.op_type == ia32_AddrModeS) {
1296 ia32_address_t *am_addr = &am.addr;
1297 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1298 am_addr->index, am_addr->mem, am.new_op1,
1300 set_am_attributes(new_node, &am);
1301 SET_IA32_ORIG_NODE(new_node, node);
1303 new_node = fix_mem_proj(new_node, &am);
1308 /* otherwise construct a lea */
1309 new_node = create_lea_from_address(dbgi, new_block, &addr);
1310 SET_IA32_ORIG_NODE(new_node, node);
1315 * Creates an ia32 Mul.
1317 * @return the created ia32 Mul node
1319 static ir_node *gen_Mul(ir_node *node)
1321 ir_node *op1 = get_Mul_left(node);
1322 ir_node *op2 = get_Mul_right(node);
1323 ir_mode *mode = get_irn_mode(node);
1325 if (mode_is_float(mode)) {
1326 if (ia32_cg_config.use_sse2)
1327 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1328 match_commutative | match_am);
1330 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1332 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1333 match_commutative | match_am | match_mode_neutral |
1334 match_immediate | match_am_and_immediates);
1338 * Creates an ia32 Mulh.
1339 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1340 * this result while Mul returns the lower 32 bit.
1342 * @return the created ia32 Mulh node
1344 static ir_node *gen_Mulh(ir_node *node)
1346 dbg_info *dbgi = get_irn_dbg_info(node);
1347 ir_node *op1 = get_Mulh_left(node);
1348 ir_node *op2 = get_Mulh_right(node);
1349 ir_mode *mode = get_irn_mode(node);
1351 ir_node *proj_res_high;
1353 if (get_mode_size_bits(mode) != 32) {
1354 panic("Mulh without 32bit size not supported in ia32 backend (%+F)", node);
1357 if (mode_is_signed(mode)) {
1358 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1359 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_IMul1OP_res_high);
1361 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1362 proj_res_high = new_rd_Proj(dbgi, new_node, mode_Iu, pn_ia32_Mul_res_high);
1364 return proj_res_high;
1368 * Creates an ia32 And.
1370 * @return The created ia32 And node
1372 static ir_node *gen_And(ir_node *node)
1374 ir_node *op1 = get_And_left(node);
1375 ir_node *op2 = get_And_right(node);
1376 assert(! mode_is_float(get_irn_mode(node)));
1378 /* is it a zero extension? */
1379 if (is_Const(op2)) {
1380 ir_tarval *tv = get_Const_tarval(op2);
1381 long v = get_tarval_long(tv);
1383 if (v == 0xFF || v == 0xFFFF) {
1384 dbg_info *dbgi = get_irn_dbg_info(node);
1385 ir_node *block = get_nodes_block(node);
1392 assert(v == 0xFFFF);
1395 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1400 return gen_binop(node, op1, op2, new_bd_ia32_And,
1401 match_commutative | match_mode_neutral | match_am | match_immediate);
1407 * Creates an ia32 Or.
1409 * @return The created ia32 Or node
1411 static ir_node *gen_Or(ir_node *node)
1413 ir_node *op1 = get_Or_left(node);
1414 ir_node *op2 = get_Or_right(node);
1416 assert (! mode_is_float(get_irn_mode(node)));
1417 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1418 | match_mode_neutral | match_am | match_immediate);
1424 * Creates an ia32 Eor.
1426 * @return The created ia32 Eor node
1428 static ir_node *gen_Eor(ir_node *node)
1430 ir_node *op1 = get_Eor_left(node);
1431 ir_node *op2 = get_Eor_right(node);
1433 assert(! mode_is_float(get_irn_mode(node)));
1434 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1435 | match_mode_neutral | match_am | match_immediate);
1440 * Creates an ia32 Sub.
1442 * @return The created ia32 Sub node
1444 static ir_node *gen_Sub(ir_node *node)
1446 ir_node *op1 = get_Sub_left(node);
1447 ir_node *op2 = get_Sub_right(node);
1448 ir_mode *mode = get_irn_mode(node);
1450 if (mode_is_float(mode)) {
1451 if (ia32_cg_config.use_sse2)
1452 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1454 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1457 if (is_Const(op2)) {
1458 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1462 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1463 | match_am | match_immediate);
1466 static ir_node *transform_AM_mem(ir_node *const block,
1467 ir_node *const src_val,
1468 ir_node *const src_mem,
1469 ir_node *const am_mem)
1471 if (is_NoMem(am_mem)) {
1472 return be_transform_node(src_mem);
1473 } else if (is_Proj(src_val) &&
1475 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1476 /* avoid memory loop */
1478 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1479 ir_node *const ptr_pred = get_Proj_pred(src_val);
1480 int const arity = get_Sync_n_preds(src_mem);
1485 NEW_ARR_A(ir_node*, ins, arity + 1);
1487 /* NOTE: This sometimes produces dead-code because the old sync in
1488 * src_mem might not be used anymore, we should detect this case
1489 * and kill the sync... */
1490 for (i = arity - 1; i >= 0; --i) {
1491 ir_node *const pred = get_Sync_pred(src_mem, i);
1493 /* avoid memory loop */
1494 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1497 ins[n++] = be_transform_node(pred);
1500 if (n==1 && ins[0] == am_mem) {
1502 /* creating a new Sync and relying on CSE may fail,
1503 * if am_mem is a ProjM, which does not yet verify. */
1507 return new_r_Sync(block, n, ins);
1511 ins[0] = be_transform_node(src_mem);
1513 return new_r_Sync(block, 2, ins);
1518 * Create a 32bit to 64bit signed extension.
1520 * @param dbgi debug info
1521 * @param block the block where node nodes should be placed
1522 * @param val the value to extend
1523 * @param orig the original node
1525 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1526 ir_node *val, const ir_node *orig)
1531 if (ia32_cg_config.use_short_sex_eax) {
1532 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1533 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1535 ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
1536 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1538 SET_IA32_ORIG_NODE(res, orig);
1543 * Generates an ia32 Div with additional infrastructure for the
1544 * register allocator if needed.
1546 static ir_node *create_Div(ir_node *node)
1548 dbg_info *dbgi = get_irn_dbg_info(node);
1549 ir_node *block = get_nodes_block(node);
1550 ir_node *new_block = be_transform_node(block);
1557 ir_node *sign_extension;
1558 ia32_address_mode_t am;
1559 ia32_address_t *addr = &am.addr;
1561 /* the upper bits have random contents for smaller modes */
1562 switch (get_irn_opcode(node)) {
1564 op1 = get_Div_left(node);
1565 op2 = get_Div_right(node);
1566 mem = get_Div_mem(node);
1567 mode = get_Div_resmode(node);
1570 op1 = get_Mod_left(node);
1571 op2 = get_Mod_right(node);
1572 mem = get_Mod_mem(node);
1573 mode = get_Mod_resmode(node);
1576 panic("invalid divmod node %+F", node);
1579 match_arguments(&am, block, op1, op2, NULL, match_am | match_upconv_32);
1581 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1582 is the memory of the consumed address. We can have only the second op as address
1583 in Div nodes, so check only op2. */
1584 new_mem = transform_AM_mem(block, op2, mem, addr->mem);
1586 if (mode_is_signed(mode)) {
1587 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1588 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1589 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1591 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0, 0);
1593 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1594 addr->index, new_mem, am.new_op2,
1595 am.new_op1, sign_extension);
1598 set_irn_pinned(new_node, get_irn_pinned(node));
1600 set_am_attributes(new_node, &am);
1601 SET_IA32_ORIG_NODE(new_node, node);
1603 new_node = fix_mem_proj(new_node, &am);
1609 * Generates an ia32 Mod.
1611 static ir_node *gen_Mod(ir_node *node)
1613 return create_Div(node);
1617 * Generates an ia32 Div.
1619 static ir_node *gen_Div(ir_node *node)
1621 ir_mode *mode = get_Div_resmode(node);
1622 if (mode_is_float(mode)) {
1623 ir_node *op1 = get_Div_left(node);
1624 ir_node *op2 = get_Div_right(node);
1626 if (ia32_cg_config.use_sse2) {
1627 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1629 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1633 return create_Div(node);
1637 * Creates an ia32 Shl.
1639 * @return The created ia32 Shl node
1641 static ir_node *gen_Shl(ir_node *node)
1643 ir_node *left = get_Shl_left(node);
1644 ir_node *right = get_Shl_right(node);
1646 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1647 match_mode_neutral | match_immediate);
1651 * Creates an ia32 Shr.
1653 * @return The created ia32 Shr node
1655 static ir_node *gen_Shr(ir_node *node)
1657 ir_node *left = get_Shr_left(node);
1658 ir_node *right = get_Shr_right(node);
1660 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1666 * Creates an ia32 Sar.
1668 * @return The created ia32 Shrs node
1670 static ir_node *gen_Shrs(ir_node *node)
1672 ir_node *left = get_Shrs_left(node);
1673 ir_node *right = get_Shrs_right(node);
1675 if (is_Const(right)) {
1676 ir_tarval *tv = get_Const_tarval(right);
1677 long val = get_tarval_long(tv);
1679 /* this is a sign extension */
1680 dbg_info *dbgi = get_irn_dbg_info(node);
1681 ir_node *block = be_transform_node(get_nodes_block(node));
1682 ir_node *new_op = be_transform_node(left);
1684 return create_sex_32_64(dbgi, block, new_op, node);
1688 /* 8 or 16 bit sign extension? */
1689 if (is_Const(right) && is_Shl(left)) {
1690 ir_node *shl_left = get_Shl_left(left);
1691 ir_node *shl_right = get_Shl_right(left);
1692 if (is_Const(shl_right)) {
1693 ir_tarval *tv1 = get_Const_tarval(right);
1694 ir_tarval *tv2 = get_Const_tarval(shl_right);
1695 if (tv1 == tv2 && tarval_is_long(tv1)) {
1696 long val = get_tarval_long(tv1);
1697 if (val == 16 || val == 24) {
1698 dbg_info *dbgi = get_irn_dbg_info(node);
1699 ir_node *block = get_nodes_block(node);
1709 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1718 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1724 * Creates an ia32 Rol.
1726 * @param op1 The first operator
1727 * @param op2 The second operator
1728 * @return The created ia32 RotL node
1730 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1732 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1738 * Creates an ia32 Ror.
1739 * NOTE: There is no RotR with immediate because this would always be a RotL
1740 * "imm-mode_size_bits" which can be pre-calculated.
1742 * @param op1 The first operator
1743 * @param op2 The second operator
1744 * @return The created ia32 RotR node
1746 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1748 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1754 * Creates an ia32 RotR or RotL (depending on the found pattern).
1756 * @return The created ia32 RotL or RotR node
1758 static ir_node *gen_Rotl(ir_node *node)
1760 ir_node *op1 = get_Rotl_left(node);
1761 ir_node *op2 = get_Rotl_right(node);
1763 if (is_Minus(op2)) {
1764 return gen_Ror(node, op1, get_Minus_op(op2));
1767 return gen_Rol(node, op1, op2);
1773 * Transforms a Minus node.
1775 * @return The created ia32 Minus node
1777 static ir_node *gen_Minus(ir_node *node)
1779 ir_node *op = get_Minus_op(node);
1780 ir_node *block = be_transform_node(get_nodes_block(node));
1781 dbg_info *dbgi = get_irn_dbg_info(node);
1782 ir_mode *mode = get_irn_mode(node);
1787 if (mode_is_float(mode)) {
1788 ir_node *new_op = be_transform_node(op);
1789 if (ia32_cg_config.use_sse2) {
1790 /* TODO: non-optimal... if we have many xXors, then we should
1791 * rather create a load for the const and use that instead of
1792 * several AM nodes... */
1793 ir_node *noreg_xmm = ia32_new_NoReg_xmm(current_ir_graph);
1795 new_node = new_bd_ia32_xXor(dbgi, block, get_symconst_base(),
1796 noreg_GP, nomem, new_op, noreg_xmm);
1798 size = get_mode_size_bits(mode);
1799 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1801 set_ia32_am_sc(new_node, ent);
1802 set_ia32_op_type(new_node, ia32_AddrModeS);
1803 set_ia32_ls_mode(new_node, mode);
1805 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1808 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1811 SET_IA32_ORIG_NODE(new_node, node);
1817 * Transforms a Not node.
1819 * @return The created ia32 Not node
1821 static ir_node *gen_Not(ir_node *node)
1823 ir_node *op = get_Not_op(node);
1825 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1826 assert (! mode_is_float(get_irn_mode(node)));
1828 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1831 static ir_node *create_abs(dbg_info *dbgi, ir_node *block, ir_node *op,
1832 bool negate, ir_node *node)
1834 ir_node *new_block = be_transform_node(block);
1835 ir_mode *mode = get_irn_mode(op);
1841 if (mode_is_float(mode)) {
1842 new_op = be_transform_node(op);
1844 if (ia32_cg_config.use_sse2) {
1845 ir_node *noreg_fp = ia32_new_NoReg_xmm(current_ir_graph);
1846 new_node = new_bd_ia32_xAnd(dbgi, new_block, get_symconst_base(),
1847 noreg_GP, nomem, new_op, noreg_fp);
1849 size = get_mode_size_bits(mode);
1850 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1852 set_ia32_am_sc(new_node, ent);
1854 SET_IA32_ORIG_NODE(new_node, node);
1856 set_ia32_op_type(new_node, ia32_AddrModeS);
1857 set_ia32_ls_mode(new_node, mode);
1859 /* TODO, implement -Abs case */
1862 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1863 SET_IA32_ORIG_NODE(new_node, node);
1865 new_node = new_bd_ia32_vfchs(dbgi, new_block, new_node);
1866 SET_IA32_ORIG_NODE(new_node, node);
1871 ir_node *sign_extension;
1873 if (get_mode_size_bits(mode) == 32) {
1874 new_op = be_transform_node(op);
1876 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1879 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1881 xorn = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP,
1882 nomem, new_op, sign_extension);
1883 SET_IA32_ORIG_NODE(xorn, node);
1886 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1887 nomem, sign_extension, xorn);
1889 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP,
1890 nomem, xorn, sign_extension);
1892 SET_IA32_ORIG_NODE(new_node, node);
1899 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1901 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1903 dbg_info *dbgi = get_irn_dbg_info(cmp);
1904 ir_node *block = get_nodes_block(cmp);
1905 ir_node *new_block = be_transform_node(block);
1906 ir_node *op1 = be_transform_node(x);
1907 ir_node *op2 = be_transform_node(n);
1909 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1912 static ia32_condition_code_t relation_to_condition_code(ir_relation relation,
1915 if (mode_is_float(mode)) {
1917 case ir_relation_equal: return ia32_cc_float_equal;
1918 case ir_relation_less: return ia32_cc_float_below;
1919 case ir_relation_less_equal: return ia32_cc_float_below_equal;
1920 case ir_relation_greater: return ia32_cc_float_above;
1921 case ir_relation_greater_equal: return ia32_cc_float_above_equal;
1922 case ir_relation_less_greater: return ia32_cc_not_equal;
1923 case ir_relation_less_equal_greater: return ia32_cc_not_parity;
1924 case ir_relation_unordered: return ia32_cc_parity;
1925 case ir_relation_unordered_equal: return ia32_cc_equal;
1926 case ir_relation_unordered_less: return ia32_cc_float_unordered_below;
1927 case ir_relation_unordered_less_equal:
1928 return ia32_cc_float_unordered_below_equal;
1929 case ir_relation_unordered_greater:
1930 return ia32_cc_float_unordered_above;
1931 case ir_relation_unordered_greater_equal:
1932 return ia32_cc_float_unordered_above_equal;
1933 case ir_relation_unordered_less_greater:
1934 return ia32_cc_float_not_equal;
1935 case ir_relation_false:
1936 case ir_relation_true:
1937 /* should we introduce a jump always/jump never? */
1940 panic("Unexpected float pnc");
1941 } else if (mode_is_signed(mode)) {
1943 case ir_relation_unordered_equal:
1944 case ir_relation_equal: return ia32_cc_equal;
1945 case ir_relation_unordered_less:
1946 case ir_relation_less: return ia32_cc_less;
1947 case ir_relation_unordered_less_equal:
1948 case ir_relation_less_equal: return ia32_cc_less_equal;
1949 case ir_relation_unordered_greater:
1950 case ir_relation_greater: return ia32_cc_greater;
1951 case ir_relation_unordered_greater_equal:
1952 case ir_relation_greater_equal: return ia32_cc_greater_equal;
1953 case ir_relation_unordered_less_greater:
1954 case ir_relation_less_greater: return ia32_cc_not_equal;
1955 case ir_relation_less_equal_greater:
1956 case ir_relation_unordered:
1957 case ir_relation_false:
1958 case ir_relation_true:
1959 /* introduce jump always/jump never? */
1962 panic("Unexpected pnc");
1965 case ir_relation_unordered_equal:
1966 case ir_relation_equal: return ia32_cc_equal;
1967 case ir_relation_unordered_less:
1968 case ir_relation_less: return ia32_cc_below;
1969 case ir_relation_unordered_less_equal:
1970 case ir_relation_less_equal: return ia32_cc_below_equal;
1971 case ir_relation_unordered_greater:
1972 case ir_relation_greater: return ia32_cc_above;
1973 case ir_relation_unordered_greater_equal:
1974 case ir_relation_greater_equal: return ia32_cc_above_equal;
1975 case ir_relation_unordered_less_greater:
1976 case ir_relation_less_greater: return ia32_cc_not_equal;
1977 case ir_relation_less_equal_greater:
1978 case ir_relation_unordered:
1979 case ir_relation_false:
1980 case ir_relation_true:
1981 /* introduce jump always/jump never? */
1984 panic("Unexpected pnc");
1988 static ir_node *get_flags_mode_b(ir_node *node, ia32_condition_code_t *cc_out)
1990 /* a mode_b value, we have to compare it against 0 */
1991 dbg_info *dbgi = get_irn_dbg_info(node);
1992 ir_node *new_block = be_transform_node(get_nodes_block(node));
1993 ir_node *new_op = be_transform_node(node);
1994 ir_node *flags = new_bd_ia32_Test(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_op, new_op, false);
1995 *cc_out = ia32_cc_not_equal;
1999 static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
2001 /* must have a Cmp as input */
2002 ir_relation relation = get_Cmp_relation(cmp);
2003 ir_relation possible;
2004 ir_node *l = get_Cmp_left(cmp);
2005 ir_node *r = get_Cmp_right(cmp);
2006 ir_mode *mode = get_irn_mode(l);
2009 /* check for bit-test */
2010 if (ia32_cg_config.use_bt && (relation == ir_relation_equal
2011 || (mode_is_signed(mode) && relation == ir_relation_less_greater)
2012 || (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater)))
2014 ir_node *la = get_And_left(l);
2015 ir_node *ra = get_And_right(l);
2022 ir_node *c = get_Shl_left(la);
2023 if (is_Const_1(c) && is_Const_0(r)) {
2024 /* (1 << n) & ra) */
2025 ir_node *n = get_Shl_right(la);
2026 flags = gen_bt(cmp, ra, n);
2027 /* the bit is copied into the CF flag */
2028 if (relation & ir_relation_equal)
2029 *cc_out = ia32_cc_above_equal; /* test for CF=0 */
2031 *cc_out = ia32_cc_below; /* test for CF=1 */
2037 /* the middle-end tries to eliminate impossible relations, so a ptr != 0
2038 * test becomes ptr > 0. But for x86 an equal comparison is preferable to
2039 * a >0 (we can sometimes eliminate the cmp in favor of flags produced by
2040 * a predecessor node). So add the < bit */
2041 possible = ir_get_possible_cmp_relations(l, r);
2042 if (((relation & ir_relation_less) && !(possible & ir_relation_greater))
2043 || ((relation & ir_relation_greater) && !(possible & ir_relation_less)))
2044 relation |= ir_relation_less_greater;
2046 /* just do a normal transformation of the Cmp */
2047 *cc_out = relation_to_condition_code(relation, mode);
2048 flags = be_transform_node(cmp);
2053 * Transform a node returning a "flag" result.
2055 * @param node the node to transform
2056 * @param cc_out the compare mode to use
2058 static ir_node *get_flags_node(ir_node *node, ia32_condition_code_t *cc_out)
2061 return get_flags_node_cmp(node, cc_out);
2062 assert(get_irn_mode(node) == mode_b);
2063 return get_flags_mode_b(node, cc_out);
2067 * Transforms a Load.
2069 * @return the created ia32 Load node
2071 static ir_node *gen_Load(ir_node *node)
2073 ir_node *old_block = get_nodes_block(node);
2074 ir_node *block = be_transform_node(old_block);
2075 ir_node *ptr = get_Load_ptr(node);
2076 ir_node *mem = get_Load_mem(node);
2077 ir_node *new_mem = be_transform_node(mem);
2078 dbg_info *dbgi = get_irn_dbg_info(node);
2079 ir_mode *mode = get_Load_mode(node);
2083 ia32_address_t addr;
2085 /* construct load address */
2086 memset(&addr, 0, sizeof(addr));
2087 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2094 base = be_transform_node(base);
2097 if (index == NULL) {
2100 index = be_transform_node(index);
2103 if (mode_is_float(mode)) {
2104 if (ia32_cg_config.use_sse2) {
2105 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
2108 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
2112 assert(mode != mode_b);
2114 /* create a conv node with address mode for smaller modes */
2115 if (get_mode_size_bits(mode) < 32) {
2116 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
2117 new_mem, noreg_GP, mode);
2119 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
2123 set_irn_pinned(new_node, get_irn_pinned(node));
2124 set_ia32_op_type(new_node, ia32_AddrModeS);
2125 set_ia32_ls_mode(new_node, mode);
2126 set_address(new_node, &addr);
2128 if (get_irn_pinned(node) == op_pin_state_floats) {
2129 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
2130 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
2131 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
2132 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2135 SET_IA32_ORIG_NODE(new_node, node);
2140 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2141 ir_node *ptr, ir_node *other)
2148 /* we only use address mode if we're the only user of the load */
2149 if (get_irn_n_edges(node) > 1)
2152 load = get_Proj_pred(node);
2155 if (get_nodes_block(load) != block)
2158 /* store should have the same pointer as the load */
2159 if (get_Load_ptr(load) != ptr)
2162 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2163 if (other != NULL &&
2164 get_nodes_block(other) == block &&
2165 heights_reachable_in_block(ia32_heights, other, load)) {
2169 if (ia32_prevents_AM(block, load, mem))
2171 /* Store should be attached to the load via mem */
2172 assert(heights_reachable_in_block(ia32_heights, mem, load));
2177 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2178 ir_node *mem, ir_node *ptr, ir_mode *mode,
2179 construct_binop_dest_func *func,
2180 construct_binop_dest_func *func8bit,
2181 match_flags_t flags)
2183 ir_node *src_block = get_nodes_block(node);
2191 ia32_address_mode_t am;
2192 ia32_address_t *addr = &am.addr;
2193 memset(&am, 0, sizeof(am));
2195 assert(flags & match_immediate); /* there is no destam node without... */
2196 commutative = (flags & match_commutative) != 0;
2198 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2199 build_address(&am, op1, ia32_create_am_double_use);
2200 new_op = create_immediate_or_transform(op2, 0);
2201 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2202 build_address(&am, op2, ia32_create_am_double_use);
2203 new_op = create_immediate_or_transform(op1, 0);
2208 if (addr->base == NULL)
2209 addr->base = noreg_GP;
2210 if (addr->index == NULL)
2211 addr->index = noreg_GP;
2212 if (addr->mem == NULL)
2215 dbgi = get_irn_dbg_info(node);
2216 block = be_transform_node(src_block);
2217 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2219 if (get_mode_size_bits(mode) == 8) {
2220 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2222 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2224 set_address(new_node, addr);
2225 set_ia32_op_type(new_node, ia32_AddrModeD);
2226 set_ia32_ls_mode(new_node, mode);
2227 SET_IA32_ORIG_NODE(new_node, node);
2229 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2230 mem_proj = be_transform_node(am.mem_proj);
2231 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2236 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2237 ir_node *ptr, ir_mode *mode,
2238 construct_unop_dest_func *func)
2240 ir_node *src_block = get_nodes_block(node);
2246 ia32_address_mode_t am;
2247 ia32_address_t *addr = &am.addr;
2249 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2252 memset(&am, 0, sizeof(am));
2253 build_address(&am, op, ia32_create_am_double_use);
2255 dbgi = get_irn_dbg_info(node);
2256 block = be_transform_node(src_block);
2257 new_mem = transform_AM_mem(block, am.am_node, mem, addr->mem);
2258 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2259 set_address(new_node, addr);
2260 set_ia32_op_type(new_node, ia32_AddrModeD);
2261 set_ia32_ls_mode(new_node, mode);
2262 SET_IA32_ORIG_NODE(new_node, node);
2264 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2265 mem_proj = be_transform_node(am.mem_proj);
2266 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2271 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2273 ir_mode *mode = get_irn_mode(node);
2274 ir_node *mux_true = get_Mux_true(node);
2275 ir_node *mux_false = get_Mux_false(node);
2283 ia32_condition_code_t cc;
2284 ia32_address_t addr;
2286 if (get_mode_size_bits(mode) != 8)
2289 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2291 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2297 cond = get_Mux_sel(node);
2298 flags = get_flags_node(cond, &cc);
2299 /* we can't handle the float special cases with SetM */
2300 if (cc & ia32_cc_additional_float_cases)
2303 cc = ia32_negate_condition_code(cc);
2305 build_address_ptr(&addr, ptr, mem);
2307 dbgi = get_irn_dbg_info(node);
2308 block = get_nodes_block(node);
2309 new_block = be_transform_node(block);
2310 new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base,
2311 addr.index, addr.mem, flags, cc);
2312 set_address(new_node, &addr);
2313 set_ia32_op_type(new_node, ia32_AddrModeD);
2314 set_ia32_ls_mode(new_node, mode);
2315 SET_IA32_ORIG_NODE(new_node, node);
2320 static ir_node *try_create_dest_am(ir_node *node)
2322 ir_node *val = get_Store_value(node);
2323 ir_node *mem = get_Store_mem(node);
2324 ir_node *ptr = get_Store_ptr(node);
2325 ir_mode *mode = get_irn_mode(val);
2326 unsigned bits = get_mode_size_bits(mode);
2331 /* handle only GP modes for now... */
2332 if (!ia32_mode_needs_gp_reg(mode))
2336 /* store must be the only user of the val node */
2337 if (get_irn_n_edges(val) > 1)
2339 /* skip pointless convs */
2341 ir_node *conv_op = get_Conv_op(val);
2342 ir_mode *pred_mode = get_irn_mode(conv_op);
2343 if (!ia32_mode_needs_gp_reg(pred_mode))
2345 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2353 /* value must be in the same block */
2354 if (get_nodes_block(node) != get_nodes_block(val))
2357 switch (get_irn_opcode(val)) {
2359 op1 = get_Add_left(val);
2360 op2 = get_Add_right(val);
2361 if (ia32_cg_config.use_incdec) {
2362 if (is_Const_1(op2)) {
2363 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2365 } else if (is_Const_Minus_1(op2)) {
2366 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2370 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2371 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2372 match_commutative | match_immediate);
2375 op1 = get_Sub_left(val);
2376 op2 = get_Sub_right(val);
2377 if (is_Const(op2)) {
2378 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2380 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2381 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2385 op1 = get_And_left(val);
2386 op2 = get_And_right(val);
2387 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2388 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2389 match_commutative | match_immediate);
2392 op1 = get_Or_left(val);
2393 op2 = get_Or_right(val);
2394 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2395 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2396 match_commutative | match_immediate);
2399 op1 = get_Eor_left(val);
2400 op2 = get_Eor_right(val);
2401 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2402 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2403 match_commutative | match_immediate);
2406 op1 = get_Shl_left(val);
2407 op2 = get_Shl_right(val);
2408 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2409 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2413 op1 = get_Shr_left(val);
2414 op2 = get_Shr_right(val);
2415 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2416 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2420 op1 = get_Shrs_left(val);
2421 op2 = get_Shrs_right(val);
2422 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2423 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2427 op1 = get_Rotl_left(val);
2428 op2 = get_Rotl_right(val);
2429 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2430 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2433 /* TODO: match ROR patterns... */
2435 new_node = try_create_SetMem(val, ptr, mem);
2439 op1 = get_Minus_op(val);
2440 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2443 /* should be lowered already */
2444 assert(mode != mode_b);
2445 op1 = get_Not_op(val);
2446 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2452 if (new_node != NULL) {
2453 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2454 get_irn_pinned(node) == op_pin_state_pinned) {
2455 set_irn_pinned(new_node, op_pin_state_pinned);
2462 static bool possible_int_mode_for_fp(ir_mode *mode)
2466 if (!mode_is_signed(mode))
2468 size = get_mode_size_bits(mode);
2469 if (size != 16 && size != 32)
2474 static int is_float_to_int_conv(const ir_node *node)
2476 ir_mode *mode = get_irn_mode(node);
2480 if (!possible_int_mode_for_fp(mode))
2485 conv_op = get_Conv_op(node);
2486 conv_mode = get_irn_mode(conv_op);
2488 if (!mode_is_float(conv_mode))
2495 * Transform a Store(floatConst) into a sequence of
2498 * @return the created ia32 Store node
2500 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2502 ir_mode *mode = get_irn_mode(cns);
2503 unsigned size = get_mode_size_bytes(mode);
2504 ir_tarval *tv = get_Const_tarval(cns);
2505 ir_node *block = get_nodes_block(node);
2506 ir_node *new_block = be_transform_node(block);
2507 ir_node *ptr = get_Store_ptr(node);
2508 ir_node *mem = get_Store_mem(node);
2509 dbg_info *dbgi = get_irn_dbg_info(node);
2513 ia32_address_t addr;
2515 assert(size % 4 == 0);
2518 build_address_ptr(&addr, ptr, mem);
2522 get_tarval_sub_bits(tv, ofs) |
2523 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2524 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2525 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2526 ir_node *imm = ia32_create_Immediate(NULL, 0, val);
2528 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2529 addr.index, addr.mem, imm);
2531 set_irn_pinned(new_node, get_irn_pinned(node));
2532 set_ia32_op_type(new_node, ia32_AddrModeD);
2533 set_ia32_ls_mode(new_node, mode_Iu);
2534 set_address(new_node, &addr);
2535 SET_IA32_ORIG_NODE(new_node, node);
2538 ins[i++] = new_node;
2543 } while (size != 0);
2546 return new_rd_Sync(dbgi, new_block, i, ins);
2553 * Generate a vfist or vfisttp instruction.
2555 static ir_node *gen_vfist(dbg_info *dbgi, ir_node *block, ir_node *base, ir_node *index,
2556 ir_node *mem, ir_node *val, ir_node **fist)
2560 if (ia32_cg_config.use_fisttp) {
2561 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2562 if other users exists */
2563 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2564 ir_node *value = new_r_Proj(vfisttp, mode_E, pn_ia32_vfisttp_res);
2565 be_new_Keep(block, 1, &value);
2567 new_node = new_r_Proj(vfisttp, mode_M, pn_ia32_vfisttp_M);
2570 ir_node *trunc_mode = ia32_new_Fpu_truncate(current_ir_graph);
2573 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2579 * Transforms a general (no special case) Store.
2581 * @return the created ia32 Store node
2583 static ir_node *gen_general_Store(ir_node *node)
2585 ir_node *val = get_Store_value(node);
2586 ir_mode *mode = get_irn_mode(val);
2587 ir_node *block = get_nodes_block(node);
2588 ir_node *new_block = be_transform_node(block);
2589 ir_node *ptr = get_Store_ptr(node);
2590 ir_node *mem = get_Store_mem(node);
2591 dbg_info *dbgi = get_irn_dbg_info(node);
2592 ir_node *new_val, *new_node, *store;
2593 ia32_address_t addr;
2595 /* check for destination address mode */
2596 new_node = try_create_dest_am(node);
2597 if (new_node != NULL)
2600 /* construct store address */
2601 memset(&addr, 0, sizeof(addr));
2602 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
2604 if (addr.base == NULL) {
2605 addr.base = noreg_GP;
2607 addr.base = be_transform_node(addr.base);
2610 if (addr.index == NULL) {
2611 addr.index = noreg_GP;
2613 addr.index = be_transform_node(addr.index);
2615 addr.mem = be_transform_node(mem);
2617 if (mode_is_float(mode)) {
2618 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2620 while (is_Conv(val) && mode == get_irn_mode(val)) {
2621 ir_node *op = get_Conv_op(val);
2622 if (!mode_is_float(get_irn_mode(op)))
2626 new_val = be_transform_node(val);
2627 if (ia32_cg_config.use_sse2) {
2628 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2629 addr.index, addr.mem, new_val);
2631 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2632 addr.index, addr.mem, new_val, mode);
2635 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2636 val = get_Conv_op(val);
2638 /* TODO: is this optimisation still necessary at all (middleend)? */
2639 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2640 while (is_Conv(val)) {
2641 ir_node *op = get_Conv_op(val);
2642 if (!mode_is_float(get_irn_mode(op)))
2644 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2648 new_val = be_transform_node(val);
2649 new_node = gen_vfist(dbgi, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2651 new_val = create_immediate_or_transform(val, 0);
2652 assert(mode != mode_b);
2654 if (get_mode_size_bits(mode) == 8) {
2655 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2656 addr.index, addr.mem, new_val);
2658 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2659 addr.index, addr.mem, new_val);
2664 set_irn_pinned(store, get_irn_pinned(node));
2665 set_ia32_op_type(store, ia32_AddrModeD);
2666 set_ia32_ls_mode(store, mode);
2668 set_address(store, &addr);
2669 SET_IA32_ORIG_NODE(store, node);
2675 * Transforms a Store.
2677 * @return the created ia32 Store node
2679 static ir_node *gen_Store(ir_node *node)
2681 ir_node *val = get_Store_value(node);
2682 ir_mode *mode = get_irn_mode(val);
2684 if (mode_is_float(mode) && is_Const(val)) {
2685 /* We can transform every floating const store
2686 into a sequence of integer stores.
2687 If the constant is already in a register,
2688 it would be better to use it, but we don't
2689 have this information here. */
2690 return gen_float_const_Store(node, val);
2692 return gen_general_Store(node);
2696 * Transforms a Switch.
2698 * @return the created ia32 SwitchJmp node
2700 static ir_node *create_Switch(ir_node *node)
2702 dbg_info *dbgi = get_irn_dbg_info(node);
2703 ir_node *block = be_transform_node(get_nodes_block(node));
2704 ir_node *sel = get_Cond_selector(node);
2705 ir_node *new_sel = be_transform_node(sel);
2706 long switch_min = LONG_MAX;
2707 long switch_max = LONG_MIN;
2708 long default_pn = get_Cond_default_proj(node);
2710 const ir_edge_t *edge;
2712 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2714 /* determine the smallest switch case value */
2715 foreach_out_edge(node, edge) {
2716 ir_node *proj = get_edge_src_irn(edge);
2717 long pn = get_Proj_proj(proj);
2718 if (pn == default_pn)
2721 if (pn < switch_min)
2723 if (pn > switch_max)
2727 if ((unsigned long) (switch_max - switch_min) > 128000) {
2728 panic("Size of switch %+F bigger than 128000", node);
2731 if (switch_min != 0) {
2732 /* if smallest switch case is not 0 we need an additional sub */
2733 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg_GP);
2734 add_ia32_am_offs_int(new_sel, -switch_min);
2735 set_ia32_op_type(new_sel, ia32_AddrModeS);
2737 SET_IA32_ORIG_NODE(new_sel, node);
2740 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2741 SET_IA32_ORIG_NODE(new_node, node);
2747 * Transform a Cond node.
2749 static ir_node *gen_Cond(ir_node *node)
2751 ir_node *block = get_nodes_block(node);
2752 ir_node *new_block = be_transform_node(block);
2753 dbg_info *dbgi = get_irn_dbg_info(node);
2754 ir_node *sel = get_Cond_selector(node);
2755 ir_mode *sel_mode = get_irn_mode(sel);
2756 ir_node *flags = NULL;
2758 ia32_condition_code_t cc;
2760 if (sel_mode != mode_b) {
2761 return create_Switch(node);
2764 /* we get flags from a Cmp */
2765 flags = get_flags_node(sel, &cc);
2767 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, cc);
2768 SET_IA32_ORIG_NODE(new_node, node);
2774 * Transform a be_Copy.
2776 static ir_node *gen_be_Copy(ir_node *node)
2778 ir_node *new_node = be_duplicate_node(node);
2779 ir_mode *mode = get_irn_mode(new_node);
2781 if (ia32_mode_needs_gp_reg(mode)) {
2782 set_irn_mode(new_node, mode_Iu);
2788 static ir_node *create_Fucom(ir_node *node)
2790 dbg_info *dbgi = get_irn_dbg_info(node);
2791 ir_node *block = get_nodes_block(node);
2792 ir_node *new_block = be_transform_node(block);
2793 ir_node *left = get_Cmp_left(node);
2794 ir_node *new_left = be_transform_node(left);
2795 ir_node *right = get_Cmp_right(node);
2799 if (ia32_cg_config.use_fucomi) {
2800 new_right = be_transform_node(right);
2801 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2803 set_ia32_commutative(new_node);
2804 SET_IA32_ORIG_NODE(new_node, node);
2806 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2807 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2809 new_right = be_transform_node(right);
2810 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2813 set_ia32_commutative(new_node);
2815 SET_IA32_ORIG_NODE(new_node, node);
2817 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2818 SET_IA32_ORIG_NODE(new_node, node);
2824 static ir_node *create_Ucomi(ir_node *node)
2826 dbg_info *dbgi = get_irn_dbg_info(node);
2827 ir_node *src_block = get_nodes_block(node);
2828 ir_node *new_block = be_transform_node(src_block);
2829 ir_node *left = get_Cmp_left(node);
2830 ir_node *right = get_Cmp_right(node);
2832 ia32_address_mode_t am;
2833 ia32_address_t *addr = &am.addr;
2835 match_arguments(&am, src_block, left, right, NULL,
2836 match_commutative | match_am);
2838 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2839 addr->mem, am.new_op1, am.new_op2,
2841 set_am_attributes(new_node, &am);
2843 SET_IA32_ORIG_NODE(new_node, node);
2845 new_node = fix_mem_proj(new_node, &am);
2851 * returns true if it is assured, that the upper bits of a node are "clean"
2852 * which means for a 16 or 8 bit value, that the upper bits in the register
2853 * are 0 for unsigned and a copy of the last significant bit for signed
2856 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2858 assert(ia32_mode_needs_gp_reg(mode));
2859 if (get_mode_size_bits(mode) >= 32)
2862 if (is_Proj(transformed_node))
2863 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2865 switch (get_ia32_irn_opcode(transformed_node)) {
2866 case iro_ia32_Conv_I2I:
2867 case iro_ia32_Conv_I2I8Bit: {
2868 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2869 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2871 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2878 if (mode_is_signed(mode)) {
2879 return false; /* TODO handle signed modes */
2881 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2882 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2883 const ia32_immediate_attr_t *attr
2884 = get_ia32_immediate_attr_const(right);
2885 if (attr->symconst == 0 &&
2886 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2890 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2894 /* TODO too conservative if shift amount is constant */
2895 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2898 if (!mode_is_signed(mode)) {
2900 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2901 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2903 /* TODO if one is known to be zero extended, then || is sufficient */
2908 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2909 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2911 case iro_ia32_Const:
2912 case iro_ia32_Immediate: {
2913 const ia32_immediate_attr_t *attr =
2914 get_ia32_immediate_attr_const(transformed_node);
2915 if (mode_is_signed(mode)) {
2916 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2917 return shifted == 0 || shifted == -1;
2919 unsigned long shifted = (unsigned long)attr->offset;
2920 shifted >>= get_mode_size_bits(mode);
2921 return shifted == 0;
2931 * Generate code for a Cmp.
2933 static ir_node *gen_Cmp(ir_node *node)
2935 dbg_info *dbgi = get_irn_dbg_info(node);
2936 ir_node *block = get_nodes_block(node);
2937 ir_node *new_block = be_transform_node(block);
2938 ir_node *left = get_Cmp_left(node);
2939 ir_node *right = get_Cmp_right(node);
2940 ir_mode *cmp_mode = get_irn_mode(left);
2942 ia32_address_mode_t am;
2943 ia32_address_t *addr = &am.addr;
2945 if (mode_is_float(cmp_mode)) {
2946 if (ia32_cg_config.use_sse2) {
2947 return create_Ucomi(node);
2949 return create_Fucom(node);
2953 assert(ia32_mode_needs_gp_reg(cmp_mode));
2955 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2956 if (is_Const_0(right) &&
2958 get_irn_n_edges(left) == 1) {
2959 /* Test(and_left, and_right) */
2960 ir_node *and_left = get_And_left(left);
2961 ir_node *and_right = get_And_right(left);
2963 /* matze: code here used mode instead of cmd_mode, I think it is always
2964 * the same as cmp_mode, but I leave this here to see if this is really
2967 assert(get_irn_mode(and_left) == cmp_mode);
2969 match_arguments(&am, block, and_left, and_right, NULL,
2971 match_am | match_8bit_am | match_16bit_am |
2972 match_am_and_immediates | match_immediate);
2974 /* use 32bit compare mode if possible since the opcode is smaller */
2975 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2976 upper_bits_clean(am.new_op2, cmp_mode)) {
2977 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2980 if (get_mode_size_bits(cmp_mode) == 8) {
2981 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2982 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
2984 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2985 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
2988 /* Cmp(left, right) */
2989 match_arguments(&am, block, left, right, NULL,
2990 match_commutative | match_am | match_8bit_am |
2991 match_16bit_am | match_am_and_immediates |
2993 /* use 32bit compare mode if possible since the opcode is smaller */
2994 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2995 upper_bits_clean(am.new_op2, cmp_mode)) {
2996 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2999 if (get_mode_size_bits(cmp_mode) == 8) {
3000 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
3001 addr->index, addr->mem, am.new_op1,
3002 am.new_op2, am.ins_permuted);
3004 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
3005 addr->mem, am.new_op1, am.new_op2, am.ins_permuted);
3008 set_am_attributes(new_node, &am);
3009 set_ia32_ls_mode(new_node, cmp_mode);
3011 SET_IA32_ORIG_NODE(new_node, node);
3013 new_node = fix_mem_proj(new_node, &am);
3018 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
3019 ia32_condition_code_t cc)
3021 dbg_info *dbgi = get_irn_dbg_info(node);
3022 ir_node *block = get_nodes_block(node);
3023 ir_node *new_block = be_transform_node(block);
3024 ir_node *val_true = get_Mux_true(node);
3025 ir_node *val_false = get_Mux_false(node);
3027 ia32_address_mode_t am;
3028 ia32_address_t *addr;
3030 assert(ia32_cg_config.use_cmov);
3031 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
3035 match_arguments(&am, block, val_false, val_true, flags,
3036 match_commutative | match_am | match_16bit_am | match_mode_neutral);
3038 if (am.ins_permuted)
3039 cc = ia32_negate_condition_code(cc);
3041 new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index,
3042 addr->mem, am.new_op1, am.new_op2, new_flags,
3044 set_am_attributes(new_node, &am);
3046 SET_IA32_ORIG_NODE(new_node, node);
3048 new_node = fix_mem_proj(new_node, &am);
3054 * Creates a ia32 Setcc instruction.
3056 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
3057 ir_node *flags, ia32_condition_code_t cc,
3060 ir_mode *mode = get_irn_mode(orig_node);
3063 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, cc);
3064 SET_IA32_ORIG_NODE(new_node, orig_node);
3066 /* we might need to conv the result up */
3067 if (get_mode_size_bits(mode) > 8) {
3068 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
3069 nomem, new_node, mode_Bu);
3070 SET_IA32_ORIG_NODE(new_node, orig_node);
3077 * Create instruction for an unsigned Difference or Zero.
3079 static ir_node *create_doz(ir_node *psi, ir_node *a, ir_node *b)
3081 ir_mode *mode = get_irn_mode(psi);
3091 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
3092 match_mode_neutral | match_am | match_immediate | match_two_users);
3094 block = get_nodes_block(new_node);
3096 if (is_Proj(new_node)) {
3097 sub = get_Proj_pred(new_node);
3100 set_irn_mode(sub, mode_T);
3101 new_node = new_rd_Proj(NULL, sub, mode, pn_ia32_res);
3103 assert(is_ia32_Sub(sub));
3104 eflags = new_rd_Proj(NULL, sub, mode_Iu, pn_ia32_Sub_flags);
3106 dbgi = get_irn_dbg_info(psi);
3107 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
3108 notn = new_bd_ia32_Not(dbgi, block, sbb);
3110 new_node = new_bd_ia32_And(dbgi, block, noreg_GP, noreg_GP, nomem, new_node, notn);
3111 set_ia32_commutative(new_node);
3116 * Create an const array of two float consts.
3118 * @param c0 the first constant
3119 * @param c1 the second constant
3120 * @param new_mode IN/OUT for the mode of the constants, if NULL
3121 * smallest possible mode will be used
3123 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode)
3126 ir_mode *mode = *new_mode;
3128 ir_initializer_t *initializer;
3129 ir_tarval *tv0 = get_Const_tarval(c0);
3130 ir_tarval *tv1 = get_Const_tarval(c1);
3133 /* detect the best mode for the constants */
3134 mode = get_tarval_mode(tv0);
3136 if (mode != mode_F) {
3137 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3138 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3140 tv0 = tarval_convert_to(tv0, mode);
3141 tv1 = tarval_convert_to(tv1, mode);
3142 } else if (mode != mode_D) {
3143 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3144 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3146 tv0 = tarval_convert_to(tv0, mode);
3147 tv1 = tarval_convert_to(tv1, mode);
3154 tp = ia32_create_float_type(mode, 4);
3155 tp = ia32_create_float_array(tp);
3157 ent = new_entity(get_glob_type(), id_unique("C%u"), tp);
3159 set_entity_ld_ident(ent, get_entity_ident(ent));
3160 set_entity_visibility(ent, ir_visibility_private);
3161 add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
3163 initializer = create_initializer_compound(2);
3165 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3166 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3168 set_entity_initializer(ent, initializer);
3175 * Possible transformations for creating a Setcc.
3177 enum setcc_transform_insn {
3190 typedef struct setcc_transform {
3192 ia32_condition_code_t cc;
3194 enum setcc_transform_insn transform;
3198 } setcc_transform_t;
3201 * Setcc can only handle 0 and 1 result.
3202 * Find a transformation that creates 0 and 1 from
3205 static void find_const_transform(ia32_condition_code_t cc,
3206 ir_tarval *t, ir_tarval *f,
3207 setcc_transform_t *res)
3213 if (tarval_is_null(t)) {
3217 cc = ia32_negate_condition_code(cc);
3218 } else if (tarval_cmp(t, f) == ir_relation_less) {
3219 // now, t is the bigger one
3223 cc = ia32_negate_condition_code(cc);
3227 if (! tarval_is_null(f)) {
3228 ir_tarval *t_sub = tarval_sub(t, f, NULL);
3231 res->steps[step].transform = SETCC_TR_ADD;
3233 if (t == tarval_bad)
3234 panic("constant subtract failed");
3235 if (! tarval_is_long(f))
3236 panic("tarval is not long");
3238 res->steps[step].val = get_tarval_long(f);
3240 f = tarval_sub(f, f, NULL);
3241 assert(tarval_is_null(f));
3244 if (tarval_is_one(t)) {
3245 res->steps[step].transform = SETCC_TR_SET;
3246 res->num_steps = ++step;
3250 if (tarval_is_minus_one(t)) {
3251 res->steps[step].transform = SETCC_TR_NEG;
3253 res->steps[step].transform = SETCC_TR_SET;
3254 res->num_steps = ++step;
3257 if (tarval_is_long(t)) {
3258 long v = get_tarval_long(t);
3260 res->steps[step].val = 0;
3263 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3265 res->steps[step].transform = SETCC_TR_LEAxx;
3266 res->steps[step].scale = 3; /* (a << 3) + a */
3269 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3271 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3272 res->steps[step].scale = 3; /* (a << 3) */
3275 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3277 res->steps[step].transform = SETCC_TR_LEAxx;
3278 res->steps[step].scale = 2; /* (a << 2) + a */
3281 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3283 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3284 res->steps[step].scale = 2; /* (a << 2) */
3287 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3289 res->steps[step].transform = SETCC_TR_LEAxx;
3290 res->steps[step].scale = 1; /* (a << 1) + a */
3293 if (step > 0 && res->steps[step - 1].transform == SETCC_TR_ADD)
3295 res->steps[step].transform = res->steps[step].val == 0 ? SETCC_TR_SHL : SETCC_TR_LEA;
3296 res->steps[step].scale = 1; /* (a << 1) */
3299 res->num_steps = step;
3302 if (! tarval_is_single_bit(t)) {
3303 res->steps[step].transform = SETCC_TR_AND;
3304 res->steps[step].val = v;
3306 res->steps[step].transform = SETCC_TR_NEG;
3308 int v = get_tarval_lowest_bit(t);
3311 res->steps[step].transform = SETCC_TR_SHL;
3312 res->steps[step].scale = v;
3316 res->steps[step].transform = SETCC_TR_SET;
3317 res->num_steps = ++step;
3320 panic("tarval is not long");
3324 * Transforms a Mux node into some code sequence.
3326 * @return The transformed node.
3328 static ir_node *gen_Mux(ir_node *node)
3330 dbg_info *dbgi = get_irn_dbg_info(node);
3331 ir_node *block = get_nodes_block(node);
3332 ir_node *new_block = be_transform_node(block);
3333 ir_node *mux_true = get_Mux_true(node);
3334 ir_node *mux_false = get_Mux_false(node);
3335 ir_node *sel = get_Mux_sel(node);
3336 ir_mode *mode = get_irn_mode(node);
3340 ia32_condition_code_t cc;
3342 assert(get_irn_mode(sel) == mode_b);
3344 is_abs = be_mux_is_abs(sel, mux_true, mux_false);
3346 return create_abs(dbgi, block, be_get_abs_op(sel), is_abs < 0, node);
3349 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3350 if (mode_is_float(mode)) {
3351 ir_node *cmp_left = get_Cmp_left(sel);
3352 ir_node *cmp_right = get_Cmp_right(sel);
3353 ir_relation relation = get_Cmp_relation(sel);
3355 if (ia32_cg_config.use_sse2) {
3356 if (relation == ir_relation_less || relation == ir_relation_less_equal) {
3357 if (cmp_left == mux_true && cmp_right == mux_false) {
3358 /* Mux(a <= b, a, b) => MIN */
3359 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3360 match_commutative | match_am | match_two_users);
3361 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3362 /* Mux(a <= b, b, a) => MAX */
3363 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3364 match_commutative | match_am | match_two_users);
3366 } else if (relation == ir_relation_greater || relation == ir_relation_greater_equal) {
3367 if (cmp_left == mux_true && cmp_right == mux_false) {
3368 /* Mux(a >= b, a, b) => MAX */
3369 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3370 match_commutative | match_am | match_two_users);
3371 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3372 /* Mux(a >= b, b, a) => MIN */
3373 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3374 match_commutative | match_am | match_two_users);
3379 if (is_Const(mux_true) && is_Const(mux_false)) {
3380 ia32_address_mode_t am;
3385 flags = get_flags_node(sel, &cc);
3386 new_node = create_set_32bit(dbgi, new_block, flags, cc, 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_Lea(dbgi, new_block, new_node, new_node);
3423 panic("Unsupported constant size");
3426 am.ls_mode = new_mode;
3427 am.addr.base = get_symconst_base();
3428 am.addr.index = new_node;
3429 am.addr.mem = nomem;
3431 am.addr.scale = scale;
3432 am.addr.use_frame = 0;
3433 am.addr.frame_entity = NULL;
3434 am.addr.symconst_sign = 0;
3435 am.mem_proj = am.addr.mem;
3436 am.op_type = ia32_AddrModeS;
3439 am.pinned = op_pin_state_floats;
3441 am.ins_permuted = false;
3443 if (ia32_cg_config.use_sse2)
3444 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3446 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3447 set_am_attributes(load, &am);
3449 return new_rd_Proj(NULL, load, mode_vfp, pn_ia32_res);
3451 panic("cannot transform floating point Mux");
3454 assert(ia32_mode_needs_gp_reg(mode));
3457 ir_node *cmp_left = get_Cmp_left(sel);
3458 ir_node *cmp_right = get_Cmp_right(sel);
3459 ir_relation relation = get_Cmp_relation(sel);
3460 ir_node *val_true = mux_true;
3461 ir_node *val_false = mux_false;
3463 if (is_Const(val_true) && is_Const_null(val_true)) {
3464 ir_node *tmp = val_false;
3465 val_false = val_true;
3467 relation = get_negated_relation(relation);
3469 if (is_Const_0(val_false) && is_Sub(val_true)) {
3470 if ((relation & ir_relation_greater)
3471 && get_Sub_left(val_true) == cmp_left
3472 && get_Sub_right(val_true) == cmp_right) {
3473 return create_doz(node, cmp_left, cmp_right);
3475 if ((relation & ir_relation_less)
3476 && get_Sub_left(val_true) == cmp_right
3477 && get_Sub_right(val_true) == cmp_left) {
3478 return create_doz(node, cmp_right, cmp_left);
3483 flags = get_flags_node(sel, &cc);
3485 if (is_Const(mux_true) && is_Const(mux_false)) {
3486 /* both are const, good */
3487 ir_tarval *tv_true = get_Const_tarval(mux_true);
3488 ir_tarval *tv_false = get_Const_tarval(mux_false);
3489 setcc_transform_t res;
3492 find_const_transform(cc, tv_true, tv_false, &res);
3494 for (step = (int)res.num_steps - 1; step >= 0; --step) {
3497 switch (res.steps[step].transform) {
3499 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, noreg_GP);
3500 add_ia32_am_offs_int(new_node, res.steps[step].val);
3502 case SETCC_TR_ADDxx:
3503 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3506 new_node = new_bd_ia32_Lea(dbgi, new_block, noreg_GP, new_node);
3507 set_ia32_am_scale(new_node, res.steps[step].scale);
3508 set_ia32_am_offs_int(new_node, res.steps[step].val);
3510 case SETCC_TR_LEAxx:
3511 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3512 set_ia32_am_scale(new_node, res.steps[step].scale);
3513 set_ia32_am_offs_int(new_node, res.steps[step].val);
3516 imm = ia32_immediate_from_long(res.steps[step].scale);
3517 new_node = new_bd_ia32_Shl(dbgi, new_block, new_node, imm);
3520 new_node = new_bd_ia32_Neg(dbgi, new_block, new_node);
3523 new_node = new_bd_ia32_Not(dbgi, new_block, new_node);
3526 imm = ia32_immediate_from_long(res.steps[step].val);
3527 new_node = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_node, imm);
3530 new_node = create_set_32bit(dbgi, new_block, flags, res.cc, node);
3533 new_node = new_bd_ia32_Sbb0(dbgi, new_block, flags);
3536 panic("unknown setcc transform");
3540 new_node = create_CMov(node, sel, flags, cc);
3548 * Create a conversion from x87 state register to general purpose.
3550 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3552 ir_node *block = be_transform_node(get_nodes_block(node));
3553 ir_node *op = get_Conv_op(node);
3554 ir_node *new_op = be_transform_node(op);
3555 ir_graph *irg = current_ir_graph;
3556 dbg_info *dbgi = get_irn_dbg_info(node);
3557 ir_mode *mode = get_irn_mode(node);
3558 ir_node *fist, *load, *mem;
3560 mem = gen_vfist(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op, &fist);
3561 set_irn_pinned(fist, op_pin_state_floats);
3562 set_ia32_use_frame(fist);
3563 set_ia32_op_type(fist, ia32_AddrModeD);
3565 assert(get_mode_size_bits(mode) <= 32);
3566 /* exception we can only store signed 32 bit integers, so for unsigned
3567 we store a 64bit (signed) integer and load the lower bits */
3568 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3569 set_ia32_ls_mode(fist, mode_Ls);
3571 set_ia32_ls_mode(fist, mode_Is);
3573 SET_IA32_ORIG_NODE(fist, node);
3576 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg_GP, mem);
3578 set_irn_pinned(load, op_pin_state_floats);
3579 set_ia32_use_frame(load);
3580 set_ia32_op_type(load, ia32_AddrModeS);
3581 set_ia32_ls_mode(load, mode_Is);
3582 if (get_ia32_ls_mode(fist) == mode_Ls) {
3583 ia32_attr_t *attr = get_ia32_attr(load);
3584 attr->data.need_64bit_stackent = 1;
3586 ia32_attr_t *attr = get_ia32_attr(load);
3587 attr->data.need_32bit_stackent = 1;
3589 SET_IA32_ORIG_NODE(load, node);
3591 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
3595 * Creates a x87 strict Conv by placing a Store and a Load
3597 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3599 ir_node *block = get_nodes_block(node);
3600 ir_graph *irg = get_Block_irg(block);
3601 dbg_info *dbgi = get_irn_dbg_info(node);
3602 ir_node *frame = get_irg_frame(irg);
3603 ir_node *store, *load;
3606 store = new_bd_ia32_vfst(dbgi, block, frame, noreg_GP, nomem, node, tgt_mode);
3607 set_ia32_use_frame(store);
3608 set_ia32_op_type(store, ia32_AddrModeD);
3609 SET_IA32_ORIG_NODE(store, node);
3611 load = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, store, tgt_mode);
3612 set_ia32_use_frame(load);
3613 set_ia32_op_type(load, ia32_AddrModeS);
3614 SET_IA32_ORIG_NODE(load, node);
3616 new_node = new_r_Proj(load, mode_E, pn_ia32_vfld_res);
3620 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3621 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3623 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3625 func = get_mode_size_bits(mode) == 8 ?
3626 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3627 return func(dbgi, block, base, index, mem, val, mode);
3631 * Create a conversion from general purpose to x87 register
3633 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3635 ir_node *src_block = get_nodes_block(node);
3636 ir_node *block = be_transform_node(src_block);
3637 ir_graph *irg = get_Block_irg(block);
3638 dbg_info *dbgi = get_irn_dbg_info(node);
3639 ir_node *op = get_Conv_op(node);
3640 ir_node *new_op = NULL;
3642 ir_mode *store_mode;
3647 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3648 if (possible_int_mode_for_fp(src_mode)) {
3649 ia32_address_mode_t am;
3651 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3652 if (am.op_type == ia32_AddrModeS) {
3653 ia32_address_t *addr = &am.addr;
3655 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index, addr->mem);
3656 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3658 set_am_attributes(fild, &am);
3659 SET_IA32_ORIG_NODE(fild, node);
3661 fix_mem_proj(fild, &am);
3666 if (new_op == NULL) {
3667 new_op = be_transform_node(op);
3670 mode = get_irn_mode(op);
3672 /* first convert to 32 bit signed if necessary */
3673 if (get_mode_size_bits(src_mode) < 32) {
3674 if (!upper_bits_clean(new_op, src_mode)) {
3675 new_op = create_Conv_I2I(dbgi, block, noreg_GP, noreg_GP, nomem, new_op, src_mode);
3676 SET_IA32_ORIG_NODE(new_op, node);
3681 assert(get_mode_size_bits(mode) == 32);
3684 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg_GP, nomem, new_op);
3686 set_ia32_use_frame(store);
3687 set_ia32_op_type(store, ia32_AddrModeD);
3688 set_ia32_ls_mode(store, mode_Iu);
3690 /* exception for 32bit unsigned, do a 64bit spill+load */
3691 if (!mode_is_signed(mode)) {
3694 ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
3696 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3697 noreg_GP, nomem, zero_const);
3699 set_ia32_use_frame(zero_store);
3700 set_ia32_op_type(zero_store, ia32_AddrModeD);
3701 add_ia32_am_offs_int(zero_store, 4);
3702 set_ia32_ls_mode(zero_store, mode_Iu);
3707 store = new_rd_Sync(dbgi, block, 2, in);
3708 store_mode = mode_Ls;
3710 store_mode = mode_Is;
3714 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg_GP, store);
3716 set_ia32_use_frame(fild);
3717 set_ia32_op_type(fild, ia32_AddrModeS);
3718 set_ia32_ls_mode(fild, store_mode);
3720 new_node = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
3726 * Create a conversion from one integer mode into another one
3728 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3729 dbg_info *dbgi, ir_node *block, ir_node *op,
3732 ir_node *new_block = be_transform_node(block);
3734 ir_mode *smaller_mode;
3735 ia32_address_mode_t am;
3736 ia32_address_t *addr = &am.addr;
3739 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3740 smaller_mode = src_mode;
3742 smaller_mode = tgt_mode;
3745 #ifdef DEBUG_libfirm
3747 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3752 match_arguments(&am, block, NULL, op, NULL,
3753 match_am | match_8bit_am | match_16bit_am);
3755 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3756 /* unnecessary conv. in theory it shouldn't have been AM */
3757 assert(is_ia32_NoReg_GP(addr->base));
3758 assert(is_ia32_NoReg_GP(addr->index));
3759 assert(is_NoMem(addr->mem));
3760 assert(am.addr.offset == 0);
3761 assert(am.addr.symconst_ent == NULL);
3765 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3766 addr->mem, am.new_op2, smaller_mode);
3767 set_am_attributes(new_node, &am);
3768 /* match_arguments assume that out-mode = in-mode, this isn't true here
3770 set_ia32_ls_mode(new_node, smaller_mode);
3771 SET_IA32_ORIG_NODE(new_node, node);
3772 new_node = fix_mem_proj(new_node, &am);
3777 * Transforms a Conv node.
3779 * @return The created ia32 Conv node
3781 static ir_node *gen_Conv(ir_node *node)
3783 ir_node *block = get_nodes_block(node);
3784 ir_node *new_block = be_transform_node(block);
3785 ir_node *op = get_Conv_op(node);
3786 ir_node *new_op = NULL;
3787 dbg_info *dbgi = get_irn_dbg_info(node);
3788 ir_mode *src_mode = get_irn_mode(op);
3789 ir_mode *tgt_mode = get_irn_mode(node);
3790 int src_bits = get_mode_size_bits(src_mode);
3791 int tgt_bits = get_mode_size_bits(tgt_mode);
3792 ir_node *res = NULL;
3794 assert(!mode_is_int(src_mode) || src_bits <= 32);
3795 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3797 /* modeB -> X should already be lowered by the lower_mode_b pass */
3798 if (src_mode == mode_b) {
3799 panic("ConvB not lowered %+F", node);
3802 if (src_mode == tgt_mode) {
3803 if (get_Conv_strict(node)) {
3804 if (ia32_cg_config.use_sse2) {
3805 /* when we are in SSE mode, we can kill all strict no-op conversion */
3806 return be_transform_node(op);
3809 /* this should be optimized already, but who knows... */
3810 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3811 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3812 return be_transform_node(op);
3816 if (mode_is_float(src_mode)) {
3817 new_op = be_transform_node(op);
3818 /* we convert from float ... */
3819 if (mode_is_float(tgt_mode)) {
3821 if (ia32_cg_config.use_sse2) {
3822 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3823 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg_GP, noreg_GP,
3825 set_ia32_ls_mode(res, tgt_mode);
3827 if (get_Conv_strict(node)) {
3828 /* if fp_no_float_fold is not set then we assume that we
3829 * don't have any float operations in a non
3830 * mode_float_arithmetic mode and can skip strict upconvs */
3831 if (src_bits < tgt_bits) {
3832 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3835 res = gen_x87_strict_conv(tgt_mode, new_op);
3836 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3840 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3845 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3846 if (ia32_cg_config.use_sse2) {
3847 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg_GP, noreg_GP,
3849 set_ia32_ls_mode(res, src_mode);
3851 return gen_x87_fp_to_gp(node);
3855 /* we convert from int ... */
3856 if (mode_is_float(tgt_mode)) {
3858 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3859 if (ia32_cg_config.use_sse2) {
3860 new_op = be_transform_node(op);
3861 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg_GP, noreg_GP,
3863 set_ia32_ls_mode(res, tgt_mode);
3865 unsigned int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3866 unsigned float_mantissa = tarval_ieee754_get_mantissa_size(tgt_mode);
3867 res = gen_x87_gp_to_fp(node, src_mode);
3869 /* we need a strict-Conv, if the int mode has more bits than the
3871 if (float_mantissa < int_mantissa) {
3872 res = gen_x87_strict_conv(tgt_mode, res);
3873 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3877 } else if (tgt_mode == mode_b) {
3878 /* mode_b lowering already took care that we only have 0/1 values */
3879 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3880 src_mode, tgt_mode));
3881 return be_transform_node(op);
3884 if (src_bits == tgt_bits) {
3885 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3886 src_mode, tgt_mode));
3887 return be_transform_node(op);
3890 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3898 static ir_node *create_immediate_or_transform(ir_node *node,
3899 char immediate_constraint_type)
3901 ir_node *new_node = ia32_try_create_Immediate(node, immediate_constraint_type);
3902 if (new_node == NULL) {
3903 new_node = be_transform_node(node);
3909 * Transforms a FrameAddr into an ia32 Add.
3911 static ir_node *gen_be_FrameAddr(ir_node *node)
3913 ir_node *block = be_transform_node(get_nodes_block(node));
3914 ir_node *op = be_get_FrameAddr_frame(node);
3915 ir_node *new_op = be_transform_node(op);
3916 dbg_info *dbgi = get_irn_dbg_info(node);
3919 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg_GP);
3920 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3921 set_ia32_use_frame(new_node);
3923 SET_IA32_ORIG_NODE(new_node, node);
3929 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3931 static ir_node *gen_be_Return(ir_node *node)
3933 ir_graph *irg = current_ir_graph;
3934 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3935 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3936 ir_node *new_ret_val = be_transform_node(ret_val);
3937 ir_node *new_ret_mem = be_transform_node(ret_mem);
3938 ir_entity *ent = get_irg_entity(irg);
3939 ir_type *tp = get_entity_type(ent);
3940 dbg_info *dbgi = get_irn_dbg_info(node);
3941 ir_node *block = be_transform_node(get_nodes_block(node));
3944 ir_node *frame, *sse_store, *fld, *mproj;
3951 assert(ret_val != NULL);
3952 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3953 return be_duplicate_node(node);
3956 res_type = get_method_res_type(tp, 0);
3958 if (! is_Primitive_type(res_type)) {
3959 return be_duplicate_node(node);
3962 mode = get_type_mode(res_type);
3963 if (! mode_is_float(mode)) {
3964 return be_duplicate_node(node);
3967 assert(get_method_n_ress(tp) == 1);
3969 frame = get_irg_frame(irg);
3971 /* store xmm0 onto stack */
3972 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg_GP,
3973 new_ret_mem, new_ret_val);
3974 set_ia32_ls_mode(sse_store, mode);
3975 set_ia32_op_type(sse_store, ia32_AddrModeD);
3976 set_ia32_use_frame(sse_store);
3978 /* load into x87 register */
3979 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg_GP, sse_store, mode);
3980 set_ia32_op_type(fld, ia32_AddrModeS);
3981 set_ia32_use_frame(fld);
3983 mproj = new_r_Proj(fld, mode_M, pn_ia32_vfld_M);
3984 fld = new_r_Proj(fld, mode_vfp, pn_ia32_vfld_res);
3986 /* create a new return */
3987 arity = get_irn_arity(node);
3988 in = ALLOCAN(ir_node*, arity);
3989 pop = be_Return_get_pop(node);
3990 for (i = 0; i < arity; ++i) {
3991 ir_node *op = get_irn_n(node, i);
3992 if (op == ret_val) {
3994 } else if (op == ret_mem) {
3997 in[i] = be_transform_node(op);
4000 new_node = be_new_Return(dbgi, irg, block, arity, pop, arity, in);
4001 copy_node_attr(irg, node, new_node);
4007 * Transform a be_AddSP into an ia32_SubSP.
4009 static ir_node *gen_be_AddSP(ir_node *node)
4011 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
4012 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4014 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_SubSP,
4015 match_am | match_immediate);
4016 assert(is_ia32_SubSP(new_node));
4017 arch_irn_set_register(new_node, pn_ia32_SubSP_stack,
4018 &ia32_registers[REG_ESP]);
4023 * Transform a be_SubSP into an ia32_AddSP
4025 static ir_node *gen_be_SubSP(ir_node *node)
4027 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
4028 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4030 ir_node *new_node = gen_binop(node, sp, sz, new_bd_ia32_AddSP,
4031 match_am | match_immediate);
4032 assert(is_ia32_AddSP(new_node));
4033 arch_irn_set_register(new_node, pn_ia32_AddSP_stack,
4034 &ia32_registers[REG_ESP]);
4039 * Change some phi modes
4041 static ir_node *gen_Phi(ir_node *node)
4043 const arch_register_req_t *req;
4044 ir_node *block = be_transform_node(get_nodes_block(node));
4045 ir_graph *irg = current_ir_graph;
4046 dbg_info *dbgi = get_irn_dbg_info(node);
4047 ir_mode *mode = get_irn_mode(node);
4050 if (ia32_mode_needs_gp_reg(mode)) {
4051 /* we shouldn't have any 64bit stuff around anymore */
4052 assert(get_mode_size_bits(mode) <= 32);
4053 /* all integer operations are on 32bit registers now */
4055 req = ia32_reg_classes[CLASS_ia32_gp].class_req;
4056 } else if (mode_is_float(mode)) {
4057 if (ia32_cg_config.use_sse2) {
4059 req = ia32_reg_classes[CLASS_ia32_xmm].class_req;
4062 req = ia32_reg_classes[CLASS_ia32_vfp].class_req;
4065 req = arch_no_register_req;
4068 /* phi nodes allow loops, so we use the old arguments for now
4069 * and fix this later */
4070 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4071 get_irn_in(node) + 1);
4072 copy_node_attr(irg, node, phi);
4073 be_duplicate_deps(node, phi);
4075 arch_set_out_register_req(phi, 0, req);
4077 be_enqueue_preds(node);
4082 static ir_node *gen_Jmp(ir_node *node)
4084 ir_node *block = get_nodes_block(node);
4085 ir_node *new_block = be_transform_node(block);
4086 dbg_info *dbgi = get_irn_dbg_info(node);
4089 new_node = new_bd_ia32_Jmp(dbgi, new_block);
4090 SET_IA32_ORIG_NODE(new_node, node);
4098 static ir_node *gen_IJmp(ir_node *node)
4100 ir_node *block = get_nodes_block(node);
4101 ir_node *new_block = be_transform_node(block);
4102 dbg_info *dbgi = get_irn_dbg_info(node);
4103 ir_node *op = get_IJmp_target(node);
4105 ia32_address_mode_t am;
4106 ia32_address_t *addr = &am.addr;
4108 assert(get_irn_mode(op) == mode_P);
4110 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
4112 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
4113 addr->mem, am.new_op2);
4114 set_am_attributes(new_node, &am);
4115 SET_IA32_ORIG_NODE(new_node, node);
4117 new_node = fix_mem_proj(new_node, &am);
4122 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4124 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
4125 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4127 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
4128 match_immediate | match_mode_neutral);
4131 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4133 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
4134 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4135 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
4139 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4141 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
4142 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4143 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
4147 static ir_node *gen_ia32_l_Add(ir_node *node)
4149 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
4150 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
4151 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
4152 match_commutative | match_am | match_immediate |
4153 match_mode_neutral);
4155 if (is_Proj(lowered)) {
4156 lowered = get_Proj_pred(lowered);
4158 assert(is_ia32_Add(lowered));
4159 set_irn_mode(lowered, mode_T);
4165 static ir_node *gen_ia32_l_Adc(ir_node *node)
4167 return gen_binop_flags(node, new_bd_ia32_Adc,
4168 match_commutative | match_am | match_immediate |
4169 match_mode_neutral);
4173 * Transforms a l_MulS into a "real" MulS node.
4175 * @return the created ia32 Mul node
4177 static ir_node *gen_ia32_l_Mul(ir_node *node)
4179 ir_node *left = get_binop_left(node);
4180 ir_node *right = get_binop_right(node);
4182 return gen_binop(node, left, right, new_bd_ia32_Mul,
4183 match_commutative | match_am | match_mode_neutral);
4187 * Transforms a l_IMulS into a "real" IMul1OPS node.
4189 * @return the created ia32 IMul1OP node
4191 static ir_node *gen_ia32_l_IMul(ir_node *node)
4193 ir_node *left = get_binop_left(node);
4194 ir_node *right = get_binop_right(node);
4196 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
4197 match_commutative | match_am | match_mode_neutral);
4200 static ir_node *gen_ia32_l_Sub(ir_node *node)
4202 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
4203 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4204 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
4205 match_am | match_immediate | match_mode_neutral);
4207 if (is_Proj(lowered)) {
4208 lowered = get_Proj_pred(lowered);
4210 assert(is_ia32_Sub(lowered));
4211 set_irn_mode(lowered, mode_T);
4217 static ir_node *gen_ia32_l_Sbb(ir_node *node)
4219 return gen_binop_flags(node, new_bd_ia32_Sbb,
4220 match_am | match_immediate | match_mode_neutral);
4224 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4225 * op1 - target to be shifted
4226 * op2 - contains bits to be shifted into target
4228 * Only op3 can be an immediate.
4230 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4231 ir_node *low, ir_node *count)
4233 ir_node *block = get_nodes_block(node);
4234 ir_node *new_block = be_transform_node(block);
4235 dbg_info *dbgi = get_irn_dbg_info(node);
4236 ir_node *new_high = be_transform_node(high);
4237 ir_node *new_low = be_transform_node(low);
4241 /* the shift amount can be any mode that is bigger than 5 bits, since all
4242 * other bits are ignored anyway */
4243 while (is_Conv(count) &&
4244 get_irn_n_edges(count) == 1 &&
4245 mode_is_int(get_irn_mode(count))) {
4246 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4247 count = get_Conv_op(count);
4249 new_count = create_immediate_or_transform(count, 0);
4251 if (is_ia32_l_ShlD(node)) {
4252 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
4255 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
4258 SET_IA32_ORIG_NODE(new_node, node);
4263 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4265 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4266 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4267 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4268 return gen_lowered_64bit_shifts(node, high, low, count);
4271 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4273 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4274 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4275 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4276 return gen_lowered_64bit_shifts(node, high, low, count);
4279 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4281 ir_node *src_block = get_nodes_block(node);
4282 ir_node *block = be_transform_node(src_block);
4283 ir_graph *irg = current_ir_graph;
4284 dbg_info *dbgi = get_irn_dbg_info(node);
4285 ir_node *frame = get_irg_frame(irg);
4286 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4287 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4288 ir_node *new_val_low = be_transform_node(val_low);
4289 ir_node *new_val_high = be_transform_node(val_high);
4291 ir_node *sync, *fild, *res;
4292 ir_node *store_low, *store_high;
4294 if (ia32_cg_config.use_sse2) {
4295 panic("ia32_l_LLtoFloat not implemented for SSE2");
4299 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4301 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg_GP, nomem,
4303 SET_IA32_ORIG_NODE(store_low, node);
4304 SET_IA32_ORIG_NODE(store_high, node);
4306 set_ia32_use_frame(store_low);
4307 set_ia32_use_frame(store_high);
4308 set_ia32_op_type(store_low, ia32_AddrModeD);
4309 set_ia32_op_type(store_high, ia32_AddrModeD);
4310 set_ia32_ls_mode(store_low, mode_Iu);
4311 set_ia32_ls_mode(store_high, mode_Is);
4312 add_ia32_am_offs_int(store_high, 4);
4316 sync = new_rd_Sync(dbgi, block, 2, in);
4319 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg_GP, sync);
4321 set_ia32_use_frame(fild);
4322 set_ia32_op_type(fild, ia32_AddrModeS);
4323 set_ia32_ls_mode(fild, mode_Ls);
4325 SET_IA32_ORIG_NODE(fild, node);
4327 res = new_r_Proj(fild, mode_vfp, pn_ia32_vfild_res);
4329 if (! mode_is_signed(get_irn_mode(val_high))) {
4330 ia32_address_mode_t am;
4332 ir_node *count = ia32_create_Immediate(NULL, 0, 31);
4335 am.addr.base = get_symconst_base();
4336 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4337 am.addr.mem = nomem;
4340 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4341 am.addr.use_frame = 0;
4342 am.addr.frame_entity = NULL;
4343 am.addr.symconst_sign = 0;
4344 am.ls_mode = mode_F;
4345 am.mem_proj = nomem;
4346 am.op_type = ia32_AddrModeS;
4348 am.new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
4349 am.pinned = op_pin_state_floats;
4351 am.ins_permuted = false;
4353 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4354 am.new_op1, am.new_op2, get_fpcw());
4355 set_am_attributes(fadd, &am);
4357 set_irn_mode(fadd, mode_T);
4358 res = new_rd_Proj(NULL, fadd, mode_vfp, pn_ia32_res);
4363 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4365 ir_node *src_block = get_nodes_block(node);
4366 ir_node *block = be_transform_node(src_block);
4367 ir_graph *irg = get_Block_irg(block);
4368 dbg_info *dbgi = get_irn_dbg_info(node);
4369 ir_node *frame = get_irg_frame(irg);
4370 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4371 ir_node *new_val = be_transform_node(val);
4372 ir_node *fist, *mem;
4374 mem = gen_vfist(dbgi, block, frame, noreg_GP, nomem, new_val, &fist);
4375 SET_IA32_ORIG_NODE(fist, node);
4376 set_ia32_use_frame(fist);
4377 set_ia32_op_type(fist, ia32_AddrModeD);
4378 set_ia32_ls_mode(fist, mode_Ls);
4383 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4385 ir_node *block = be_transform_node(get_nodes_block(node));
4386 ir_graph *irg = get_Block_irg(block);
4387 ir_node *pred = get_Proj_pred(node);
4388 ir_node *new_pred = be_transform_node(pred);
4389 ir_node *frame = get_irg_frame(irg);
4390 dbg_info *dbgi = get_irn_dbg_info(node);
4391 long pn = get_Proj_proj(node);
4396 load = new_bd_ia32_Load(dbgi, block, frame, noreg_GP, new_pred);
4397 SET_IA32_ORIG_NODE(load, node);
4398 set_ia32_use_frame(load);
4399 set_ia32_op_type(load, ia32_AddrModeS);
4400 set_ia32_ls_mode(load, mode_Iu);
4401 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4402 * 32 bit from it with this particular load */
4403 attr = get_ia32_attr(load);
4404 attr->data.need_64bit_stackent = 1;
4406 if (pn == pn_ia32_l_FloattoLL_res_high) {
4407 add_ia32_am_offs_int(load, 4);
4409 assert(pn == pn_ia32_l_FloattoLL_res_low);
4412 proj = new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4418 * Transform the Projs of an AddSP.
4420 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4422 ir_node *pred = get_Proj_pred(node);
4423 ir_node *new_pred = be_transform_node(pred);
4424 dbg_info *dbgi = get_irn_dbg_info(node);
4425 long proj = get_Proj_proj(node);
4427 if (proj == pn_be_AddSP_sp) {
4428 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4429 pn_ia32_SubSP_stack);
4430 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4432 } else if (proj == pn_be_AddSP_res) {
4433 return new_rd_Proj(dbgi, new_pred, mode_Iu,
4434 pn_ia32_SubSP_addr);
4435 } else if (proj == pn_be_AddSP_M) {
4436 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_SubSP_M);
4439 panic("No idea how to transform proj->AddSP");
4443 * Transform the Projs of a SubSP.
4445 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4447 ir_node *pred = get_Proj_pred(node);
4448 ir_node *new_pred = be_transform_node(pred);
4449 dbg_info *dbgi = get_irn_dbg_info(node);
4450 long proj = get_Proj_proj(node);
4452 if (proj == pn_be_SubSP_sp) {
4453 ir_node *res = new_rd_Proj(dbgi, new_pred, mode_Iu,
4454 pn_ia32_AddSP_stack);
4455 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
4457 } else if (proj == pn_be_SubSP_M) {
4458 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_AddSP_M);
4461 panic("No idea how to transform proj->SubSP");
4465 * Transform and renumber the Projs from a Load.
4467 static ir_node *gen_Proj_Load(ir_node *node)
4470 ir_node *block = be_transform_node(get_nodes_block(node));
4471 ir_node *pred = get_Proj_pred(node);
4472 dbg_info *dbgi = get_irn_dbg_info(node);
4473 long proj = get_Proj_proj(node);
4475 /* loads might be part of source address mode matches, so we don't
4476 * transform the ProjMs yet (with the exception of loads whose result is
4479 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4482 /* this is needed, because sometimes we have loops that are only
4483 reachable through the ProjM */
4484 be_enqueue_preds(node);
4485 /* do it in 2 steps, to silence firm verifier */
4486 res = new_rd_Proj(dbgi, pred, mode_M, pn_Load_M);
4487 set_Proj_proj(res, pn_ia32_mem);
4491 /* renumber the proj */
4492 new_pred = be_transform_node(pred);
4493 if (is_ia32_Load(new_pred)) {
4496 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Load_res);
4498 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Load_M);
4499 case pn_Load_X_regular:
4500 return new_rd_Jmp(dbgi, block);
4501 case pn_Load_X_except:
4502 /* This Load might raise an exception. Mark it. */
4503 set_ia32_exc_label(new_pred, 1);
4504 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Load_X_exc);
4508 } else if (is_ia32_Conv_I2I(new_pred) ||
4509 is_ia32_Conv_I2I8Bit(new_pred)) {
4510 set_irn_mode(new_pred, mode_T);
4511 if (proj == pn_Load_res) {
4512 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_res);
4513 } else if (proj == pn_Load_M) {
4514 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_mem);
4516 } else if (is_ia32_xLoad(new_pred)) {
4519 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xLoad_res);
4521 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xLoad_M);
4522 case pn_Load_X_regular:
4523 return new_rd_Jmp(dbgi, block);
4524 case pn_Load_X_except:
4525 /* This Load might raise an exception. Mark it. */
4526 set_ia32_exc_label(new_pred, 1);
4527 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4531 } else if (is_ia32_vfld(new_pred)) {
4534 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfld_res);
4536 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfld_M);
4537 case pn_Load_X_regular:
4538 return new_rd_Jmp(dbgi, block);
4539 case pn_Load_X_except:
4540 /* This Load might raise an exception. Mark it. */
4541 set_ia32_exc_label(new_pred, 1);
4542 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_vfld_X_exc);
4547 /* can happen for ProJMs when source address mode happened for the
4550 /* however it should not be the result proj, as that would mean the
4551 load had multiple users and should not have been used for
4553 if (proj != pn_Load_M) {
4554 panic("internal error: transformed node not a Load");
4556 return new_rd_Proj(dbgi, new_pred, mode_M, 1);
4559 panic("No idea how to transform proj");
4563 * Transform and renumber the Projs from a Div or Mod instruction.
4565 static ir_node *gen_Proj_Div(ir_node *node)
4567 ir_node *block = be_transform_node(get_nodes_block(node));
4568 ir_node *pred = get_Proj_pred(node);
4569 ir_node *new_pred = be_transform_node(pred);
4570 dbg_info *dbgi = get_irn_dbg_info(node);
4571 long proj = get_Proj_proj(node);
4573 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4574 assert(pn_ia32_Div_div_res == pn_ia32_IDiv_div_res);
4578 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4579 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4580 } else if (is_ia32_xDiv(new_pred)) {
4581 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_xDiv_M);
4582 } else if (is_ia32_vfdiv(new_pred)) {
4583 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_vfdiv_M);
4585 panic("Div transformed to unexpected thing %+F", new_pred);
4588 if (is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred)) {
4589 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_div_res);
4590 } else if (is_ia32_xDiv(new_pred)) {
4591 return new_rd_Proj(dbgi, new_pred, mode_xmm, pn_ia32_xDiv_res);
4592 } else if (is_ia32_vfdiv(new_pred)) {
4593 return new_rd_Proj(dbgi, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4595 panic("Div transformed to unexpected thing %+F", new_pred);
4597 case pn_Div_X_regular:
4598 return new_rd_Jmp(dbgi, block);
4599 case pn_Div_X_except:
4600 set_ia32_exc_label(new_pred, 1);
4601 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4606 panic("No idea how to transform proj->Div");
4610 * Transform and renumber the Projs from a Div or Mod instruction.
4612 static ir_node *gen_Proj_Mod(ir_node *node)
4614 ir_node *pred = get_Proj_pred(node);
4615 ir_node *new_pred = be_transform_node(pred);
4616 dbg_info *dbgi = get_irn_dbg_info(node);
4617 long proj = get_Proj_proj(node);
4619 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4620 assert(pn_ia32_Div_M == pn_ia32_IDiv_M);
4621 assert(pn_ia32_Div_mod_res == pn_ia32_IDiv_mod_res);
4625 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_Div_M);
4627 return new_rd_Proj(dbgi, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4628 case pn_Mod_X_except:
4629 set_ia32_exc_label(new_pred, 1);
4630 return new_rd_Proj(dbgi, new_pred, mode_X, pn_ia32_Div_X_exc);
4634 panic("No idea how to transform proj->Mod");
4638 * Transform and renumber the Projs from a CopyB.
4640 static ir_node *gen_Proj_CopyB(ir_node *node)
4642 ir_node *pred = get_Proj_pred(node);
4643 ir_node *new_pred = be_transform_node(pred);
4644 dbg_info *dbgi = get_irn_dbg_info(node);
4645 long proj = get_Proj_proj(node);
4649 if (is_ia32_CopyB_i(new_pred)) {
4650 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_i_M);
4651 } else if (is_ia32_CopyB(new_pred)) {
4652 return new_rd_Proj(dbgi, new_pred, mode_M, pn_ia32_CopyB_M);
4659 panic("No idea how to transform proj->CopyB");
4662 static ir_node *gen_be_Call(ir_node *node)
4664 dbg_info *const dbgi = get_irn_dbg_info(node);
4665 ir_node *const src_block = get_nodes_block(node);
4666 ir_node *const block = be_transform_node(src_block);
4667 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4668 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4669 ir_node *const sp = be_transform_node(src_sp);
4670 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4671 ia32_address_mode_t am;
4672 ia32_address_t *const addr = &am.addr;
4677 ir_node * eax = noreg_GP;
4678 ir_node * ecx = noreg_GP;
4679 ir_node * edx = noreg_GP;
4680 unsigned const pop = be_Call_get_pop(node);
4681 ir_type *const call_tp = be_Call_get_type(node);
4682 int old_no_pic_adjust;
4684 /* Run the x87 simulator if the call returns a float value */
4685 if (get_method_n_ress(call_tp) > 0) {
4686 ir_type *const res_type = get_method_res_type(call_tp, 0);
4687 ir_mode *const res_mode = get_type_mode(res_type);
4689 if (res_mode != NULL && mode_is_float(res_mode)) {
4690 ir_graph *irg = current_ir_graph;
4691 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
4692 irg_data->do_x87_sim = 1;
4696 /* We do not want be_Call direct calls */
4697 assert(be_Call_get_entity(node) == NULL);
4699 /* special case for PIC trampoline calls */
4700 old_no_pic_adjust = ia32_no_pic_adjust;
4701 ia32_no_pic_adjust = be_get_irg_options(current_ir_graph)->pic;
4703 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4704 match_am | match_immediate);
4706 ia32_no_pic_adjust = old_no_pic_adjust;
4708 i = get_irn_arity(node) - 1;
4709 fpcw = be_transform_node(get_irn_n(node, i--));
4710 for (; i >= be_pos_Call_first_arg; --i) {
4711 arch_register_req_t const *const req = arch_get_register_req(node, i);
4712 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4714 assert(req->type == arch_register_req_type_limited);
4715 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4717 switch (*req->limited) {
4718 case 1 << REG_GP_EAX: assert(eax == noreg_GP); eax = reg_parm; break;
4719 case 1 << REG_GP_ECX: assert(ecx == noreg_GP); ecx = reg_parm; break;
4720 case 1 << REG_GP_EDX: assert(edx == noreg_GP); edx = reg_parm; break;
4721 default: panic("Invalid GP register for register parameter");
4725 mem = transform_AM_mem(block, src_ptr, src_mem, addr->mem);
4726 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4727 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4728 set_am_attributes(call, &am);
4729 call = fix_mem_proj(call, &am);
4731 if (get_irn_pinned(node) == op_pin_state_pinned)
4732 set_irn_pinned(call, op_pin_state_pinned);
4734 SET_IA32_ORIG_NODE(call, node);
4736 if (ia32_cg_config.use_sse2) {
4737 /* remember this call for post-processing */
4738 ARR_APP1(ir_node *, call_list, call);
4739 ARR_APP1(ir_type *, call_types, be_Call_get_type(node));
4746 * Transform Builtin trap
4748 static ir_node *gen_trap(ir_node *node)
4750 dbg_info *dbgi = get_irn_dbg_info(node);
4751 ir_node *block = be_transform_node(get_nodes_block(node));
4752 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4754 return new_bd_ia32_UD2(dbgi, block, mem);
4758 * Transform Builtin debugbreak
4760 static ir_node *gen_debugbreak(ir_node *node)
4762 dbg_info *dbgi = get_irn_dbg_info(node);
4763 ir_node *block = be_transform_node(get_nodes_block(node));
4764 ir_node *mem = be_transform_node(get_Builtin_mem(node));
4766 return new_bd_ia32_Breakpoint(dbgi, block, mem);
4770 * Transform Builtin return_address
4772 static ir_node *gen_return_address(ir_node *node)
4774 ir_node *param = get_Builtin_param(node, 0);
4775 ir_node *frame = get_Builtin_param(node, 1);
4776 dbg_info *dbgi = get_irn_dbg_info(node);
4777 ir_tarval *tv = get_Const_tarval(param);
4778 unsigned long value = get_tarval_long(tv);
4780 ir_node *block = be_transform_node(get_nodes_block(node));
4781 ir_node *ptr = be_transform_node(frame);
4785 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4786 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4787 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4790 /* load the return address from this frame */
4791 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4793 set_irn_pinned(load, get_irn_pinned(node));
4794 set_ia32_op_type(load, ia32_AddrModeS);
4795 set_ia32_ls_mode(load, mode_Iu);
4797 set_ia32_am_offs_int(load, 0);
4798 set_ia32_use_frame(load);
4799 set_ia32_frame_ent(load, ia32_get_return_address_entity());
4801 if (get_irn_pinned(node) == op_pin_state_floats) {
4802 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4803 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4804 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4805 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4808 SET_IA32_ORIG_NODE(load, node);
4809 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4813 * Transform Builtin frame_address
4815 static ir_node *gen_frame_address(ir_node *node)
4817 ir_node *param = get_Builtin_param(node, 0);
4818 ir_node *frame = get_Builtin_param(node, 1);
4819 dbg_info *dbgi = get_irn_dbg_info(node);
4820 ir_tarval *tv = get_Const_tarval(param);
4821 unsigned long value = get_tarval_long(tv);
4823 ir_node *block = be_transform_node(get_nodes_block(node));
4824 ir_node *ptr = be_transform_node(frame);
4829 ir_node *cnt = new_bd_ia32_ProduceVal(dbgi, block);
4830 ir_node *res = new_bd_ia32_ProduceVal(dbgi, block);
4831 ptr = new_bd_ia32_ClimbFrame(dbgi, block, ptr, cnt, res, value);
4834 /* load the frame address from this frame */
4835 load = new_bd_ia32_Load(dbgi, block, ptr, noreg_GP, nomem);
4837 set_irn_pinned(load, get_irn_pinned(node));
4838 set_ia32_op_type(load, ia32_AddrModeS);
4839 set_ia32_ls_mode(load, mode_Iu);
4841 ent = ia32_get_frame_address_entity();
4843 set_ia32_am_offs_int(load, 0);
4844 set_ia32_use_frame(load);
4845 set_ia32_frame_ent(load, ent);
4847 /* will fail anyway, but gcc does this: */
4848 set_ia32_am_offs_int(load, 0);
4851 if (get_irn_pinned(node) == op_pin_state_floats) {
4852 assert((int)pn_ia32_xLoad_res == (int)pn_ia32_vfld_res
4853 && (int)pn_ia32_vfld_res == (int)pn_ia32_Load_res
4854 && (int)pn_ia32_Load_res == (int)pn_ia32_res);
4855 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
4858 SET_IA32_ORIG_NODE(load, node);
4859 return new_r_Proj(load, mode_Iu, pn_ia32_Load_res);
4863 * Transform Builtin frame_address
4865 static ir_node *gen_prefetch(ir_node *node)
4868 ir_node *ptr, *block, *mem, *base, *index;
4869 ir_node *param, *new_node;
4872 ia32_address_t addr;
4874 if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
4875 /* no prefetch at all, route memory */
4876 return be_transform_node(get_Builtin_mem(node));
4879 param = get_Builtin_param(node, 1);
4880 tv = get_Const_tarval(param);
4881 rw = get_tarval_long(tv);
4883 /* construct load address */
4884 memset(&addr, 0, sizeof(addr));
4885 ptr = get_Builtin_param(node, 0);
4886 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
4893 base = be_transform_node(base);
4896 if (index == NULL) {
4899 index = be_transform_node(index);
4902 dbgi = get_irn_dbg_info(node);
4903 block = be_transform_node(get_nodes_block(node));
4904 mem = be_transform_node(get_Builtin_mem(node));
4906 if (rw == 1 && ia32_cg_config.use_3dnow_prefetch) {
4907 /* we have 3DNow!, this was already checked above */
4908 new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
4909 } else if (ia32_cg_config.use_sse_prefetch) {
4910 /* note: rw == 1 is IGNORED in that case */
4911 param = get_Builtin_param(node, 2);
4912 tv = get_Const_tarval(param);
4913 locality = get_tarval_long(tv);
4915 /* SSE style prefetch */
4918 new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
4921 new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
4924 new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
4927 new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
4931 assert(ia32_cg_config.use_3dnow_prefetch);
4932 /* 3DNow! style prefetch */
4933 new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
4936 set_irn_pinned(new_node, get_irn_pinned(node));
4937 set_ia32_op_type(new_node, ia32_AddrModeS);
4938 set_ia32_ls_mode(new_node, mode_Bu);
4939 set_address(new_node, &addr);
4941 SET_IA32_ORIG_NODE(new_node, node);
4943 return new_r_Proj(new_node, mode_M, pn_ia32_Prefetch_M);
4947 * Transform bsf like node
4949 static ir_node *gen_unop_AM(ir_node *node, construct_binop_dest_func *func)
4951 ir_node *param = get_Builtin_param(node, 0);
4952 dbg_info *dbgi = get_irn_dbg_info(node);
4954 ir_node *block = get_nodes_block(node);
4955 ir_node *new_block = be_transform_node(block);
4957 ia32_address_mode_t am;
4958 ia32_address_t *addr = &am.addr;
4961 match_arguments(&am, block, NULL, param, NULL, match_am);
4963 cnt = func(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
4964 set_am_attributes(cnt, &am);
4965 set_ia32_ls_mode(cnt, get_irn_mode(param));
4967 SET_IA32_ORIG_NODE(cnt, node);
4968 return fix_mem_proj(cnt, &am);
4972 * Transform builtin ffs.
4974 static ir_node *gen_ffs(ir_node *node)
4976 ir_node *bsf = gen_unop_AM(node, new_bd_ia32_Bsf);
4977 ir_node *real = skip_Proj(bsf);
4978 dbg_info *dbgi = get_irn_dbg_info(real);
4979 ir_node *block = get_nodes_block(real);
4980 ir_node *flag, *set, *conv, *neg, *orn, *add;
4983 if (get_irn_mode(real) != mode_T) {
4984 set_irn_mode(real, mode_T);
4985 bsf = new_r_Proj(real, mode_Iu, pn_ia32_res);
4988 flag = new_r_Proj(real, mode_b, pn_ia32_flags);
4991 set = new_bd_ia32_Setcc(dbgi, block, flag, ia32_cc_equal);
4992 SET_IA32_ORIG_NODE(set, node);
4995 conv = new_bd_ia32_Conv_I2I8Bit(dbgi, block, noreg_GP, noreg_GP, nomem, set, mode_Bu);
4996 SET_IA32_ORIG_NODE(conv, node);
4999 neg = new_bd_ia32_Neg(dbgi, block, conv);
5002 orn = new_bd_ia32_Or(dbgi, block, noreg_GP, noreg_GP, nomem, bsf, neg);
5003 set_ia32_commutative(orn);
5006 add = new_bd_ia32_Lea(dbgi, block, orn, noreg_GP);
5007 add_ia32_am_offs_int(add, 1);
5012 * Transform builtin clz.
5014 static ir_node *gen_clz(ir_node *node)
5016 ir_node *bsr = gen_unop_AM(node, new_bd_ia32_Bsr);
5017 ir_node *real = skip_Proj(bsr);
5018 dbg_info *dbgi = get_irn_dbg_info(real);
5019 ir_node *block = get_nodes_block(real);
5020 ir_node *imm = ia32_create_Immediate(NULL, 0, 31);
5022 return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
5026 * Transform builtin ctz.
5028 static ir_node *gen_ctz(ir_node *node)
5030 return gen_unop_AM(node, new_bd_ia32_Bsf);
5034 * Transform builtin parity.
5036 static ir_node *gen_parity(ir_node *node)
5038 dbg_info *dbgi = get_irn_dbg_info(node);
5039 ir_node *block = get_nodes_block(node);
5040 ir_node *new_block = be_transform_node(block);
5041 ir_node *param = get_Builtin_param(node, 0);
5042 ir_node *new_param = be_transform_node(param);
5045 /* the x86 parity bit is stupid: it only looks at the lowest byte,
5046 * so we have to do complicated xoring first.
5047 * (we should also better lower this before the backend so we still have a
5048 * chance for CSE, constant folding and other goodies for some of these
5051 ir_node *count = ia32_create_Immediate(NULL, 0, 16);
5052 ir_node *shr = new_bd_ia32_Shr(dbgi, new_block, new_param, count);
5053 ir_node *xor = new_bd_ia32_Xor(dbgi, new_block, noreg_GP, noreg_GP, nomem,
5055 ir_node *xor2 = new_bd_ia32_XorHighLow(dbgi, new_block, xor);
5058 set_irn_mode(xor2, mode_T);
5059 flags = new_r_Proj(xor2, mode_Iu, pn_ia32_XorHighLow_flags);
5062 new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, ia32_cc_not_parity);
5063 SET_IA32_ORIG_NODE(new_node, node);
5066 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg_GP, noreg_GP,
5067 nomem, new_node, mode_Bu);
5068 SET_IA32_ORIG_NODE(new_node, node);
5073 * Transform builtin popcount
5075 static ir_node *gen_popcount(ir_node *node)
5077 ir_node *param = get_Builtin_param(node, 0);
5078 dbg_info *dbgi = get_irn_dbg_info(node);
5080 ir_node *block = get_nodes_block(node);
5081 ir_node *new_block = be_transform_node(block);
5084 ir_node *imm, *simm, *m1, *s1, *s2, *s3, *s4, *s5, *m2, *m3, *m4, *m5, *m6, *m7, *m8, *m9, *m10, *m11, *m12, *m13;
5086 /* check for SSE4.2 or SSE4a and use the popcnt instruction */
5087 if (ia32_cg_config.use_popcnt) {
5088 ia32_address_mode_t am;
5089 ia32_address_t *addr = &am.addr;
5092 match_arguments(&am, block, NULL, param, NULL, match_am | match_16bit_am);
5094 cnt = new_bd_ia32_Popcnt(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op2);
5095 set_am_attributes(cnt, &am);
5096 set_ia32_ls_mode(cnt, get_irn_mode(param));
5098 SET_IA32_ORIG_NODE(cnt, node);
5099 return fix_mem_proj(cnt, &am);
5102 new_param = be_transform_node(param);
5104 /* do the standard popcount algo */
5105 /* TODO: This is stupid, we should transform this before the backend,
5106 * to get CSE, localopts, etc. for the operations
5107 * TODO: This is also not the optimal algorithm (it is just the starting
5108 * example in hackers delight, they optimize it more on the following page)
5109 * But I'm too lazy to fix this now, as the code should get lowered before
5110 * the backend anyway.
5113 /* m1 = x & 0x55555555 */
5114 imm = ia32_create_Immediate(NULL, 0, 0x55555555);
5115 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
5118 simm = ia32_create_Immediate(NULL, 0, 1);
5119 s1 = new_bd_ia32_Shr(dbgi, new_block, new_param, simm);
5121 /* m2 = s1 & 0x55555555 */
5122 m2 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s1, imm);
5125 m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
5127 /* m4 = m3 & 0x33333333 */
5128 imm = ia32_create_Immediate(NULL, 0, 0x33333333);
5129 m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
5132 simm = ia32_create_Immediate(NULL, 0, 2);
5133 s2 = new_bd_ia32_Shr(dbgi, new_block, m3, simm);
5135 /* m5 = s2 & 0x33333333 */
5136 m5 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, imm);
5139 m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
5141 /* m7 = m6 & 0x0F0F0F0F */
5142 imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
5143 m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
5146 simm = ia32_create_Immediate(NULL, 0, 4);
5147 s3 = new_bd_ia32_Shr(dbgi, new_block, m6, simm);
5149 /* m8 = s3 & 0x0F0F0F0F */
5150 m8 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, imm);
5153 m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
5155 /* m10 = m9 & 0x00FF00FF */
5156 imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
5157 m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
5160 simm = ia32_create_Immediate(NULL, 0, 8);
5161 s4 = new_bd_ia32_Shr(dbgi, new_block, m9, simm);
5163 /* m11 = s4 & 0x00FF00FF */
5164 m11 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s4, imm);
5166 /* m12 = m10 + m11 */
5167 m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
5169 /* m13 = m12 & 0x0000FFFF */
5170 imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
5171 m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
5173 /* s5 = m12 >> 16 */
5174 simm = ia32_create_Immediate(NULL, 0, 16);
5175 s5 = new_bd_ia32_Shr(dbgi, new_block, m12, simm);
5177 /* res = m13 + s5 */
5178 return new_bd_ia32_Lea(dbgi, new_block, m13, s5);
5182 * Transform builtin byte swap.
5184 static ir_node *gen_bswap(ir_node *node)
5186 ir_node *param = be_transform_node(get_Builtin_param(node, 0));
5187 dbg_info *dbgi = get_irn_dbg_info(node);
5189 ir_node *block = get_nodes_block(node);
5190 ir_node *new_block = be_transform_node(block);
5191 ir_mode *mode = get_irn_mode(param);
5192 unsigned size = get_mode_size_bits(mode);
5193 ir_node *m1, *m2, *m3, *m4, *s1, *s2, *s3, *s4;
5197 if (ia32_cg_config.use_i486) {
5198 /* swap available */
5199 return new_bd_ia32_Bswap(dbgi, new_block, param);
5201 s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5202 s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5204 m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
5205 m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
5207 s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
5209 m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
5210 m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
5212 s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
5213 return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
5216 /* swap16 always available */
5217 return new_bd_ia32_Bswap16(dbgi, new_block, param);
5220 panic("Invalid bswap size (%d)", size);
5225 * Transform builtin outport.
5227 static ir_node *gen_outport(ir_node *node)
5229 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5230 ir_node *oldv = get_Builtin_param(node, 1);
5231 ir_mode *mode = get_irn_mode(oldv);
5232 ir_node *value = be_transform_node(oldv);
5233 ir_node *block = be_transform_node(get_nodes_block(node));
5234 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5235 dbg_info *dbgi = get_irn_dbg_info(node);
5237 ir_node *res = new_bd_ia32_Outport(dbgi, block, port, value, mem);
5238 set_ia32_ls_mode(res, mode);
5243 * Transform builtin inport.
5245 static ir_node *gen_inport(ir_node *node)
5247 ir_type *tp = get_Builtin_type(node);
5248 ir_type *rstp = get_method_res_type(tp, 0);
5249 ir_mode *mode = get_type_mode(rstp);
5250 ir_node *port = create_immediate_or_transform(get_Builtin_param(node, 0), 0);
5251 ir_node *block = be_transform_node(get_nodes_block(node));
5252 ir_node *mem = be_transform_node(get_Builtin_mem(node));
5253 dbg_info *dbgi = get_irn_dbg_info(node);
5255 ir_node *res = new_bd_ia32_Inport(dbgi, block, port, mem);
5256 set_ia32_ls_mode(res, mode);
5258 /* check for missing Result Proj */
5263 * Transform a builtin inner trampoline
5265 static ir_node *gen_inner_trampoline(ir_node *node)
5267 ir_node *ptr = get_Builtin_param(node, 0);
5268 ir_node *callee = get_Builtin_param(node, 1);
5269 ir_node *env = be_transform_node(get_Builtin_param(node, 2));
5270 ir_node *mem = get_Builtin_mem(node);
5271 ir_node *block = get_nodes_block(node);
5272 ir_node *new_block = be_transform_node(block);
5276 ir_node *trampoline;
5278 dbg_info *dbgi = get_irn_dbg_info(node);
5279 ia32_address_t addr;
5281 /* construct store address */
5282 memset(&addr, 0, sizeof(addr));
5283 ia32_create_address_mode(&addr, ptr, ia32_create_am_normal);
5285 if (addr.base == NULL) {
5286 addr.base = noreg_GP;
5288 addr.base = be_transform_node(addr.base);
5291 if (addr.index == NULL) {
5292 addr.index = noreg_GP;
5294 addr.index = be_transform_node(addr.index);
5296 addr.mem = be_transform_node(mem);
5298 /* mov ecx, <env> */
5299 val = ia32_create_Immediate(NULL, 0, 0xB9);
5300 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5301 addr.index, addr.mem, val);
5302 set_irn_pinned(store, get_irn_pinned(node));
5303 set_ia32_op_type(store, ia32_AddrModeD);
5304 set_ia32_ls_mode(store, mode_Bu);
5305 set_address(store, &addr);
5309 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5310 addr.index, addr.mem, env);
5311 set_irn_pinned(store, get_irn_pinned(node));
5312 set_ia32_op_type(store, ia32_AddrModeD);
5313 set_ia32_ls_mode(store, mode_Iu);
5314 set_address(store, &addr);
5318 /* jmp rel <callee> */
5319 val = ia32_create_Immediate(NULL, 0, 0xE9);
5320 store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
5321 addr.index, addr.mem, val);
5322 set_irn_pinned(store, get_irn_pinned(node));
5323 set_ia32_op_type(store, ia32_AddrModeD);
5324 set_ia32_ls_mode(store, mode_Bu);
5325 set_address(store, &addr);
5329 trampoline = be_transform_node(ptr);
5331 /* the callee is typically an immediate */
5332 if (is_SymConst(callee)) {
5333 rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, 0, -10);
5335 rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), noreg_GP);
5336 add_ia32_am_offs_int(rel, -10);
5338 rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
5340 store = new_bd_ia32_Store(dbgi, new_block, addr.base,
5341 addr.index, addr.mem, rel);
5342 set_irn_pinned(store, get_irn_pinned(node));
5343 set_ia32_op_type(store, ia32_AddrModeD);
5344 set_ia32_ls_mode(store, mode_Iu);
5345 set_address(store, &addr);
5350 return new_r_Tuple(new_block, 2, in);
5354 * Transform Builtin node.
5356 static ir_node *gen_Builtin(ir_node *node)
5358 ir_builtin_kind kind = get_Builtin_kind(node);
5362 return gen_trap(node);
5363 case ir_bk_debugbreak:
5364 return gen_debugbreak(node);
5365 case ir_bk_return_address:
5366 return gen_return_address(node);
5367 case ir_bk_frame_address:
5368 return gen_frame_address(node);
5369 case ir_bk_prefetch:
5370 return gen_prefetch(node);
5372 return gen_ffs(node);
5374 return gen_clz(node);
5376 return gen_ctz(node);
5378 return gen_parity(node);
5379 case ir_bk_popcount:
5380 return gen_popcount(node);
5382 return gen_bswap(node);
5384 return gen_outport(node);
5386 return gen_inport(node);
5387 case ir_bk_inner_trampoline:
5388 return gen_inner_trampoline(node);
5390 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5394 * Transform Proj(Builtin) node.
5396 static ir_node *gen_Proj_Builtin(ir_node *proj)
5398 ir_node *node = get_Proj_pred(proj);
5399 ir_node *new_node = be_transform_node(node);
5400 ir_builtin_kind kind = get_Builtin_kind(node);
5403 case ir_bk_return_address:
5404 case ir_bk_frame_address:
5409 case ir_bk_popcount:
5411 assert(get_Proj_proj(proj) == pn_Builtin_1_result);
5414 case ir_bk_debugbreak:
5415 case ir_bk_prefetch:
5417 assert(get_Proj_proj(proj) == pn_Builtin_M);
5420 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5421 return new_r_Proj(new_node, get_irn_mode(proj), pn_ia32_Inport_res);
5423 assert(get_Proj_proj(proj) == pn_Builtin_M);
5424 return new_r_Proj(new_node, mode_M, pn_ia32_Inport_M);
5426 case ir_bk_inner_trampoline:
5427 if (get_Proj_proj(proj) == pn_Builtin_1_result) {
5428 return get_Tuple_pred(new_node, 1);
5430 assert(get_Proj_proj(proj) == pn_Builtin_M);
5431 return get_Tuple_pred(new_node, 0);
5434 panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
5437 static ir_node *gen_be_IncSP(ir_node *node)
5439 ir_node *res = be_duplicate_node(node);
5440 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
5446 * Transform the Projs from a be_Call.
5448 static ir_node *gen_Proj_be_Call(ir_node *node)
5450 ir_node *call = get_Proj_pred(node);
5451 ir_node *new_call = be_transform_node(call);
5452 dbg_info *dbgi = get_irn_dbg_info(node);
5453 long proj = get_Proj_proj(node);
5454 ir_mode *mode = get_irn_mode(node);
5457 if (proj == pn_be_Call_M_regular) {
5458 return new_rd_Proj(dbgi, new_call, mode_M, n_ia32_Call_mem);
5460 /* transform call modes */
5461 if (mode_is_data(mode)) {
5462 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
5466 /* Map from be_Call to ia32_Call proj number */
5467 if (proj == pn_be_Call_sp) {
5468 proj = pn_ia32_Call_stack;
5469 } else if (proj == pn_be_Call_M_regular) {
5470 proj = pn_ia32_Call_M;
5472 arch_register_req_t const *const req = arch_get_register_req_out(node);
5473 int const n_outs = arch_irn_get_n_outs(new_call);
5476 assert(proj >= pn_be_Call_first_res);
5477 assert(req->type & arch_register_req_type_limited);
5479 for (i = 0; i < n_outs; ++i) {
5480 arch_register_req_t const *const new_req
5481 = arch_get_out_register_req(new_call, i);
5483 if (!(new_req->type & arch_register_req_type_limited) ||
5484 new_req->cls != req->cls ||
5485 *new_req->limited != *req->limited)
5494 res = new_rd_Proj(dbgi, new_call, mode, proj);
5496 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
5498 case pn_ia32_Call_stack:
5499 arch_set_irn_register(res, &ia32_registers[REG_ESP]);
5502 case pn_ia32_Call_fpcw:
5503 arch_set_irn_register(res, &ia32_registers[REG_FPCW]);
5511 * Transform the Projs from a Cmp.
5513 static ir_node *gen_Proj_Cmp(ir_node *node)
5515 /* this probably means not all mode_b nodes were lowered... */
5516 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5520 static ir_node *gen_Proj_ASM(ir_node *node)
5522 ir_mode *mode = get_irn_mode(node);
5523 ir_node *pred = get_Proj_pred(node);
5524 ir_node *new_pred = be_transform_node(pred);
5525 long pos = get_Proj_proj(node);
5527 if (mode == mode_M) {
5528 pos = arch_irn_get_n_outs(new_pred)-1;
5529 } else if (mode_is_int(mode) || mode_is_reference(mode)) {
5531 } else if (mode_is_float(mode)) {
5534 panic("unexpected proj mode at ASM");
5537 return new_r_Proj(new_pred, mode, pos);
5541 * Transform and potentially renumber Proj nodes.
5543 static ir_node *gen_Proj(ir_node *node)
5545 ir_node *pred = get_Proj_pred(node);
5548 switch (get_irn_opcode(pred)) {
5550 proj = get_Proj_proj(node);
5551 if (proj == pn_Store_M) {
5552 return be_transform_node(pred);
5554 panic("No idea how to transform proj->Store");
5557 return gen_Proj_Load(node);
5559 return gen_Proj_ASM(node);
5561 return gen_Proj_Builtin(node);
5563 return gen_Proj_Div(node);
5565 return gen_Proj_Mod(node);
5567 return gen_Proj_CopyB(node);
5569 return gen_Proj_be_SubSP(node);
5571 return gen_Proj_be_AddSP(node);
5573 return gen_Proj_be_Call(node);
5575 return gen_Proj_Cmp(node);
5577 proj = get_Proj_proj(node);
5579 case pn_Start_X_initial_exec: {
5580 ir_node *block = get_nodes_block(pred);
5581 ir_node *new_block = be_transform_node(block);
5582 dbg_info *dbgi = get_irn_dbg_info(node);
5583 /* we exchange the ProjX with a jump */
5584 ir_node *jump = new_rd_Jmp(dbgi, new_block);
5589 case pn_Start_P_tls:
5590 return ia32_gen_Proj_tls(node);
5595 if (is_ia32_l_FloattoLL(pred)) {
5596 return gen_Proj_l_FloattoLL(node);
5598 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5602 ir_mode *mode = get_irn_mode(node);
5603 if (ia32_mode_needs_gp_reg(mode)) {
5604 ir_node *new_pred = be_transform_node(pred);
5605 ir_node *new_proj = new_r_Proj(new_pred, mode_Iu,
5606 get_Proj_proj(node));
5607 new_proj->node_nr = node->node_nr;
5612 return be_duplicate_node(node);
5616 * Enters all transform functions into the generic pointer
5618 static void register_transformers(void)
5620 /* first clear the generic function pointer for all ops */
5621 be_start_transform_setup();
5623 be_set_transform_function(op_Add, gen_Add);
5624 be_set_transform_function(op_And, gen_And);
5625 be_set_transform_function(op_ASM, ia32_gen_ASM);
5626 be_set_transform_function(op_be_AddSP, gen_be_AddSP);
5627 be_set_transform_function(op_be_Call, gen_be_Call);
5628 be_set_transform_function(op_be_Copy, gen_be_Copy);
5629 be_set_transform_function(op_be_FrameAddr, gen_be_FrameAddr);
5630 be_set_transform_function(op_be_IncSP, gen_be_IncSP);
5631 be_set_transform_function(op_be_Return, gen_be_Return);
5632 be_set_transform_function(op_be_SubSP, gen_be_SubSP);
5633 be_set_transform_function(op_Builtin, gen_Builtin);
5634 be_set_transform_function(op_Cmp, gen_Cmp);
5635 be_set_transform_function(op_Cond, gen_Cond);
5636 be_set_transform_function(op_Const, gen_Const);
5637 be_set_transform_function(op_Conv, gen_Conv);
5638 be_set_transform_function(op_CopyB, ia32_gen_CopyB);
5639 be_set_transform_function(op_Div, gen_Div);
5640 be_set_transform_function(op_Eor, gen_Eor);
5641 be_set_transform_function(op_ia32_l_Adc, gen_ia32_l_Adc);
5642 be_set_transform_function(op_ia32_l_Add, gen_ia32_l_Add);
5643 be_set_transform_function(op_ia32_Leave, be_duplicate_node);
5644 be_set_transform_function(op_ia32_l_FloattoLL, gen_ia32_l_FloattoLL);
5645 be_set_transform_function(op_ia32_l_IMul, gen_ia32_l_IMul);
5646 be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
5647 be_set_transform_function(op_ia32_l_Mul, gen_ia32_l_Mul);
5648 be_set_transform_function(op_ia32_l_SarDep, gen_ia32_l_SarDep);
5649 be_set_transform_function(op_ia32_l_Sbb, gen_ia32_l_Sbb);
5650 be_set_transform_function(op_ia32_l_ShlDep, gen_ia32_l_ShlDep);
5651 be_set_transform_function(op_ia32_l_ShlD, gen_ia32_l_ShlD);
5652 be_set_transform_function(op_ia32_l_ShrDep, gen_ia32_l_ShrDep);
5653 be_set_transform_function(op_ia32_l_ShrD, gen_ia32_l_ShrD);
5654 be_set_transform_function(op_ia32_l_Sub, gen_ia32_l_Sub);
5655 be_set_transform_function(op_ia32_GetEIP, be_duplicate_node);
5656 be_set_transform_function(op_ia32_Minus64Bit, be_duplicate_node);
5657 be_set_transform_function(op_ia32_NoReg_GP, be_duplicate_node);
5658 be_set_transform_function(op_ia32_NoReg_VFP, be_duplicate_node);
5659 be_set_transform_function(op_ia32_NoReg_XMM, be_duplicate_node);
5660 be_set_transform_function(op_ia32_PopEbp, be_duplicate_node);
5661 be_set_transform_function(op_ia32_Push, be_duplicate_node);
5662 be_set_transform_function(op_IJmp, gen_IJmp);
5663 be_set_transform_function(op_Jmp, gen_Jmp);
5664 be_set_transform_function(op_Load, gen_Load);
5665 be_set_transform_function(op_Minus, gen_Minus);
5666 be_set_transform_function(op_Mod, gen_Mod);
5667 be_set_transform_function(op_Mul, gen_Mul);
5668 be_set_transform_function(op_Mulh, gen_Mulh);
5669 be_set_transform_function(op_Mux, gen_Mux);
5670 be_set_transform_function(op_Not, gen_Not);
5671 be_set_transform_function(op_Or, gen_Or);
5672 be_set_transform_function(op_Phi, gen_Phi);
5673 be_set_transform_function(op_Proj, gen_Proj);
5674 be_set_transform_function(op_Rotl, gen_Rotl);
5675 be_set_transform_function(op_Shl, gen_Shl);
5676 be_set_transform_function(op_Shr, gen_Shr);
5677 be_set_transform_function(op_Shrs, gen_Shrs);
5678 be_set_transform_function(op_Store, gen_Store);
5679 be_set_transform_function(op_Sub, gen_Sub);
5680 be_set_transform_function(op_SymConst, gen_SymConst);
5681 be_set_transform_function(op_Unknown, ia32_gen_Unknown);
5685 * Pre-transform all unknown and noreg nodes.
5687 static void ia32_pretransform_node(void)
5689 ir_graph *irg = current_ir_graph;
5690 ia32_irg_data_t *irg_data = ia32_get_irg_data(current_ir_graph);
5692 irg_data->noreg_gp = be_pre_transform_node(irg_data->noreg_gp);
5693 irg_data->noreg_vfp = be_pre_transform_node(irg_data->noreg_vfp);
5694 irg_data->noreg_xmm = be_pre_transform_node(irg_data->noreg_xmm);
5695 irg_data->get_eip = be_pre_transform_node(irg_data->get_eip);
5696 irg_data->fpu_trunc_mode = be_pre_transform_node(irg_data->fpu_trunc_mode);
5698 nomem = get_irg_no_mem(irg);
5699 noreg_GP = ia32_new_NoReg_gp(irg);
5705 * Post-process all calls if we are in SSE mode.
5706 * The ABI requires that the results are in st0, copy them
5707 * to a xmm register.
5709 static void postprocess_fp_call_results(void)
5713 for (i = 0, n = ARR_LEN(call_list); i < n; ++i) {
5714 ir_node *call = call_list[i];
5715 ir_type *mtp = call_types[i];
5718 for (j = get_method_n_ress(mtp) - 1; j >= 0; --j) {
5719 ir_type *res_tp = get_method_res_type(mtp, j);
5720 ir_node *res, *new_res;
5721 const ir_edge_t *edge, *next;
5724 if (! is_atomic_type(res_tp)) {
5725 /* no floating point return */
5728 mode = get_type_mode(res_tp);
5729 if (! mode_is_float(mode)) {
5730 /* no floating point return */
5734 res = be_get_Proj_for_pn(call, pn_ia32_Call_vf0 + j);
5737 /* now patch the users */
5738 foreach_out_edge_safe(res, edge, next) {
5739 ir_node *succ = get_edge_src_irn(edge);
5742 if (be_is_Keep(succ))
5745 if (is_ia32_xStore(succ)) {
5746 /* an xStore can be patched into an vfst */
5747 dbg_info *db = get_irn_dbg_info(succ);
5748 ir_node *block = get_nodes_block(succ);
5749 ir_node *base = get_irn_n(succ, n_ia32_xStore_base);
5750 ir_node *index = get_irn_n(succ, n_ia32_xStore_index);
5751 ir_node *mem = get_irn_n(succ, n_ia32_xStore_mem);
5752 ir_node *value = get_irn_n(succ, n_ia32_xStore_val);
5753 ir_mode *mode = get_ia32_ls_mode(succ);
5755 ir_node *st = new_bd_ia32_vfst(db, block, base, index, mem, value, mode);
5756 set_ia32_am_offs_int(st, get_ia32_am_offs_int(succ));
5757 if (is_ia32_use_frame(succ))
5758 set_ia32_use_frame(st);
5759 set_ia32_frame_ent(st, get_ia32_frame_ent(succ));
5760 set_irn_pinned(st, get_irn_pinned(succ));
5761 set_ia32_op_type(st, ia32_AddrModeD);
5765 if (new_res == NULL) {
5766 dbg_info *db = get_irn_dbg_info(call);
5767 ir_node *block = get_nodes_block(call);
5768 ir_node *frame = get_irg_frame(current_ir_graph);
5769 ir_node *old_mem = be_get_Proj_for_pn(call, pn_ia32_Call_M);
5770 ir_node *call_mem = new_r_Proj(call, mode_M, pn_ia32_Call_M);
5771 ir_node *vfst, *xld, *new_mem;
5773 /* store st(0) on stack */
5774 vfst = new_bd_ia32_vfst(db, block, frame, noreg_GP, call_mem, res, mode);
5775 set_ia32_op_type(vfst, ia32_AddrModeD);
5776 set_ia32_use_frame(vfst);
5778 /* load into SSE register */
5779 xld = new_bd_ia32_xLoad(db, block, frame, noreg_GP, vfst, mode);
5780 set_ia32_op_type(xld, ia32_AddrModeS);
5781 set_ia32_use_frame(xld);
5783 new_res = new_r_Proj(xld, mode, pn_ia32_xLoad_res);
5784 new_mem = new_r_Proj(xld, mode_M, pn_ia32_xLoad_M);
5786 if (old_mem != NULL) {
5787 edges_reroute(old_mem, new_mem, current_ir_graph);
5791 set_irn_n(succ, get_edge_src_pos(edge), new_res);
5798 /* do the transformation */
5799 void ia32_transform_graph(ir_graph *irg)
5803 register_transformers();
5804 initial_fpcw = NULL;
5805 ia32_no_pic_adjust = 0;
5807 be_timer_push(T_HEIGHTS);
5808 ia32_heights = heights_new(irg);
5809 be_timer_pop(T_HEIGHTS);
5810 ia32_calculate_non_address_mode_nodes(irg);
5812 /* the transform phase is not safe for CSE (yet) because several nodes get
5813 * attributes set after their creation */
5814 cse_last = get_opt_cse();
5817 call_list = NEW_ARR_F(ir_node *, 0);
5818 call_types = NEW_ARR_F(ir_type *, 0);
5819 be_transform_graph(irg, ia32_pretransform_node);
5821 if (ia32_cg_config.use_sse2)
5822 postprocess_fp_call_results();
5823 DEL_ARR_F(call_types);
5824 DEL_ARR_F(call_list);
5826 set_opt_cse(cse_last);
5828 ia32_free_non_address_mode_nodes();
5829 heights_free(ia32_heights);
5830 ia32_heights = NULL;
5833 void ia32_init_transform(void)
5835 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");