2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief This file implements the IR transformation from firm into
24 * @author Christian Wuerdig, Matthias Braun
34 #include "irgraph_t.h"
39 #include "iredges_t.h"
51 #include "../benode_t.h"
52 #include "../besched.h"
54 #include "../beutil.h"
55 #include "../beirg_t.h"
56 #include "../betranshlp.h"
59 #include "bearch_ia32_t.h"
60 #include "ia32_common_transform.h"
61 #include "ia32_nodes_attr.h"
62 #include "ia32_transform.h"
63 #include "ia32_new_nodes.h"
64 #include "ia32_map_regs.h"
65 #include "ia32_dbg_stat.h"
66 #include "ia32_optimize.h"
67 #include "ia32_util.h"
68 #include "ia32_address_mode.h"
69 #include "ia32_architecture.h"
71 #include "gen_ia32_regalloc_if.h"
73 #define SFP_SIGN "0x80000000"
74 #define DFP_SIGN "0x8000000000000000"
75 #define SFP_ABS "0x7FFFFFFF"
76 #define DFP_ABS "0x7FFFFFFFFFFFFFFF"
77 #define DFP_INTMAX "9223372036854775807"
78 #define ULL_BIAS "18446744073709551616"
80 #define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
81 #define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
82 #define ENT_SFP_ABS ".LC_ia32_sfp_abs"
83 #define ENT_DFP_ABS ".LC_ia32_dfp_abs"
84 #define ENT_ULL_BIAS ".LC_ia32_ull_bias"
86 #define mode_vfp (ia32_reg_classes[CLASS_ia32_vfp].mode)
87 #define mode_xmm (ia32_reg_classes[CLASS_ia32_xmm].mode)
89 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
91 static ir_node *initial_fpcw = NULL;
93 extern ir_op *get_op_Mulh(void);
95 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
96 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
99 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
100 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
103 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
104 ir_node *op1, ir_node *op2);
106 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
107 ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
109 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
110 ir_node *base, ir_node *index, ir_node *mem);
112 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
113 ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
116 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
118 static ir_node *create_immediate_or_transform(ir_node *node,
119 char immediate_constraint_type);
121 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
122 dbg_info *dbgi, ir_node *block,
123 ir_node *op, ir_node *orig_node);
125 /** Return non-zero is a node represents the 0 constant. */
126 static bool is_Const_0(ir_node *node)
128 return is_Const(node) && is_Const_null(node);
131 /** Return non-zero is a node represents the 1 constant. */
132 static bool is_Const_1(ir_node *node)
134 return is_Const(node) && is_Const_one(node);
137 /** Return non-zero is a node represents the -1 constant. */
138 static bool is_Const_Minus_1(ir_node *node)
140 return is_Const(node) && is_Const_all_one(node);
144 * returns true if constant can be created with a simple float command
146 static bool is_simple_x87_Const(ir_node *node)
148 tarval *tv = get_Const_tarval(node);
149 if (tarval_is_null(tv) || tarval_is_one(tv))
152 /* TODO: match all the other float constants */
157 * returns true if constant can be created with a simple float command
159 static bool is_simple_sse_Const(ir_node *node)
161 tarval *tv = get_Const_tarval(node);
162 ir_mode *mode = get_tarval_mode(tv);
167 if (tarval_is_null(tv) || tarval_is_one(tv))
170 if (mode == mode_D) {
171 unsigned val = get_tarval_sub_bits(tv, 0) |
172 (get_tarval_sub_bits(tv, 1) << 8) |
173 (get_tarval_sub_bits(tv, 2) << 16) |
174 (get_tarval_sub_bits(tv, 3) << 24);
176 /* lower 32bit are zero, really a 32bit constant */
180 /* TODO: match all the other float constants */
185 * Transforms a Const.
187 static ir_node *gen_Const(ir_node *node)
189 ir_node *old_block = get_nodes_block(node);
190 ir_node *block = be_transform_node(old_block);
191 dbg_info *dbgi = get_irn_dbg_info(node);
192 ir_mode *mode = get_irn_mode(node);
194 assert(is_Const(node));
196 if (mode_is_float(mode)) {
198 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
199 ir_node *nomem = new_NoMem();
203 if (ia32_cg_config.use_sse2) {
204 tarval *tv = get_Const_tarval(node);
205 if (tarval_is_null(tv)) {
206 load = new_bd_ia32_xZero(dbgi, block);
207 set_ia32_ls_mode(load, mode);
209 } else if (tarval_is_one(tv)) {
210 int cnst = mode == mode_F ? 26 : 55;
211 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
212 ir_node *imm2 = create_Immediate(NULL, 0, 2);
213 ir_node *pslld, *psrld;
215 load = new_bd_ia32_xAllOnes(dbgi, block);
216 set_ia32_ls_mode(load, mode);
217 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
218 set_ia32_ls_mode(pslld, mode);
219 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
220 set_ia32_ls_mode(psrld, mode);
222 } else if (mode == mode_F) {
223 /* we can place any 32bit constant by using a movd gp, sse */
224 unsigned val = get_tarval_sub_bits(tv, 0) |
225 (get_tarval_sub_bits(tv, 1) << 8) |
226 (get_tarval_sub_bits(tv, 2) << 16) |
227 (get_tarval_sub_bits(tv, 3) << 24);
228 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
229 load = new_bd_ia32_xMovd(dbgi, block, cnst);
230 set_ia32_ls_mode(load, mode);
233 if (mode == mode_D) {
234 unsigned val = get_tarval_sub_bits(tv, 0) |
235 (get_tarval_sub_bits(tv, 1) << 8) |
236 (get_tarval_sub_bits(tv, 2) << 16) |
237 (get_tarval_sub_bits(tv, 3) << 24);
239 ir_node *imm32 = create_Immediate(NULL, 0, 32);
240 ir_node *cnst, *psllq;
242 /* fine, lower 32bit are zero, produce 32bit value */
243 val = get_tarval_sub_bits(tv, 4) |
244 (get_tarval_sub_bits(tv, 5) << 8) |
245 (get_tarval_sub_bits(tv, 6) << 16) |
246 (get_tarval_sub_bits(tv, 7) << 24);
247 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
248 load = new_bd_ia32_xMovd(dbgi, block, cnst);
249 set_ia32_ls_mode(load, mode);
250 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
251 set_ia32_ls_mode(psllq, mode);
256 floatent = create_float_const_entity(node);
258 load = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem,
260 set_ia32_op_type(load, ia32_AddrModeS);
261 set_ia32_am_sc(load, floatent);
262 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
263 res = new_r_Proj(current_ir_graph, block, load, mode_xmm, pn_ia32_xLoad_res);
266 if (is_Const_null(node)) {
267 load = new_bd_ia32_vfldz(dbgi, block);
269 set_ia32_ls_mode(load, mode);
270 } else if (is_Const_one(node)) {
271 load = new_bd_ia32_vfld1(dbgi, block);
273 set_ia32_ls_mode(load, mode);
275 floatent = create_float_const_entity(node);
277 load = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode);
278 set_ia32_op_type(load, ia32_AddrModeS);
279 set_ia32_am_sc(load, floatent);
280 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
281 res = new_r_Proj(current_ir_graph, block, load, mode_vfp, pn_ia32_vfld_res);
282 /* take the mode from the entity */
283 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
287 SET_IA32_ORIG_NODE(load, node);
289 be_dep_on_frame(load);
291 } else { /* non-float mode */
293 tarval *tv = get_Const_tarval(node);
296 tv = tarval_convert_to(tv, mode_Iu);
298 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
300 panic("couldn't convert constant tarval (%+F)", node);
302 val = get_tarval_long(tv);
304 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
305 SET_IA32_ORIG_NODE(cnst, node);
307 be_dep_on_frame(cnst);
313 * Transforms a SymConst.
315 static ir_node *gen_SymConst(ir_node *node)
317 ir_node *old_block = get_nodes_block(node);
318 ir_node *block = be_transform_node(old_block);
319 dbg_info *dbgi = get_irn_dbg_info(node);
320 ir_mode *mode = get_irn_mode(node);
323 if (mode_is_float(mode)) {
324 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
325 ir_node *nomem = new_NoMem();
327 if (ia32_cg_config.use_sse2)
328 cnst = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem, mode_E);
330 cnst = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode_E);
331 set_ia32_am_sc(cnst, get_SymConst_entity(node));
332 set_ia32_use_frame(cnst);
336 if (get_SymConst_kind(node) != symconst_addr_ent) {
337 panic("backend only support symconst_addr_ent (at %+F)", node);
339 entity = get_SymConst_entity(node);
340 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0);
343 SET_IA32_ORIG_NODE(cnst, node);
345 be_dep_on_frame(cnst);
350 * Create a float type for the given mode and cache it.
352 * @param mode the mode for the float type (might be integer mode for SSE2 types)
353 * @param align alignment
355 static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align) {
361 if (mode == mode_Iu) {
362 static ir_type *int_Iu[16] = {NULL, };
364 if (int_Iu[align] == NULL) {
365 snprintf(buf, sizeof(buf), "int_Iu_%u", align);
366 int_Iu[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
367 /* set the specified alignment */
368 set_type_alignment_bytes(tp, align);
370 return int_Iu[align];
371 } else if (mode == mode_Lu) {
372 static ir_type *int_Lu[16] = {NULL, };
374 if (int_Lu[align] == NULL) {
375 snprintf(buf, sizeof(buf), "int_Lu_%u", align);
376 int_Lu[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
377 /* set the specified alignment */
378 set_type_alignment_bytes(tp, align);
380 return int_Lu[align];
381 } else if (mode == mode_F) {
382 static ir_type *float_F[16] = {NULL, };
384 if (float_F[align] == NULL) {
385 snprintf(buf, sizeof(buf), "float_F_%u", align);
386 float_F[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
387 /* set the specified alignment */
388 set_type_alignment_bytes(tp, align);
390 return float_F[align];
391 } else if (mode == mode_D) {
392 static ir_type *float_D[16] = {NULL, };
394 if (float_D[align] == NULL) {
395 snprintf(buf, sizeof(buf), "float_D_%u", align);
396 float_D[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
397 /* set the specified alignment */
398 set_type_alignment_bytes(tp, align);
400 return float_D[align];
402 static ir_type *float_E[16] = {NULL, };
404 if (float_E[align] == NULL) {
405 snprintf(buf, sizeof(buf), "float_E_%u", align);
406 float_E[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
407 /* set the specified alignment */
408 set_type_alignment_bytes(tp, align);
410 return float_E[align];
415 * Create a float[2] array type for the given atomic type.
417 * @param tp the atomic type
419 static ir_type *ia32_create_float_array(ir_type *tp) {
421 ir_mode *mode = get_type_mode(tp);
422 unsigned align = get_type_alignment_bytes(tp);
427 if (mode == mode_F) {
428 static ir_type *float_F[16] = {NULL, };
430 if (float_F[align] != NULL)
431 return float_F[align];
432 snprintf(buf, sizeof(buf), "arr_float_F_%u", align);
433 arr = float_F[align] = new_type_array(new_id_from_str(buf), 1, tp);
434 } else if (mode == mode_D) {
435 static ir_type *float_D[16] = {NULL, };
437 if (float_D[align] != NULL)
438 return float_D[align];
439 snprintf(buf, sizeof(buf), "arr_float_D_%u", align);
440 arr = float_D[align] = new_type_array(new_id_from_str(buf), 1, tp);
442 static ir_type *float_E[16] = {NULL, };
444 if (float_E[align] != NULL)
445 return float_E[align];
446 snprintf(buf, sizeof(buf), "arr_float_E_%u", align);
447 arr = float_E[align] = new_type_array(new_id_from_str(buf), 1, tp);
449 set_type_alignment_bytes(arr, align);
450 set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
451 set_type_state(arr, layout_fixed);
455 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
456 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
458 static const struct {
459 const char *ent_name;
460 const char *cnst_str;
463 } names [ia32_known_const_max] = {
464 { ENT_SFP_SIGN, SFP_SIGN, 0, 16 }, /* ia32_SSIGN */
465 { ENT_DFP_SIGN, DFP_SIGN, 1, 16 }, /* ia32_DSIGN */
466 { ENT_SFP_ABS, SFP_ABS, 0, 16 }, /* ia32_SABS */
467 { ENT_DFP_ABS, DFP_ABS, 1, 16 }, /* ia32_DABS */
468 { ENT_ULL_BIAS, ULL_BIAS, 2, 4 } /* ia32_ULLBIAS */
470 static ir_entity *ent_cache[ia32_known_const_max];
472 const char *ent_name, *cnst_str;
478 ent_name = names[kct].ent_name;
479 if (! ent_cache[kct]) {
480 cnst_str = names[kct].cnst_str;
482 switch (names[kct].mode) {
483 case 0: mode = mode_Iu; break;
484 case 1: mode = mode_Lu; break;
485 default: mode = mode_F; break;
487 tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
488 tp = ia32_create_float_type(mode, names[kct].align);
490 if (kct == ia32_ULLBIAS)
491 tp = ia32_create_float_array(tp);
492 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
494 set_entity_ld_ident(ent, get_entity_ident(ent));
495 set_entity_visibility(ent, visibility_local);
496 set_entity_variability(ent, variability_constant);
497 set_entity_allocation(ent, allocation_static);
499 if (kct == ia32_ULLBIAS) {
500 ir_initializer_t *initializer = create_initializer_compound(2);
502 set_initializer_compound_value(initializer, 0,
503 create_initializer_tarval(get_tarval_null(mode)));
504 set_initializer_compound_value(initializer, 1,
505 create_initializer_tarval(tv));
507 set_entity_initializer(ent, initializer);
509 set_entity_initializer(ent, create_initializer_tarval(tv));
512 /* cache the entry */
513 ent_cache[kct] = ent;
516 return ent_cache[kct];
520 * return true if the node is a Proj(Load) and could be used in source address
521 * mode for another node. Will return only true if the @p other node is not
522 * dependent on the memory of the Load (for binary operations use the other
523 * input here, for unary operations use NULL).
525 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
526 ir_node *other, ir_node *other2, match_flags_t flags)
531 /* float constants are always available */
532 if (is_Const(node)) {
533 ir_mode *mode = get_irn_mode(node);
534 if (mode_is_float(mode)) {
535 if (ia32_cg_config.use_sse2) {
536 if (is_simple_sse_Const(node))
539 if (is_simple_x87_Const(node))
542 if (get_irn_n_edges(node) > 1)
550 load = get_Proj_pred(node);
551 pn = get_Proj_proj(node);
552 if (!is_Load(load) || pn != pn_Load_res)
554 if (get_nodes_block(load) != block)
556 /* we only use address mode if we're the only user of the load */
557 if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
559 /* in some edge cases with address mode we might reach the load normally
560 * and through some AM sequence, if it is already materialized then we
561 * can't create an AM node from it */
562 if (be_is_transformed(node))
565 /* don't do AM if other node inputs depend on the load (via mem-proj) */
566 if (other != NULL && prevents_AM(block, load, other))
569 if (other2 != NULL && prevents_AM(block, load, other2))
575 typedef struct ia32_address_mode_t ia32_address_mode_t;
576 struct ia32_address_mode_t {
581 ia32_op_type_t op_type;
585 unsigned commutative : 1;
586 unsigned ins_permuted : 1;
589 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
593 /* construct load address */
594 memset(addr, 0, sizeof(addr[0]));
595 ia32_create_address_mode(addr, ptr, 0);
597 noreg_gp = ia32_new_NoReg_gp(env_cg);
598 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
599 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
600 addr->mem = be_transform_node(mem);
603 static void build_address(ia32_address_mode_t *am, ir_node *node,
604 ia32_create_am_flags_t flags)
606 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
607 ia32_address_t *addr = &am->addr;
613 if (is_Const(node)) {
614 ir_entity *entity = create_float_const_entity(node);
615 addr->base = noreg_gp;
616 addr->index = noreg_gp;
617 addr->mem = new_NoMem();
618 addr->symconst_ent = entity;
620 am->ls_mode = get_type_mode(get_entity_type(entity));
621 am->pinned = op_pin_state_floats;
625 load = get_Proj_pred(node);
626 ptr = get_Load_ptr(load);
627 mem = get_Load_mem(load);
628 new_mem = be_transform_node(mem);
629 am->pinned = get_irn_pinned(load);
630 am->ls_mode = get_Load_mode(load);
631 am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
634 /* construct load address */
635 ia32_create_address_mode(addr, ptr, flags);
637 addr->base = addr->base ? be_transform_node(addr->base) : noreg_gp;
638 addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
642 static void set_address(ir_node *node, const ia32_address_t *addr)
644 set_ia32_am_scale(node, addr->scale);
645 set_ia32_am_sc(node, addr->symconst_ent);
646 set_ia32_am_offs_int(node, addr->offset);
647 if (addr->symconst_sign)
648 set_ia32_am_sc_sign(node);
650 set_ia32_use_frame(node);
651 set_ia32_frame_ent(node, addr->frame_entity);
655 * Apply attributes of a given address mode to a node.
657 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
659 set_address(node, &am->addr);
661 set_ia32_op_type(node, am->op_type);
662 set_ia32_ls_mode(node, am->ls_mode);
663 if (am->pinned == op_pin_state_pinned) {
664 /* beware: some nodes are already pinned and did not allow to change the state */
665 if (get_irn_pinned(node) != op_pin_state_pinned)
666 set_irn_pinned(node, op_pin_state_pinned);
669 set_ia32_commutative(node);
673 * Check, if a given node is a Down-Conv, ie. a integer Conv
674 * from a mode with a mode with more bits to a mode with lesser bits.
675 * Moreover, we return only true if the node has not more than 1 user.
677 * @param node the node
678 * @return non-zero if node is a Down-Conv
680 static int is_downconv(const ir_node *node)
688 /* we only want to skip the conv when we're the only user
689 * (not optimal but for now...)
691 if (get_irn_n_edges(node) > 1)
694 src_mode = get_irn_mode(get_Conv_op(node));
695 dest_mode = get_irn_mode(node);
697 ia32_mode_needs_gp_reg(src_mode) &&
698 ia32_mode_needs_gp_reg(dest_mode) &&
699 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
702 /* Skip all Down-Conv's on a given node and return the resulting node. */
703 ir_node *ia32_skip_downconv(ir_node *node)
705 while (is_downconv(node))
706 node = get_Conv_op(node);
711 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
713 ir_mode *mode = get_irn_mode(node);
718 if (mode_is_signed(mode)) {
723 block = get_nodes_block(node);
724 dbgi = get_irn_dbg_info(node);
726 return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
730 * matches operands of a node into ia32 addressing/operand modes. This covers
731 * usage of source address mode, immediates, operations with non 32-bit modes,
733 * The resulting data is filled into the @p am struct. block is the block
734 * of the node whose arguments are matched. op1, op2 are the first and second
735 * input that are matched (op1 may be NULL). other_op is another unrelated
736 * input that is not matched! but which is needed sometimes to check if AM
737 * for op1/op2 is legal.
738 * @p flags describes the supported modes of the operation in detail.
740 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
741 ir_node *op1, ir_node *op2, ir_node *other_op,
744 ia32_address_t *addr = &am->addr;
745 ir_mode *mode = get_irn_mode(op2);
746 int mode_bits = get_mode_size_bits(mode);
747 ir_node *noreg_gp, *new_op1, *new_op2;
749 unsigned commutative;
750 int use_am_and_immediates;
753 memset(am, 0, sizeof(am[0]));
755 commutative = (flags & match_commutative) != 0;
756 use_am_and_immediates = (flags & match_am_and_immediates) != 0;
757 use_am = (flags & match_am) != 0;
758 use_immediate = (flags & match_immediate) != 0;
759 assert(!use_am_and_immediates || use_immediate);
762 assert(!commutative || op1 != NULL);
763 assert(use_am || !(flags & match_8bit_am));
764 assert(use_am || !(flags & match_16bit_am));
766 if ((mode_bits == 8 && !(flags & match_8bit_am)) ||
767 (mode_bits == 16 && !(flags & match_16bit_am))) {
771 /* we can simply skip downconvs for mode neutral nodes: the upper bits
772 * can be random for these operations */
773 if (flags & match_mode_neutral) {
774 op2 = ia32_skip_downconv(op2);
776 op1 = ia32_skip_downconv(op1);
780 /* match immediates. firm nodes are normalized: constants are always on the
783 if (!(flags & match_try_am) && use_immediate) {
784 new_op2 = try_create_Immediate(op2, 0);
787 noreg_gp = ia32_new_NoReg_gp(env_cg);
788 if (new_op2 == NULL &&
789 use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
790 build_address(am, op2, 0);
791 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
792 if (mode_is_float(mode)) {
793 new_op2 = ia32_new_NoReg_vfp(env_cg);
797 am->op_type = ia32_AddrModeS;
798 } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
800 ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
802 build_address(am, op1, 0);
804 if (mode_is_float(mode)) {
805 noreg = ia32_new_NoReg_vfp(env_cg);
810 if (new_op2 != NULL) {
813 new_op1 = be_transform_node(op2);
815 am->ins_permuted = 1;
817 am->op_type = ia32_AddrModeS;
819 am->op_type = ia32_Normal;
821 if (flags & match_try_am) {
827 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
829 new_op2 = be_transform_node(op2);
831 (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
833 if (addr->base == NULL)
834 addr->base = noreg_gp;
835 if (addr->index == NULL)
836 addr->index = noreg_gp;
837 if (addr->mem == NULL)
838 addr->mem = new_NoMem();
840 am->new_op1 = new_op1;
841 am->new_op2 = new_op2;
842 am->commutative = commutative;
845 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
850 if (am->mem_proj == NULL)
853 /* we have to create a mode_T so the old MemProj can attach to us */
854 mode = get_irn_mode(node);
855 load = get_Proj_pred(am->mem_proj);
857 be_set_transformed_node(load, node);
859 if (mode != mode_T) {
860 set_irn_mode(node, mode_T);
861 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
868 * Construct a standard binary operation, set AM and immediate if required.
870 * @param node The original node for which the binop is created
871 * @param op1 The first operand
872 * @param op2 The second operand
873 * @param func The node constructor function
874 * @return The constructed ia32 node.
876 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
877 construct_binop_func *func, match_flags_t flags)
880 ir_node *block, *new_block, *new_node;
881 ia32_address_mode_t am;
882 ia32_address_t *addr = &am.addr;
884 block = get_nodes_block(node);
885 match_arguments(&am, block, op1, op2, NULL, flags);
887 dbgi = get_irn_dbg_info(node);
888 new_block = be_transform_node(block);
889 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
890 am.new_op1, am.new_op2);
891 set_am_attributes(new_node, &am);
892 /* we can't use source address mode anymore when using immediates */
893 if (!(flags & match_am_and_immediates) &&
894 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
895 set_ia32_am_support(new_node, ia32_am_none);
896 SET_IA32_ORIG_NODE(new_node, node);
898 new_node = fix_mem_proj(new_node, &am);
905 n_ia32_l_binop_right,
906 n_ia32_l_binop_eflags
908 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Adc_left, n_Adc_left)
909 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Adc_right, n_Adc_right)
910 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags, n_Adc_eflags)
911 COMPILETIME_ASSERT(n_ia32_l_binop_left == n_ia32_l_Sbb_minuend, n_Sbb_minuend)
912 COMPILETIME_ASSERT(n_ia32_l_binop_right == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
913 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags, n_Sbb_eflags)
916 * Construct a binary operation which also consumes the eflags.
918 * @param node The node to transform
919 * @param func The node constructor function
920 * @param flags The match flags
921 * @return The constructor ia32 node
923 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
926 ir_node *src_block = get_nodes_block(node);
927 ir_node *op1 = get_irn_n(node, n_ia32_l_binop_left);
928 ir_node *op2 = get_irn_n(node, n_ia32_l_binop_right);
929 ir_node *eflags = get_irn_n(node, n_ia32_l_binop_eflags);
931 ir_node *block, *new_node, *new_eflags;
932 ia32_address_mode_t am;
933 ia32_address_t *addr = &am.addr;
935 match_arguments(&am, src_block, op1, op2, eflags, flags);
937 dbgi = get_irn_dbg_info(node);
938 block = be_transform_node(src_block);
939 new_eflags = be_transform_node(eflags);
940 new_node = func(dbgi, block, addr->base, addr->index, addr->mem,
941 am.new_op1, am.new_op2, new_eflags);
942 set_am_attributes(new_node, &am);
943 /* we can't use source address mode anymore when using immediates */
944 if (!(flags & match_am_and_immediates) &&
945 (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
946 set_ia32_am_support(new_node, ia32_am_none);
947 SET_IA32_ORIG_NODE(new_node, node);
949 new_node = fix_mem_proj(new_node, &am);
954 static ir_node *get_fpcw(void)
957 if (initial_fpcw != NULL)
960 fpcw = be_abi_get_ignore_irn(env_cg->birg->abi,
961 &ia32_fp_cw_regs[REG_FPCW]);
962 initial_fpcw = be_transform_node(fpcw);
968 * Construct a standard binary operation, set AM and immediate if required.
970 * @param op1 The first operand
971 * @param op2 The second operand
972 * @param func The node constructor function
973 * @return The constructed ia32 node.
975 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
976 construct_binop_float_func *func)
978 ir_mode *mode = get_irn_mode(node);
980 ir_node *block, *new_block, *new_node;
981 ia32_address_mode_t am;
982 ia32_address_t *addr = &am.addr;
983 ia32_x87_attr_t *attr;
984 /* All operations are considered commutative, because there are reverse
986 match_flags_t flags = match_commutative;
988 /* cannot use address mode with long double on x87 */
989 if (get_mode_size_bits(mode) <= 64)
992 block = get_nodes_block(node);
993 match_arguments(&am, block, op1, op2, NULL, flags);
995 dbgi = get_irn_dbg_info(node);
996 new_block = be_transform_node(block);
997 new_node = func(dbgi, new_block, addr->base, addr->index, addr->mem,
998 am.new_op1, am.new_op2, get_fpcw());
999 set_am_attributes(new_node, &am);
1001 attr = get_ia32_x87_attr(new_node);
1002 attr->attr.data.ins_permuted = am.ins_permuted;
1004 SET_IA32_ORIG_NODE(new_node, node);
1006 new_node = fix_mem_proj(new_node, &am);
1012 * Construct a shift/rotate binary operation, sets AM and immediate if required.
1014 * @param op1 The first operand
1015 * @param op2 The second operand
1016 * @param func The node constructor function
1017 * @return The constructed ia32 node.
1019 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1020 construct_shift_func *func,
1021 match_flags_t flags)
1024 ir_node *block, *new_block, *new_op1, *new_op2, *new_node;
1026 assert(! mode_is_float(get_irn_mode(node)));
1027 assert(flags & match_immediate);
1028 assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1030 if (flags & match_mode_neutral) {
1031 op1 = ia32_skip_downconv(op1);
1032 new_op1 = be_transform_node(op1);
1033 } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1034 new_op1 = create_upconv(op1, node);
1036 new_op1 = be_transform_node(op1);
1039 /* the shift amount can be any mode that is bigger than 5 bits, since all
1040 * other bits are ignored anyway */
1041 while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1042 ir_node *const op = get_Conv_op(op2);
1043 if (mode_is_float(get_irn_mode(op)))
1046 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1048 new_op2 = create_immediate_or_transform(op2, 0);
1050 dbgi = get_irn_dbg_info(node);
1051 block = get_nodes_block(node);
1052 new_block = be_transform_node(block);
1053 new_node = func(dbgi, new_block, new_op1, new_op2);
1054 SET_IA32_ORIG_NODE(new_node, node);
1056 /* lowered shift instruction may have a dependency operand, handle it here */
1057 if (get_irn_arity(node) == 3) {
1058 /* we have a dependency */
1059 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1060 add_irn_dep(new_node, new_dep);
1068 * Construct a standard unary operation, set AM and immediate if required.
1070 * @param op The operand
1071 * @param func The node constructor function
1072 * @return The constructed ia32 node.
1074 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1075 match_flags_t flags)
1078 ir_node *block, *new_block, *new_op, *new_node;
1080 assert(flags == 0 || flags == match_mode_neutral);
1081 if (flags & match_mode_neutral) {
1082 op = ia32_skip_downconv(op);
1085 new_op = be_transform_node(op);
1086 dbgi = get_irn_dbg_info(node);
1087 block = get_nodes_block(node);
1088 new_block = be_transform_node(block);
1089 new_node = func(dbgi, new_block, new_op);
1091 SET_IA32_ORIG_NODE(new_node, node);
1096 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1097 ia32_address_t *addr)
1099 ir_node *base, *index, *res;
1103 base = ia32_new_NoReg_gp(env_cg);
1105 base = be_transform_node(base);
1108 index = addr->index;
1109 if (index == NULL) {
1110 index = ia32_new_NoReg_gp(env_cg);
1112 index = be_transform_node(index);
1115 res = new_bd_ia32_Lea(dbgi, block, base, index);
1116 set_address(res, addr);
1122 * Returns non-zero if a given address mode has a symbolic or
1123 * numerical offset != 0.
1125 static int am_has_immediates(const ia32_address_t *addr)
1127 return addr->offset != 0 || addr->symconst_ent != NULL
1128 || addr->frame_entity || addr->use_frame;
1132 * Creates an ia32 Add.
1134 * @return the created ia32 Add node
1136 static ir_node *gen_Add(ir_node *node)
1138 ir_mode *mode = get_irn_mode(node);
1139 ir_node *op1 = get_Add_left(node);
1140 ir_node *op2 = get_Add_right(node);
1142 ir_node *block, *new_block, *new_node, *add_immediate_op;
1143 ia32_address_t addr;
1144 ia32_address_mode_t am;
1146 if (mode_is_float(mode)) {
1147 if (ia32_cg_config.use_sse2)
1148 return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1149 match_commutative | match_am);
1151 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1154 ia32_mark_non_am(node);
1156 op2 = ia32_skip_downconv(op2);
1157 op1 = ia32_skip_downconv(op1);
1161 * 0. Immediate Trees (example Add(Symconst, Const) -> Const)
1162 * 1. Add with immediate -> Lea
1163 * 2. Add with possible source address mode -> Add
1164 * 3. Otherwise -> Lea
1166 memset(&addr, 0, sizeof(addr));
1167 ia32_create_address_mode(&addr, node, ia32_create_am_force);
1168 add_immediate_op = NULL;
1170 dbgi = get_irn_dbg_info(node);
1171 block = get_nodes_block(node);
1172 new_block = be_transform_node(block);
1175 if (addr.base == NULL && addr.index == NULL) {
1176 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1177 addr.symconst_sign, addr.offset);
1178 be_dep_on_frame(new_node);
1179 SET_IA32_ORIG_NODE(new_node, node);
1182 /* add with immediate? */
1183 if (addr.index == NULL) {
1184 add_immediate_op = addr.base;
1185 } else if (addr.base == NULL && addr.scale == 0) {
1186 add_immediate_op = addr.index;
1189 if (add_immediate_op != NULL) {
1190 if (!am_has_immediates(&addr)) {
1191 #ifdef DEBUG_libfirm
1192 ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1195 return be_transform_node(add_immediate_op);
1198 new_node = create_lea_from_address(dbgi, new_block, &addr);
1199 SET_IA32_ORIG_NODE(new_node, node);
1203 /* test if we can use source address mode */
1204 match_arguments(&am, block, op1, op2, NULL, match_commutative
1205 | match_mode_neutral | match_am | match_immediate | match_try_am);
1207 /* construct an Add with source address mode */
1208 if (am.op_type == ia32_AddrModeS) {
1209 ia32_address_t *am_addr = &am.addr;
1210 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1211 am_addr->index, am_addr->mem, am.new_op1,
1213 set_am_attributes(new_node, &am);
1214 SET_IA32_ORIG_NODE(new_node, node);
1216 new_node = fix_mem_proj(new_node, &am);
1221 /* otherwise construct a lea */
1222 new_node = create_lea_from_address(dbgi, new_block, &addr);
1223 SET_IA32_ORIG_NODE(new_node, node);
1228 * Creates an ia32 Mul.
1230 * @return the created ia32 Mul node
1232 static ir_node *gen_Mul(ir_node *node)
1234 ir_node *op1 = get_Mul_left(node);
1235 ir_node *op2 = get_Mul_right(node);
1236 ir_mode *mode = get_irn_mode(node);
1238 if (mode_is_float(mode)) {
1239 if (ia32_cg_config.use_sse2)
1240 return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1241 match_commutative | match_am);
1243 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1245 return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1246 match_commutative | match_am | match_mode_neutral |
1247 match_immediate | match_am_and_immediates);
1251 * Creates an ia32 Mulh.
1252 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1253 * this result while Mul returns the lower 32 bit.
1255 * @return the created ia32 Mulh node
1257 static ir_node *gen_Mulh(ir_node *node)
1259 ir_node *block = get_nodes_block(node);
1260 ir_node *new_block = be_transform_node(block);
1261 dbg_info *dbgi = get_irn_dbg_info(node);
1262 ir_node *op1 = get_Mulh_left(node);
1263 ir_node *op2 = get_Mulh_right(node);
1264 ir_mode *mode = get_irn_mode(node);
1266 ir_node *proj_res_high;
1268 if (mode_is_signed(mode)) {
1269 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1270 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1271 mode_Iu, pn_ia32_IMul1OP_res_high);
1273 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1274 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1275 mode_Iu, pn_ia32_Mul_res_high);
1277 return proj_res_high;
1281 * Creates an ia32 And.
1283 * @return The created ia32 And node
1285 static ir_node *gen_And(ir_node *node)
1287 ir_node *op1 = get_And_left(node);
1288 ir_node *op2 = get_And_right(node);
1289 assert(! mode_is_float(get_irn_mode(node)));
1291 /* is it a zero extension? */
1292 if (is_Const(op2)) {
1293 tarval *tv = get_Const_tarval(op2);
1294 long v = get_tarval_long(tv);
1296 if (v == 0xFF || v == 0xFFFF) {
1297 dbg_info *dbgi = get_irn_dbg_info(node);
1298 ir_node *block = get_nodes_block(node);
1305 assert(v == 0xFFFF);
1308 res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1313 return gen_binop(node, op1, op2, new_bd_ia32_And,
1314 match_commutative | match_mode_neutral | match_am | match_immediate);
1320 * Creates an ia32 Or.
1322 * @return The created ia32 Or node
1324 static ir_node *gen_Or(ir_node *node)
1326 ir_node *op1 = get_Or_left(node);
1327 ir_node *op2 = get_Or_right(node);
1329 assert (! mode_is_float(get_irn_mode(node)));
1330 return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1331 | match_mode_neutral | match_am | match_immediate);
1337 * Creates an ia32 Eor.
1339 * @return The created ia32 Eor node
1341 static ir_node *gen_Eor(ir_node *node)
1343 ir_node *op1 = get_Eor_left(node);
1344 ir_node *op2 = get_Eor_right(node);
1346 assert(! mode_is_float(get_irn_mode(node)));
1347 return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1348 | match_mode_neutral | match_am | match_immediate);
1353 * Creates an ia32 Sub.
1355 * @return The created ia32 Sub node
1357 static ir_node *gen_Sub(ir_node *node)
1359 ir_node *op1 = get_Sub_left(node);
1360 ir_node *op2 = get_Sub_right(node);
1361 ir_mode *mode = get_irn_mode(node);
1363 if (mode_is_float(mode)) {
1364 if (ia32_cg_config.use_sse2)
1365 return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1367 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1370 if (is_Const(op2)) {
1371 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1375 return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1376 | match_am | match_immediate);
1379 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1380 ir_node *const src_val,
1381 ir_node *const src_mem,
1382 ir_node *const am_mem)
1384 if (is_NoMem(am_mem)) {
1385 return be_transform_node(src_mem);
1386 } else if (is_Proj(src_val) &&
1388 get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1389 /* avoid memory loop */
1391 } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1392 ir_node *const ptr_pred = get_Proj_pred(src_val);
1393 int const arity = get_Sync_n_preds(src_mem);
1398 NEW_ARR_A(ir_node*, ins, arity + 1);
1400 /* NOTE: This sometimes produces dead-code because the old sync in
1401 * src_mem might not be used anymore, we should detect this case
1402 * and kill the sync... */
1403 for (i = arity - 1; i >= 0; --i) {
1404 ir_node *const pred = get_Sync_pred(src_mem, i);
1406 /* avoid memory loop */
1407 if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1410 ins[n++] = be_transform_node(pred);
1415 return new_r_Sync(irg, block, n, ins);
1419 ins[0] = be_transform_node(src_mem);
1421 return new_r_Sync(irg, block, 2, ins);
1425 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1426 ir_node *val, const ir_node *orig)
1431 if (ia32_cg_config.use_short_sex_eax) {
1432 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1433 be_dep_on_frame(pval);
1434 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1436 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1437 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1439 SET_IA32_ORIG_NODE(res, orig);
1444 * Generates an ia32 DivMod with additional infrastructure for the
1445 * register allocator if needed.
1447 static ir_node *create_Div(ir_node *node)
1449 dbg_info *dbgi = get_irn_dbg_info(node);
1450 ir_node *block = get_nodes_block(node);
1451 ir_node *new_block = be_transform_node(block);
1458 ir_node *sign_extension;
1459 ia32_address_mode_t am;
1460 ia32_address_t *addr = &am.addr;
1462 /* the upper bits have random contents for smaller modes */
1463 switch (get_irn_opcode(node)) {
1465 op1 = get_Div_left(node);
1466 op2 = get_Div_right(node);
1467 mem = get_Div_mem(node);
1468 mode = get_Div_resmode(node);
1471 op1 = get_Mod_left(node);
1472 op2 = get_Mod_right(node);
1473 mem = get_Mod_mem(node);
1474 mode = get_Mod_resmode(node);
1477 op1 = get_DivMod_left(node);
1478 op2 = get_DivMod_right(node);
1479 mem = get_DivMod_mem(node);
1480 mode = get_DivMod_resmode(node);
1483 panic("invalid divmod node %+F", node);
1486 match_arguments(&am, block, op1, op2, NULL, match_am);
1488 /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1489 is the memory of the consumed address. We can have only the second op as address
1490 in Div nodes, so check only op2. */
1491 new_mem = transform_AM_mem(current_ir_graph, block, op2, mem, addr->mem);
1493 if (mode_is_signed(mode)) {
1494 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1495 new_node = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1496 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1498 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0);
1499 be_dep_on_frame(sign_extension);
1501 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1502 addr->index, new_mem, am.new_op2,
1503 am.new_op1, sign_extension);
1506 set_irn_pinned(new_node, get_irn_pinned(node));
1508 set_am_attributes(new_node, &am);
1509 SET_IA32_ORIG_NODE(new_node, node);
1511 new_node = fix_mem_proj(new_node, &am);
1517 static ir_node *gen_Mod(ir_node *node)
1519 return create_Div(node);
1522 static ir_node *gen_Div(ir_node *node)
1524 return create_Div(node);
1527 static ir_node *gen_DivMod(ir_node *node)
1529 return create_Div(node);
1535 * Creates an ia32 floating Div.
1537 * @return The created ia32 xDiv node
1539 static ir_node *gen_Quot(ir_node *node)
1541 ir_node *op1 = get_Quot_left(node);
1542 ir_node *op2 = get_Quot_right(node);
1544 if (ia32_cg_config.use_sse2) {
1545 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1547 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1553 * Creates an ia32 Shl.
1555 * @return The created ia32 Shl node
1557 static ir_node *gen_Shl(ir_node *node)
1559 ir_node *left = get_Shl_left(node);
1560 ir_node *right = get_Shl_right(node);
1562 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1563 match_mode_neutral | match_immediate);
1567 * Creates an ia32 Shr.
1569 * @return The created ia32 Shr node
1571 static ir_node *gen_Shr(ir_node *node)
1573 ir_node *left = get_Shr_left(node);
1574 ir_node *right = get_Shr_right(node);
1576 return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1582 * Creates an ia32 Sar.
1584 * @return The created ia32 Shrs node
1586 static ir_node *gen_Shrs(ir_node *node)
1588 ir_node *left = get_Shrs_left(node);
1589 ir_node *right = get_Shrs_right(node);
1591 if (is_Const(right)) {
1592 tarval *tv = get_Const_tarval(right);
1593 long val = get_tarval_long(tv);
1595 /* this is a sign extension */
1596 dbg_info *dbgi = get_irn_dbg_info(node);
1597 ir_node *block = be_transform_node(get_nodes_block(node));
1598 ir_node *new_op = be_transform_node(left);
1600 return create_sex_32_64(dbgi, block, new_op, node);
1604 /* 8 or 16 bit sign extension? */
1605 if (is_Const(right) && is_Shl(left)) {
1606 ir_node *shl_left = get_Shl_left(left);
1607 ir_node *shl_right = get_Shl_right(left);
1608 if (is_Const(shl_right)) {
1609 tarval *tv1 = get_Const_tarval(right);
1610 tarval *tv2 = get_Const_tarval(shl_right);
1611 if (tv1 == tv2 && tarval_is_long(tv1)) {
1612 long val = get_tarval_long(tv1);
1613 if (val == 16 || val == 24) {
1614 dbg_info *dbgi = get_irn_dbg_info(node);
1615 ir_node *block = get_nodes_block(node);
1625 res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1634 return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1640 * Creates an ia32 Rol.
1642 * @param op1 The first operator
1643 * @param op2 The second operator
1644 * @return The created ia32 RotL node
1646 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1648 return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1654 * Creates an ia32 Ror.
1655 * NOTE: There is no RotR with immediate because this would always be a RotL
1656 * "imm-mode_size_bits" which can be pre-calculated.
1658 * @param op1 The first operator
1659 * @param op2 The second operator
1660 * @return The created ia32 RotR node
1662 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1664 return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1670 * Creates an ia32 RotR or RotL (depending on the found pattern).
1672 * @return The created ia32 RotL or RotR node
1674 static ir_node *gen_Rotl(ir_node *node)
1676 ir_node *rotate = NULL;
1677 ir_node *op1 = get_Rotl_left(node);
1678 ir_node *op2 = get_Rotl_right(node);
1680 /* Firm has only RotL, so we are looking for a right (op2)
1681 operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1682 that means we can create a RotR instead of an Add and a RotL */
1686 ir_node *left = get_Add_left(add);
1687 ir_node *right = get_Add_right(add);
1688 if (is_Const(right)) {
1689 tarval *tv = get_Const_tarval(right);
1690 ir_mode *mode = get_irn_mode(node);
1691 long bits = get_mode_size_bits(mode);
1693 if (is_Minus(left) &&
1694 tarval_is_long(tv) &&
1695 get_tarval_long(tv) == bits &&
1698 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1699 rotate = gen_Ror(node, op1, get_Minus_op(left));
1704 if (rotate == NULL) {
1705 rotate = gen_Rol(node, op1, op2);
1714 * Transforms a Minus node.
1716 * @return The created ia32 Minus node
1718 static ir_node *gen_Minus(ir_node *node)
1720 ir_node *op = get_Minus_op(node);
1721 ir_node *block = be_transform_node(get_nodes_block(node));
1722 dbg_info *dbgi = get_irn_dbg_info(node);
1723 ir_mode *mode = get_irn_mode(node);
1728 if (mode_is_float(mode)) {
1729 ir_node *new_op = be_transform_node(op);
1730 if (ia32_cg_config.use_sse2) {
1731 /* TODO: non-optimal... if we have many xXors, then we should
1732 * rather create a load for the const and use that instead of
1733 * several AM nodes... */
1734 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1735 ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1736 ir_node *nomem = new_NoMem();
1738 new_node = new_bd_ia32_xXor(dbgi, block, noreg_gp, noreg_gp,
1739 nomem, new_op, noreg_xmm);
1741 size = get_mode_size_bits(mode);
1742 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1744 set_ia32_am_sc(new_node, ent);
1745 set_ia32_op_type(new_node, ia32_AddrModeS);
1746 set_ia32_ls_mode(new_node, mode);
1748 new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1751 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1754 SET_IA32_ORIG_NODE(new_node, node);
1760 * Transforms a Not node.
1762 * @return The created ia32 Not node
1764 static ir_node *gen_Not(ir_node *node)
1766 ir_node *op = get_Not_op(node);
1768 assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1769 assert (! mode_is_float(get_irn_mode(node)));
1771 return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1777 * Transforms an Abs node.
1779 * @return The created ia32 Abs node
1781 static ir_node *gen_Abs(ir_node *node)
1783 ir_node *block = get_nodes_block(node);
1784 ir_node *new_block = be_transform_node(block);
1785 ir_node *op = get_Abs_op(node);
1786 dbg_info *dbgi = get_irn_dbg_info(node);
1787 ir_mode *mode = get_irn_mode(node);
1788 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
1789 ir_node *nomem = new_NoMem();
1795 if (mode_is_float(mode)) {
1796 new_op = be_transform_node(op);
1798 if (ia32_cg_config.use_sse2) {
1799 ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1800 new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_gp, noreg_gp,
1801 nomem, new_op, noreg_fp);
1803 size = get_mode_size_bits(mode);
1804 ent = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1806 set_ia32_am_sc(new_node, ent);
1808 SET_IA32_ORIG_NODE(new_node, node);
1810 set_ia32_op_type(new_node, ia32_AddrModeS);
1811 set_ia32_ls_mode(new_node, mode);
1813 new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1814 SET_IA32_ORIG_NODE(new_node, node);
1817 ir_node *xor, *sign_extension;
1819 if (get_mode_size_bits(mode) == 32) {
1820 new_op = be_transform_node(op);
1822 new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1825 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1827 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_gp, noreg_gp,
1828 nomem, new_op, sign_extension);
1829 SET_IA32_ORIG_NODE(xor, node);
1831 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_gp, noreg_gp,
1832 nomem, xor, sign_extension);
1833 SET_IA32_ORIG_NODE(new_node, node);
1840 * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1842 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1844 dbg_info *dbgi = get_irn_dbg_info(cmp);
1845 ir_node *block = get_nodes_block(cmp);
1846 ir_node *new_block = be_transform_node(block);
1847 ir_node *op1 = be_transform_node(x);
1848 ir_node *op2 = be_transform_node(n);
1850 return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1854 * Transform a node returning a "flag" result.
1856 * @param node the node to transform
1857 * @param pnc_out the compare mode to use
1859 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1868 /* we have a Cmp as input */
1869 if (is_Proj(node)) {
1870 ir_node *pred = get_Proj_pred(node);
1872 pn_Cmp pnc = get_Proj_proj(node);
1873 if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1874 ir_node *l = get_Cmp_left(pred);
1875 ir_node *r = get_Cmp_right(pred);
1877 ir_node *la = get_And_left(l);
1878 ir_node *ra = get_And_right(l);
1880 ir_node *c = get_Shl_left(la);
1881 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1882 /* (1 << n) & ra) */
1883 ir_node *n = get_Shl_right(la);
1884 flags = gen_bt(pred, ra, n);
1885 /* we must generate a Jc/Jnc jump */
1886 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1889 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1894 ir_node *c = get_Shl_left(ra);
1895 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1896 /* la & (1 << n)) */
1897 ir_node *n = get_Shl_right(ra);
1898 flags = gen_bt(pred, la, n);
1899 /* we must generate a Jc/Jnc jump */
1900 pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1903 *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1909 flags = be_transform_node(pred);
1915 /* a mode_b value, we have to compare it against 0 */
1916 dbgi = get_irn_dbg_info(node);
1917 new_block = be_transform_node(get_nodes_block(node));
1918 new_op = be_transform_node(node);
1919 noreg = ia32_new_NoReg_gp(env_cg);
1920 nomem = new_NoMem();
1921 flags = new_bd_ia32_Test(dbgi, new_block, noreg, noreg, nomem, new_op,
1922 new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1923 *pnc_out = pn_Cmp_Lg;
1928 * Transforms a Load.
1930 * @return the created ia32 Load node
1932 static ir_node *gen_Load(ir_node *node)
1934 ir_node *old_block = get_nodes_block(node);
1935 ir_node *block = be_transform_node(old_block);
1936 ir_node *ptr = get_Load_ptr(node);
1937 ir_node *mem = get_Load_mem(node);
1938 ir_node *new_mem = be_transform_node(mem);
1941 dbg_info *dbgi = get_irn_dbg_info(node);
1942 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
1943 ir_mode *mode = get_Load_mode(node);
1946 ia32_address_t addr;
1948 /* construct load address */
1949 memset(&addr, 0, sizeof(addr));
1950 ia32_create_address_mode(&addr, ptr, 0);
1957 base = be_transform_node(base);
1960 if (index == NULL) {
1963 index = be_transform_node(index);
1966 if (mode_is_float(mode)) {
1967 if (ia32_cg_config.use_sse2) {
1968 new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1970 res_mode = mode_xmm;
1972 new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1974 res_mode = mode_vfp;
1977 assert(mode != mode_b);
1979 /* create a conv node with address mode for smaller modes */
1980 if (get_mode_size_bits(mode) < 32) {
1981 new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1982 new_mem, noreg, mode);
1984 new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1989 set_irn_pinned(new_node, get_irn_pinned(node));
1990 set_ia32_op_type(new_node, ia32_AddrModeS);
1991 set_ia32_ls_mode(new_node, mode);
1992 set_address(new_node, &addr);
1994 if (get_irn_pinned(node) == op_pin_state_floats) {
1995 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1996 && pn_ia32_vfld_res == pn_ia32_Load_res
1997 && pn_ia32_Load_res == pn_ia32_res);
1998 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
2001 SET_IA32_ORIG_NODE(new_node, node);
2003 be_dep_on_frame(new_node);
2007 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2008 ir_node *ptr, ir_node *other)
2015 /* we only use address mode if we're the only user of the load */
2016 if (get_irn_n_edges(node) > 1)
2019 load = get_Proj_pred(node);
2022 if (get_nodes_block(load) != block)
2025 /* store should have the same pointer as the load */
2026 if (get_Load_ptr(load) != ptr)
2029 /* don't do AM if other node inputs depend on the load (via mem-proj) */
2030 if (other != NULL &&
2031 get_nodes_block(other) == block &&
2032 heights_reachable_in_block(heights, other, load)) {
2036 if (prevents_AM(block, load, mem))
2038 /* Store should be attached to the load via mem */
2039 assert(heights_reachable_in_block(heights, mem, load));
2044 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2045 ir_node *mem, ir_node *ptr, ir_mode *mode,
2046 construct_binop_dest_func *func,
2047 construct_binop_dest_func *func8bit,
2048 match_flags_t flags)
2050 ir_node *src_block = get_nodes_block(node);
2052 ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg);
2059 ia32_address_mode_t am;
2060 ia32_address_t *addr = &am.addr;
2061 memset(&am, 0, sizeof(am));
2063 assert(flags & match_immediate); /* there is no destam node without... */
2064 commutative = (flags & match_commutative) != 0;
2066 if (use_dest_am(src_block, op1, mem, ptr, op2)) {
2067 build_address(&am, op1, ia32_create_am_double_use);
2068 new_op = create_immediate_or_transform(op2, 0);
2069 } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2070 build_address(&am, op2, ia32_create_am_double_use);
2071 new_op = create_immediate_or_transform(op1, 0);
2076 if (addr->base == NULL)
2077 addr->base = noreg_gp;
2078 if (addr->index == NULL)
2079 addr->index = noreg_gp;
2080 if (addr->mem == NULL)
2081 addr->mem = new_NoMem();
2083 dbgi = get_irn_dbg_info(node);
2084 block = be_transform_node(src_block);
2085 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2087 if (get_mode_size_bits(mode) == 8) {
2088 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2090 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2092 set_address(new_node, addr);
2093 set_ia32_op_type(new_node, ia32_AddrModeD);
2094 set_ia32_ls_mode(new_node, mode);
2095 SET_IA32_ORIG_NODE(new_node, node);
2097 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2098 mem_proj = be_transform_node(am.mem_proj);
2099 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2104 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2105 ir_node *ptr, ir_mode *mode,
2106 construct_unop_dest_func *func)
2108 ir_node *src_block = get_nodes_block(node);
2114 ia32_address_mode_t am;
2115 ia32_address_t *addr = &am.addr;
2117 if (!use_dest_am(src_block, op, mem, ptr, NULL))
2120 memset(&am, 0, sizeof(am));
2121 build_address(&am, op, ia32_create_am_double_use);
2123 dbgi = get_irn_dbg_info(node);
2124 block = be_transform_node(src_block);
2125 new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2126 new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2127 set_address(new_node, addr);
2128 set_ia32_op_type(new_node, ia32_AddrModeD);
2129 set_ia32_ls_mode(new_node, mode);
2130 SET_IA32_ORIG_NODE(new_node, node);
2132 be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2133 mem_proj = be_transform_node(am.mem_proj);
2134 be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2139 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2141 ir_mode *mode = get_irn_mode(node);
2142 ir_node *mux_true = get_Mux_true(node);
2143 ir_node *mux_false = get_Mux_false(node);
2153 ia32_address_t addr;
2155 if (get_mode_size_bits(mode) != 8)
2158 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2160 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2166 build_address_ptr(&addr, ptr, mem);
2168 dbgi = get_irn_dbg_info(node);
2169 block = get_nodes_block(node);
2170 new_block = be_transform_node(block);
2171 cond = get_Mux_sel(node);
2172 flags = get_flags_node(cond, &pnc);
2173 new_mem = be_transform_node(mem);
2174 new_node = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2175 addr.index, addr.mem, flags, pnc, negated);
2176 set_address(new_node, &addr);
2177 set_ia32_op_type(new_node, ia32_AddrModeD);
2178 set_ia32_ls_mode(new_node, mode);
2179 SET_IA32_ORIG_NODE(new_node, node);
2184 static ir_node *try_create_dest_am(ir_node *node)
2186 ir_node *val = get_Store_value(node);
2187 ir_node *mem = get_Store_mem(node);
2188 ir_node *ptr = get_Store_ptr(node);
2189 ir_mode *mode = get_irn_mode(val);
2190 unsigned bits = get_mode_size_bits(mode);
2195 /* handle only GP modes for now... */
2196 if (!ia32_mode_needs_gp_reg(mode))
2200 /* store must be the only user of the val node */
2201 if (get_irn_n_edges(val) > 1)
2203 /* skip pointless convs */
2205 ir_node *conv_op = get_Conv_op(val);
2206 ir_mode *pred_mode = get_irn_mode(conv_op);
2207 if (!ia32_mode_needs_gp_reg(pred_mode))
2209 if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2217 /* value must be in the same block */
2218 if (get_nodes_block(node) != get_nodes_block(val))
2221 switch (get_irn_opcode(val)) {
2223 op1 = get_Add_left(val);
2224 op2 = get_Add_right(val);
2225 if (ia32_cg_config.use_incdec) {
2226 if (is_Const_1(op2)) {
2227 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2229 } else if (is_Const_Minus_1(op2)) {
2230 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2234 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2235 new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2236 match_commutative | match_immediate);
2239 op1 = get_Sub_left(val);
2240 op2 = get_Sub_right(val);
2241 if (is_Const(op2)) {
2242 ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2244 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2245 new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2249 op1 = get_And_left(val);
2250 op2 = get_And_right(val);
2251 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2252 new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2253 match_commutative | match_immediate);
2256 op1 = get_Or_left(val);
2257 op2 = get_Or_right(val);
2258 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2259 new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2260 match_commutative | match_immediate);
2263 op1 = get_Eor_left(val);
2264 op2 = get_Eor_right(val);
2265 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2266 new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2267 match_commutative | match_immediate);
2270 op1 = get_Shl_left(val);
2271 op2 = get_Shl_right(val);
2272 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2273 new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2277 op1 = get_Shr_left(val);
2278 op2 = get_Shr_right(val);
2279 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2280 new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2284 op1 = get_Shrs_left(val);
2285 op2 = get_Shrs_right(val);
2286 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2287 new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2291 op1 = get_Rotl_left(val);
2292 op2 = get_Rotl_right(val);
2293 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2294 new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2297 /* TODO: match ROR patterns... */
2299 new_node = try_create_SetMem(val, ptr, mem);
2302 op1 = get_Minus_op(val);
2303 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2306 /* should be lowered already */
2307 assert(mode != mode_b);
2308 op1 = get_Not_op(val);
2309 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2315 if (new_node != NULL) {
2316 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2317 get_irn_pinned(node) == op_pin_state_pinned) {
2318 set_irn_pinned(new_node, op_pin_state_pinned);
2325 static bool possible_int_mode_for_fp(ir_mode *mode)
2329 if (!mode_is_signed(mode))
2331 size = get_mode_size_bits(mode);
2332 if (size != 16 && size != 32)
2337 static int is_float_to_int_conv(const ir_node *node)
2339 ir_mode *mode = get_irn_mode(node);
2343 if (!possible_int_mode_for_fp(mode))
2348 conv_op = get_Conv_op(node);
2349 conv_mode = get_irn_mode(conv_op);
2351 if (!mode_is_float(conv_mode))
2358 * Transform a Store(floatConst) into a sequence of
2361 * @return the created ia32 Store node
2363 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2365 ir_mode *mode = get_irn_mode(cns);
2366 unsigned size = get_mode_size_bytes(mode);
2367 tarval *tv = get_Const_tarval(cns);
2368 ir_node *block = get_nodes_block(node);
2369 ir_node *new_block = be_transform_node(block);
2370 ir_node *ptr = get_Store_ptr(node);
2371 ir_node *mem = get_Store_mem(node);
2372 dbg_info *dbgi = get_irn_dbg_info(node);
2376 ia32_address_t addr;
2378 assert(size % 4 == 0);
2381 build_address_ptr(&addr, ptr, mem);
2385 get_tarval_sub_bits(tv, ofs) |
2386 (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2387 (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2388 (get_tarval_sub_bits(tv, ofs + 3) << 24);
2389 ir_node *imm = create_Immediate(NULL, 0, val);
2391 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2392 addr.index, addr.mem, imm);
2394 set_irn_pinned(new_node, get_irn_pinned(node));
2395 set_ia32_op_type(new_node, ia32_AddrModeD);
2396 set_ia32_ls_mode(new_node, mode_Iu);
2397 set_address(new_node, &addr);
2398 SET_IA32_ORIG_NODE(new_node, node);
2401 ins[i++] = new_node;
2406 } while (size != 0);
2409 return new_rd_Sync(dbgi, current_ir_graph, new_block, i, ins);
2416 * Generate a vfist or vfisttp instruction.
2418 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2419 ir_node *mem, ir_node *val, ir_node **fist)
2423 if (ia32_cg_config.use_fisttp) {
2424 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2425 if other users exists */
2426 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2427 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2428 ir_node *value = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2429 be_new_Keep(reg_class, irg, block, 1, &value);
2431 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2434 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2437 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2443 * Transforms a general (no special case) Store.
2445 * @return the created ia32 Store node
2447 static ir_node *gen_general_Store(ir_node *node)
2449 ir_node *val = get_Store_value(node);
2450 ir_mode *mode = get_irn_mode(val);
2451 ir_node *block = get_nodes_block(node);
2452 ir_node *new_block = be_transform_node(block);
2453 ir_node *ptr = get_Store_ptr(node);
2454 ir_node *mem = get_Store_mem(node);
2455 dbg_info *dbgi = get_irn_dbg_info(node);
2456 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2457 ir_node *new_val, *new_node, *store;
2458 ia32_address_t addr;
2460 /* check for destination address mode */
2461 new_node = try_create_dest_am(node);
2462 if (new_node != NULL)
2465 /* construct store address */
2466 memset(&addr, 0, sizeof(addr));
2467 ia32_create_address_mode(&addr, ptr, 0);
2469 if (addr.base == NULL) {
2472 addr.base = be_transform_node(addr.base);
2475 if (addr.index == NULL) {
2478 addr.index = be_transform_node(addr.index);
2480 addr.mem = be_transform_node(mem);
2482 if (mode_is_float(mode)) {
2483 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2485 while (is_Conv(val) && mode == get_irn_mode(val)) {
2486 ir_node *op = get_Conv_op(val);
2487 if (!mode_is_float(get_irn_mode(op)))
2491 new_val = be_transform_node(val);
2492 if (ia32_cg_config.use_sse2) {
2493 new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2494 addr.index, addr.mem, new_val);
2496 new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2497 addr.index, addr.mem, new_val, mode);
2500 } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2501 val = get_Conv_op(val);
2503 /* TODO: is this optimisation still necessary at all (middleend)? */
2504 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2505 while (is_Conv(val)) {
2506 ir_node *op = get_Conv_op(val);
2507 if (!mode_is_float(get_irn_mode(op)))
2509 if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2513 new_val = be_transform_node(val);
2514 new_node = gen_vfist(dbgi, current_ir_graph, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2516 new_val = create_immediate_or_transform(val, 0);
2517 assert(mode != mode_b);
2519 if (get_mode_size_bits(mode) == 8) {
2520 new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2521 addr.index, addr.mem, new_val);
2523 new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2524 addr.index, addr.mem, new_val);
2529 set_irn_pinned(store, get_irn_pinned(node));
2530 set_ia32_op_type(store, ia32_AddrModeD);
2531 set_ia32_ls_mode(store, mode);
2533 set_address(store, &addr);
2534 SET_IA32_ORIG_NODE(store, node);
2540 * Transforms a Store.
2542 * @return the created ia32 Store node
2544 static ir_node *gen_Store(ir_node *node)
2546 ir_node *val = get_Store_value(node);
2547 ir_mode *mode = get_irn_mode(val);
2549 if (mode_is_float(mode) && is_Const(val)) {
2550 /* We can transform every floating const store
2551 into a sequence of integer stores.
2552 If the constant is already in a register,
2553 it would be better to use it, but we don't
2554 have this information here. */
2555 return gen_float_const_Store(node, val);
2557 return gen_general_Store(node);
2561 * Transforms a Switch.
2563 * @return the created ia32 SwitchJmp node
2565 static ir_node *create_Switch(ir_node *node)
2567 dbg_info *dbgi = get_irn_dbg_info(node);
2568 ir_node *block = be_transform_node(get_nodes_block(node));
2569 ir_node *sel = get_Cond_selector(node);
2570 ir_node *new_sel = be_transform_node(sel);
2571 long switch_min = LONG_MAX;
2572 long switch_max = LONG_MIN;
2573 long default_pn = get_Cond_defaultProj(node);
2575 const ir_edge_t *edge;
2577 assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2579 /* determine the smallest switch case value */
2580 foreach_out_edge(node, edge) {
2581 ir_node *proj = get_edge_src_irn(edge);
2582 long pn = get_Proj_proj(proj);
2583 if (pn == default_pn)
2586 if (pn < switch_min)
2588 if (pn > switch_max)
2592 if ((unsigned long) (switch_max - switch_min) > 256000) {
2593 panic("Size of switch %+F bigger than 256000", node);
2596 if (switch_min != 0) {
2597 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2599 /* if smallest switch case is not 0 we need an additional sub */
2600 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg);
2601 add_ia32_am_offs_int(new_sel, -switch_min);
2602 set_ia32_op_type(new_sel, ia32_AddrModeS);
2604 SET_IA32_ORIG_NODE(new_sel, node);
2607 new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2608 SET_IA32_ORIG_NODE(new_node, node);
2614 * Transform a Cond node.
2616 static ir_node *gen_Cond(ir_node *node)
2618 ir_node *block = get_nodes_block(node);
2619 ir_node *new_block = be_transform_node(block);
2620 dbg_info *dbgi = get_irn_dbg_info(node);
2621 ir_node *sel = get_Cond_selector(node);
2622 ir_mode *sel_mode = get_irn_mode(sel);
2623 ir_node *flags = NULL;
2627 if (sel_mode != mode_b) {
2628 return create_Switch(node);
2631 /* we get flags from a Cmp */
2632 flags = get_flags_node(sel, &pnc);
2634 new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2635 SET_IA32_ORIG_NODE(new_node, node);
2640 static ir_node *gen_be_Copy(ir_node *node)
2642 ir_node *new_node = be_duplicate_node(node);
2643 ir_mode *mode = get_irn_mode(new_node);
2645 if (ia32_mode_needs_gp_reg(mode)) {
2646 set_irn_mode(new_node, mode_Iu);
2652 static ir_node *create_Fucom(ir_node *node)
2654 dbg_info *dbgi = get_irn_dbg_info(node);
2655 ir_node *block = get_nodes_block(node);
2656 ir_node *new_block = be_transform_node(block);
2657 ir_node *left = get_Cmp_left(node);
2658 ir_node *new_left = be_transform_node(left);
2659 ir_node *right = get_Cmp_right(node);
2663 if (ia32_cg_config.use_fucomi) {
2664 new_right = be_transform_node(right);
2665 new_node = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2667 set_ia32_commutative(new_node);
2668 SET_IA32_ORIG_NODE(new_node, node);
2670 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2671 new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2673 new_right = be_transform_node(right);
2674 new_node = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2677 set_ia32_commutative(new_node);
2679 SET_IA32_ORIG_NODE(new_node, node);
2681 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2682 SET_IA32_ORIG_NODE(new_node, node);
2688 static ir_node *create_Ucomi(ir_node *node)
2690 dbg_info *dbgi = get_irn_dbg_info(node);
2691 ir_node *src_block = get_nodes_block(node);
2692 ir_node *new_block = be_transform_node(src_block);
2693 ir_node *left = get_Cmp_left(node);
2694 ir_node *right = get_Cmp_right(node);
2696 ia32_address_mode_t am;
2697 ia32_address_t *addr = &am.addr;
2699 match_arguments(&am, src_block, left, right, NULL,
2700 match_commutative | match_am);
2702 new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2703 addr->mem, am.new_op1, am.new_op2,
2705 set_am_attributes(new_node, &am);
2707 SET_IA32_ORIG_NODE(new_node, node);
2709 new_node = fix_mem_proj(new_node, &am);
2715 * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2716 * to fold an and into a test node
2718 static bool can_fold_test_and(ir_node *node)
2720 const ir_edge_t *edge;
2722 /** we can only have eq and lg projs */
2723 foreach_out_edge(node, edge) {
2724 ir_node *proj = get_edge_src_irn(edge);
2725 pn_Cmp pnc = get_Proj_proj(proj);
2726 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2734 * returns true if it is assured, that the upper bits of a node are "clean"
2735 * which means for a 16 or 8 bit value, that the upper bits in the register
2736 * are 0 for unsigned and a copy of the last significant bit for signed
2739 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2741 assert(ia32_mode_needs_gp_reg(mode));
2742 if (get_mode_size_bits(mode) >= 32)
2745 if (is_Proj(transformed_node))
2746 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2748 switch (get_ia32_irn_opcode(transformed_node)) {
2749 case iro_ia32_Conv_I2I:
2750 case iro_ia32_Conv_I2I8Bit: {
2751 ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2752 if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2754 if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2761 if (mode_is_signed(mode)) {
2762 return false; /* TODO handle signed modes */
2764 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2765 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2766 const ia32_immediate_attr_t *attr
2767 = get_ia32_immediate_attr_const(right);
2768 if (attr->symconst == 0 &&
2769 (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2773 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2777 /* TODO too conservative if shift amount is constant */
2778 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2781 if (!mode_is_signed(mode)) {
2783 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2784 upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left), mode);
2786 /* TODO if one is known to be zero extended, then || is sufficient */
2791 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2792 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left), mode);
2794 case iro_ia32_Const:
2795 case iro_ia32_Immediate: {
2796 const ia32_immediate_attr_t *attr =
2797 get_ia32_immediate_attr_const(transformed_node);
2798 if (mode_is_signed(mode)) {
2799 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2800 return shifted == 0 || shifted == -1;
2802 unsigned long shifted = (unsigned long)attr->offset;
2803 shifted >>= get_mode_size_bits(mode);
2804 return shifted == 0;
2814 * Generate code for a Cmp.
2816 static ir_node *gen_Cmp(ir_node *node)
2818 dbg_info *dbgi = get_irn_dbg_info(node);
2819 ir_node *block = get_nodes_block(node);
2820 ir_node *new_block = be_transform_node(block);
2821 ir_node *left = get_Cmp_left(node);
2822 ir_node *right = get_Cmp_right(node);
2823 ir_mode *cmp_mode = get_irn_mode(left);
2825 ia32_address_mode_t am;
2826 ia32_address_t *addr = &am.addr;
2829 if (mode_is_float(cmp_mode)) {
2830 if (ia32_cg_config.use_sse2) {
2831 return create_Ucomi(node);
2833 return create_Fucom(node);
2837 assert(ia32_mode_needs_gp_reg(cmp_mode));
2839 /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2840 cmp_unsigned = !mode_is_signed(cmp_mode);
2841 if (is_Const_0(right) &&
2843 get_irn_n_edges(left) == 1 &&
2844 can_fold_test_and(node)) {
2845 /* Test(and_left, and_right) */
2846 ir_node *and_left = get_And_left(left);
2847 ir_node *and_right = get_And_right(left);
2849 /* matze: code here used mode instead of cmd_mode, I think it is always
2850 * the same as cmp_mode, but I leave this here to see if this is really
2853 assert(get_irn_mode(and_left) == cmp_mode);
2855 match_arguments(&am, block, and_left, and_right, NULL,
2857 match_am | match_8bit_am | match_16bit_am |
2858 match_am_and_immediates | match_immediate);
2860 /* use 32bit compare mode if possible since the opcode is smaller */
2861 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2862 upper_bits_clean(am.new_op2, cmp_mode)) {
2863 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2866 if (get_mode_size_bits(cmp_mode) == 8) {
2867 new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2868 addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2871 new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2872 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2875 /* Cmp(left, right) */
2876 match_arguments(&am, block, left, right, NULL,
2877 match_commutative | match_am | match_8bit_am |
2878 match_16bit_am | match_am_and_immediates |
2880 /* use 32bit compare mode if possible since the opcode is smaller */
2881 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2882 upper_bits_clean(am.new_op2, cmp_mode)) {
2883 cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2886 if (get_mode_size_bits(cmp_mode) == 8) {
2887 new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2888 addr->index, addr->mem, am.new_op1,
2889 am.new_op2, am.ins_permuted,
2892 new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2893 addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2896 set_am_attributes(new_node, &am);
2897 set_ia32_ls_mode(new_node, cmp_mode);
2899 SET_IA32_ORIG_NODE(new_node, node);
2901 new_node = fix_mem_proj(new_node, &am);
2906 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2909 dbg_info *dbgi = get_irn_dbg_info(node);
2910 ir_node *block = get_nodes_block(node);
2911 ir_node *new_block = be_transform_node(block);
2912 ir_node *val_true = get_Mux_true(node);
2913 ir_node *val_false = get_Mux_false(node);
2915 ia32_address_mode_t am;
2916 ia32_address_t *addr;
2918 assert(ia32_cg_config.use_cmov);
2919 assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2923 match_arguments(&am, block, val_false, val_true, flags,
2924 match_commutative | match_am | match_16bit_am | match_mode_neutral);
2926 new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2927 addr->mem, am.new_op1, am.new_op2, new_flags,
2928 am.ins_permuted, pnc);
2929 set_am_attributes(new_node, &am);
2931 SET_IA32_ORIG_NODE(new_node, node);
2933 new_node = fix_mem_proj(new_node, &am);
2939 * Creates a ia32 Setcc instruction.
2941 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2942 ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2945 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2946 ir_node *nomem = new_NoMem();
2947 ir_mode *mode = get_irn_mode(orig_node);
2950 new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2951 SET_IA32_ORIG_NODE(new_node, orig_node);
2953 /* we might need to conv the result up */
2954 if (get_mode_size_bits(mode) > 8) {
2955 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg, noreg,
2956 nomem, new_node, mode_Bu);
2957 SET_IA32_ORIG_NODE(new_node, orig_node);
2964 * Create instruction for an unsigned Difference or Zero.
2966 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2968 ir_graph *irg = current_ir_graph;
2969 ir_mode *mode = get_irn_mode(psi);
2970 ir_node *nomem = new_NoMem();
2971 ir_node *new_node, *sub, *sbb, *eflags, *block, *noreg;
2975 new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2976 match_mode_neutral | match_am | match_immediate | match_two_users);
2978 block = get_nodes_block(new_node);
2980 if (is_Proj(new_node)) {
2981 sub = get_Proj_pred(new_node);
2982 assert(is_ia32_Sub(sub));
2985 set_irn_mode(sub, mode_T);
2986 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2988 eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2990 dbgi = get_irn_dbg_info(psi);
2991 sbb = new_bd_ia32_Sbb0(dbgi, block, eflags);
2993 noreg = ia32_new_NoReg_gp(env_cg);
2994 new_node = new_bd_ia32_And(dbgi, block, noreg, noreg, nomem, new_node, sbb);
2995 set_ia32_commutative(new_node);
3000 * Create an const array of two float consts.
3002 * @param c0 the first constant
3003 * @param c1 the second constant
3004 * @param new_mode IN/OUT for the mode of the constants, if NULL
3005 * smallest possible mode will be used
3007 static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **new_mode) {
3009 ir_mode *mode = *new_mode;
3011 ir_initializer_t *initializer;
3012 tarval *tv0 = get_Const_tarval(c0);
3013 tarval *tv1 = get_Const_tarval(c1);
3016 /* detect the best mode for the constants */
3017 mode = get_tarval_mode(tv0);
3019 if (mode != mode_F) {
3020 if (tarval_ieee754_can_conv_lossless(tv0, mode_F) &&
3021 tarval_ieee754_can_conv_lossless(tv1, mode_F)) {
3023 tv0 = tarval_convert_to(tv0, mode);
3024 tv1 = tarval_convert_to(tv1, mode);
3025 } else if (mode != mode_D) {
3026 if (tarval_ieee754_can_conv_lossless(tv0, mode_D) &&
3027 tarval_ieee754_can_conv_lossless(tv1, mode_D)) {
3029 tv0 = tarval_convert_to(tv0, mode);
3030 tv1 = tarval_convert_to(tv1, mode);
3037 tp = ia32_create_float_type(mode, 4);
3038 tp = ia32_create_float_array(tp);
3040 ent = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp);
3042 set_entity_ld_ident(ent, get_entity_ident(ent));
3043 set_entity_visibility(ent, visibility_local);
3044 set_entity_variability(ent, variability_constant);
3045 set_entity_allocation(ent, allocation_static);
3047 initializer = create_initializer_compound(2);
3049 set_initializer_compound_value(initializer, 0, create_initializer_tarval(tv0));
3050 set_initializer_compound_value(initializer, 1, create_initializer_tarval(tv1));
3052 set_entity_initializer(ent, initializer);
3059 * Transforms a Mux node into CMov.
3061 * @return The transformed node.
3063 static ir_node *gen_Mux(ir_node *node)
3065 dbg_info *dbgi = get_irn_dbg_info(node);
3066 ir_node *block = get_nodes_block(node);
3067 ir_node *new_block = be_transform_node(block);
3068 ir_node *mux_true = get_Mux_true(node);
3069 ir_node *mux_false = get_Mux_false(node);
3070 ir_node *cond = get_Mux_sel(node);
3071 ir_mode *mode = get_irn_mode(node);
3076 assert(get_irn_mode(cond) == mode_b);
3078 /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
3079 if (mode_is_float(mode)) {
3080 ir_node *cmp = get_Proj_pred(cond);
3081 ir_node *cmp_left = get_Cmp_left(cmp);
3082 ir_node *cmp_right = get_Cmp_right(cmp);
3083 pn_Cmp pnc = get_Proj_proj(cond);
3085 if (ia32_cg_config.use_sse2) {
3086 if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3087 if (cmp_left == mux_true && cmp_right == mux_false) {
3088 /* Mux(a <= b, a, b) => MIN */
3089 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3090 match_commutative | match_am | match_two_users);
3091 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3092 /* Mux(a <= b, b, a) => MAX */
3093 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3094 match_commutative | match_am | match_two_users);
3096 } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3097 if (cmp_left == mux_true && cmp_right == mux_false) {
3098 /* Mux(a >= b, a, b) => MAX */
3099 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
3100 match_commutative | match_am | match_two_users);
3101 } else if (cmp_left == mux_false && cmp_right == mux_true) {
3102 /* Mux(a >= b, b, a) => MIN */
3103 return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
3104 match_commutative | match_am | match_two_users);
3108 if (is_Const(mux_true) && is_Const(mux_false)) {
3109 ia32_address_mode_t am;
3110 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3111 ir_node *nomem = new_NoMem();
3116 flags = get_flags_node(cond, &pnc);
3117 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3119 if (ia32_cg_config.use_sse2) {
3120 /* cannot load from different mode on SSE */
3123 /* x87 can load any mode */
3127 am.addr.symconst_ent = ia32_create_const_array(mux_false, mux_true, &new_mode);
3129 switch (get_mode_size_bytes(new_mode)) {
3139 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3140 set_ia32_am_scale(new_node, 2);
3145 new_node = new_bd_ia32_Lea(dbgi, new_block, new_node, new_node);
3146 set_ia32_am_scale(new_node, 1);
3149 /* arg, shift 16 NOT supported */
3151 new_node = new_bd_ia32_Add(dbgi, new_block, noreg, noreg, nomem, new_node, new_node);
3154 panic("Unsupported constant size");
3157 am.ls_mode = new_mode;
3158 am.addr.base = noreg;
3159 am.addr.index = new_node;
3160 am.addr.mem = nomem;
3162 am.addr.scale = scale;
3163 am.addr.use_frame = 0;
3164 am.addr.frame_entity = NULL;
3165 am.addr.symconst_sign = 0;
3166 am.mem_proj = am.addr.mem;
3167 am.op_type = ia32_AddrModeS;
3170 am.pinned = op_pin_state_floats;
3172 am.ins_permuted = 0;
3174 if (ia32_cg_config.use_sse2)
3175 load = new_bd_ia32_xLoad(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3177 load = new_bd_ia32_vfld(dbgi, block, am.addr.base, am.addr.index, am.addr.mem, new_mode);
3178 set_am_attributes(load, &am);
3180 return new_rd_Proj(NULL, current_ir_graph, block, load, mode_vfp, pn_ia32_res);
3182 panic("cannot transform floating point Mux");
3185 assert(ia32_mode_needs_gp_reg(mode));
3187 if (is_Proj(cond)) {
3188 ir_node *cmp = get_Proj_pred(cond);
3190 ir_node *cmp_left = get_Cmp_left(cmp);
3191 ir_node *cmp_right = get_Cmp_right(cmp);
3192 pn_Cmp pnc = get_Proj_proj(cond);
3194 /* check for unsigned Doz first */
3195 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3196 is_Const_0(mux_false) && is_Sub(mux_true) &&
3197 get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
3198 /* Mux(a >=u b, a - b, 0) unsigned Doz */
3199 return create_Doz(node, cmp_left, cmp_right);
3200 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3201 is_Const_0(mux_true) && is_Sub(mux_false) &&
3202 get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
3203 /* Mux(a <=u b, 0, a - b) unsigned Doz */
3204 return create_Doz(node, cmp_left, cmp_right);
3209 flags = get_flags_node(cond, &pnc);
3211 if (is_Const(mux_true) && is_Const(mux_false)) {
3212 /* both are const, good */
3213 if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
3214 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3215 } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
3216 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3218 /* Not that simple. */
3223 new_node = create_CMov(node, cond, flags, pnc);
3231 * Create a conversion from x87 state register to general purpose.
3233 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3235 ir_node *block = be_transform_node(get_nodes_block(node));
3236 ir_node *op = get_Conv_op(node);
3237 ir_node *new_op = be_transform_node(op);
3238 ia32_code_gen_t *cg = env_cg;
3239 ir_graph *irg = current_ir_graph;
3240 dbg_info *dbgi = get_irn_dbg_info(node);
3241 ir_node *noreg = ia32_new_NoReg_gp(cg);
3242 ir_mode *mode = get_irn_mode(node);
3243 ir_node *fist, *load, *mem;
3245 mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3246 set_irn_pinned(fist, op_pin_state_floats);
3247 set_ia32_use_frame(fist);
3248 set_ia32_op_type(fist, ia32_AddrModeD);
3250 assert(get_mode_size_bits(mode) <= 32);
3251 /* exception we can only store signed 32 bit integers, so for unsigned
3252 we store a 64bit (signed) integer and load the lower bits */
3253 if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3254 set_ia32_ls_mode(fist, mode_Ls);
3256 set_ia32_ls_mode(fist, mode_Is);
3258 SET_IA32_ORIG_NODE(fist, node);
3261 load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg, mem);
3263 set_irn_pinned(load, op_pin_state_floats);
3264 set_ia32_use_frame(load);
3265 set_ia32_op_type(load, ia32_AddrModeS);
3266 set_ia32_ls_mode(load, mode_Is);
3267 if (get_ia32_ls_mode(fist) == mode_Ls) {
3268 ia32_attr_t *attr = get_ia32_attr(load);
3269 attr->data.need_64bit_stackent = 1;
3271 ia32_attr_t *attr = get_ia32_attr(load);
3272 attr->data.need_32bit_stackent = 1;
3274 SET_IA32_ORIG_NODE(load, node);
3276 return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3280 * Creates a x87 strict Conv by placing a Store and a Load
3282 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3284 ir_node *block = get_nodes_block(node);
3285 ir_graph *irg = current_ir_graph;
3286 dbg_info *dbgi = get_irn_dbg_info(node);
3287 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3288 ir_node *nomem = new_NoMem();
3289 ir_node *frame = get_irg_frame(irg);
3290 ir_node *store, *load;
3293 store = new_bd_ia32_vfst(dbgi, block, frame, noreg, nomem, node, tgt_mode);
3294 set_ia32_use_frame(store);
3295 set_ia32_op_type(store, ia32_AddrModeD);
3296 SET_IA32_ORIG_NODE(store, node);
3298 load = new_bd_ia32_vfld(dbgi, block, frame, noreg, store, tgt_mode);
3299 set_ia32_use_frame(load);
3300 set_ia32_op_type(load, ia32_AddrModeS);
3301 SET_IA32_ORIG_NODE(load, node);
3303 new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3307 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3308 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3310 ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3312 func = get_mode_size_bits(mode) == 8 ?
3313 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3314 return func(dbgi, block, base, index, mem, val, mode);
3318 * Create a conversion from general purpose to x87 register
3320 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3322 ir_node *src_block = get_nodes_block(node);
3323 ir_node *block = be_transform_node(src_block);
3324 ir_graph *irg = current_ir_graph;
3325 dbg_info *dbgi = get_irn_dbg_info(node);
3326 ir_node *op = get_Conv_op(node);
3327 ir_node *new_op = NULL;
3331 ir_mode *store_mode;
3336 /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3337 if (possible_int_mode_for_fp(src_mode)) {
3338 ia32_address_mode_t am;
3340 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3341 if (am.op_type == ia32_AddrModeS) {
3342 ia32_address_t *addr = &am.addr;
3344 fild = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index,
3346 new_node = new_r_Proj(irg, block, fild, mode_vfp,
3349 set_am_attributes(fild, &am);
3350 SET_IA32_ORIG_NODE(fild, node);
3352 fix_mem_proj(fild, &am);
3357 if (new_op == NULL) {
3358 new_op = be_transform_node(op);
3361 noreg = ia32_new_NoReg_gp(env_cg);
3362 nomem = new_NoMem();
3363 mode = get_irn_mode(op);
3365 /* first convert to 32 bit signed if necessary */
3366 if (get_mode_size_bits(src_mode) < 32) {
3367 if (!upper_bits_clean(new_op, src_mode)) {
3368 new_op = create_Conv_I2I(dbgi, block, noreg, noreg, nomem, new_op, src_mode);
3369 SET_IA32_ORIG_NODE(new_op, node);
3374 assert(get_mode_size_bits(mode) == 32);
3377 store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg, nomem,
3380 set_ia32_use_frame(store);
3381 set_ia32_op_type(store, ia32_AddrModeD);
3382 set_ia32_ls_mode(store, mode_Iu);
3384 /* exception for 32bit unsigned, do a 64bit spill+load */
3385 if (!mode_is_signed(mode)) {
3388 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3390 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3391 noreg, nomem, zero_const);
3393 set_ia32_use_frame(zero_store);
3394 set_ia32_op_type(zero_store, ia32_AddrModeD);
3395 add_ia32_am_offs_int(zero_store, 4);
3396 set_ia32_ls_mode(zero_store, mode_Iu);
3401 store = new_rd_Sync(dbgi, irg, block, 2, in);
3402 store_mode = mode_Ls;
3404 store_mode = mode_Is;
3408 fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg, store);
3410 set_ia32_use_frame(fild);
3411 set_ia32_op_type(fild, ia32_AddrModeS);
3412 set_ia32_ls_mode(fild, store_mode);
3414 new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3420 * Create a conversion from one integer mode into another one
3422 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3423 dbg_info *dbgi, ir_node *block, ir_node *op,
3426 ir_node *new_block = be_transform_node(block);
3428 ir_mode *smaller_mode;
3429 ia32_address_mode_t am;
3430 ia32_address_t *addr = &am.addr;
3433 if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3434 smaller_mode = src_mode;
3436 smaller_mode = tgt_mode;
3439 #ifdef DEBUG_libfirm
3441 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3446 match_arguments(&am, block, NULL, op, NULL,
3447 match_am | match_8bit_am | match_16bit_am);
3449 if (upper_bits_clean(am.new_op2, smaller_mode)) {
3450 /* unnecessary conv. in theory it shouldn't have been AM */
3451 assert(is_ia32_NoReg_GP(addr->base));
3452 assert(is_ia32_NoReg_GP(addr->index));
3453 assert(is_NoMem(addr->mem));
3454 assert(am.addr.offset == 0);
3455 assert(am.addr.symconst_ent == NULL);
3459 new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3460 addr->mem, am.new_op2, smaller_mode);
3461 set_am_attributes(new_node, &am);
3462 /* match_arguments assume that out-mode = in-mode, this isn't true here
3464 set_ia32_ls_mode(new_node, smaller_mode);
3465 SET_IA32_ORIG_NODE(new_node, node);
3466 new_node = fix_mem_proj(new_node, &am);
3471 * Transforms a Conv node.
3473 * @return The created ia32 Conv node
3475 static ir_node *gen_Conv(ir_node *node)
3477 ir_node *block = get_nodes_block(node);
3478 ir_node *new_block = be_transform_node(block);
3479 ir_node *op = get_Conv_op(node);
3480 ir_node *new_op = NULL;
3481 dbg_info *dbgi = get_irn_dbg_info(node);
3482 ir_mode *src_mode = get_irn_mode(op);
3483 ir_mode *tgt_mode = get_irn_mode(node);
3484 int src_bits = get_mode_size_bits(src_mode);
3485 int tgt_bits = get_mode_size_bits(tgt_mode);
3486 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3487 ir_node *nomem = new_NoMem();
3488 ir_node *res = NULL;
3490 assert(!mode_is_int(src_mode) || src_bits <= 32);
3491 assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3493 if (src_mode == mode_b) {
3494 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3495 /* nothing to do, we already model bools as 0/1 ints */
3496 return be_transform_node(op);
3499 if (src_mode == tgt_mode) {
3500 if (get_Conv_strict(node)) {
3501 if (ia32_cg_config.use_sse2) {
3502 /* when we are in SSE mode, we can kill all strict no-op conversion */
3503 return be_transform_node(op);
3506 /* this should be optimized already, but who knows... */
3507 DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3508 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3509 return be_transform_node(op);
3513 if (mode_is_float(src_mode)) {
3514 new_op = be_transform_node(op);
3515 /* we convert from float ... */
3516 if (mode_is_float(tgt_mode)) {
3517 if (src_mode == mode_E && tgt_mode == mode_D
3518 && !get_Conv_strict(node)) {
3519 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3524 if (ia32_cg_config.use_sse2) {
3525 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3526 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg, noreg,
3528 set_ia32_ls_mode(res, tgt_mode);
3530 if (get_Conv_strict(node)) {
3531 res = gen_x87_strict_conv(tgt_mode, new_op);
3532 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3535 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3540 DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3541 if (ia32_cg_config.use_sse2) {
3542 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg, noreg,
3544 set_ia32_ls_mode(res, src_mode);
3546 return gen_x87_fp_to_gp(node);
3550 /* we convert from int ... */
3551 if (mode_is_float(tgt_mode)) {
3553 DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3554 if (ia32_cg_config.use_sse2) {
3555 new_op = be_transform_node(op);
3556 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg, noreg,
3558 set_ia32_ls_mode(res, tgt_mode);
3560 res = gen_x87_gp_to_fp(node, src_mode);
3561 if (get_Conv_strict(node)) {
3562 /* The strict-Conv is only necessary, if the int mode has more bits
3563 * than the float mantissa */
3564 size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3565 size_t float_mantissa;
3566 /* FIXME There is no way to get the mantissa size of a mode */
3567 switch (get_mode_size_bits(tgt_mode)) {
3568 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3569 case 64: float_mantissa = 52 + 1; break;
3571 case 96: float_mantissa = 64; break;
3572 default: float_mantissa = 0; break;
3574 if (float_mantissa < int_mantissa) {
3575 res = gen_x87_strict_conv(tgt_mode, res);
3576 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3581 } else if (tgt_mode == mode_b) {
3582 /* mode_b lowering already took care that we only have 0/1 values */
3583 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3584 src_mode, tgt_mode));
3585 return be_transform_node(op);
3588 if (src_bits == tgt_bits) {
3589 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3590 src_mode, tgt_mode));
3591 return be_transform_node(op);
3594 res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3602 static ir_node *create_immediate_or_transform(ir_node *node,
3603 char immediate_constraint_type)
3605 ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3606 if (new_node == NULL) {
3607 new_node = be_transform_node(node);
3613 * Transforms a FrameAddr into an ia32 Add.
3615 static ir_node *gen_be_FrameAddr(ir_node *node)
3617 ir_node *block = be_transform_node(get_nodes_block(node));
3618 ir_node *op = be_get_FrameAddr_frame(node);
3619 ir_node *new_op = be_transform_node(op);
3620 dbg_info *dbgi = get_irn_dbg_info(node);
3621 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
3624 new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg);
3625 set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3626 set_ia32_use_frame(new_node);
3628 SET_IA32_ORIG_NODE(new_node, node);
3634 * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3636 static ir_node *gen_be_Return(ir_node *node)
3638 ir_graph *irg = current_ir_graph;
3639 ir_node *ret_val = get_irn_n(node, be_pos_Return_val);
3640 ir_node *ret_mem = get_irn_n(node, be_pos_Return_mem);
3641 ir_entity *ent = get_irg_entity(irg);
3642 ir_type *tp = get_entity_type(ent);
3647 ir_node *frame, *sse_store, *fld, *mproj, *barrier;
3648 ir_node *new_barrier, *new_ret_val, *new_ret_mem;
3651 int pn_ret_val, pn_ret_mem, arity, i;
3653 assert(ret_val != NULL);
3654 if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3655 return be_duplicate_node(node);
3658 res_type = get_method_res_type(tp, 0);
3660 if (! is_Primitive_type(res_type)) {
3661 return be_duplicate_node(node);
3664 mode = get_type_mode(res_type);
3665 if (! mode_is_float(mode)) {
3666 return be_duplicate_node(node);
3669 assert(get_method_n_ress(tp) == 1);
3671 pn_ret_val = get_Proj_proj(ret_val);
3672 pn_ret_mem = get_Proj_proj(ret_mem);
3674 /* get the Barrier */
3675 barrier = get_Proj_pred(ret_val);
3677 /* get result input of the Barrier */
3678 ret_val = get_irn_n(barrier, pn_ret_val);
3679 new_ret_val = be_transform_node(ret_val);
3681 /* get memory input of the Barrier */
3682 ret_mem = get_irn_n(barrier, pn_ret_mem);
3683 new_ret_mem = be_transform_node(ret_mem);
3685 frame = get_irg_frame(irg);
3687 dbgi = get_irn_dbg_info(barrier);
3688 block = be_transform_node(get_nodes_block(barrier));
3690 noreg = ia32_new_NoReg_gp(env_cg);
3692 /* store xmm0 onto stack */
3693 sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg,
3694 new_ret_mem, new_ret_val);
3695 set_ia32_ls_mode(sse_store, mode);
3696 set_ia32_op_type(sse_store, ia32_AddrModeD);
3697 set_ia32_use_frame(sse_store);
3699 /* load into x87 register */
3700 fld = new_bd_ia32_vfld(dbgi, block, frame, noreg, sse_store, mode);
3701 set_ia32_op_type(fld, ia32_AddrModeS);
3702 set_ia32_use_frame(fld);
3704 mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3705 fld = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3707 /* create a new barrier */
3708 arity = get_irn_arity(barrier);
3709 in = ALLOCAN(ir_node*, arity);
3710 for (i = 0; i < arity; ++i) {
3713 if (i == pn_ret_val) {
3715 } else if (i == pn_ret_mem) {
3718 ir_node *in = get_irn_n(barrier, i);
3719 new_in = be_transform_node(in);
3724 new_barrier = new_ir_node(dbgi, irg, block,
3725 get_irn_op(barrier), get_irn_mode(barrier),
3727 copy_node_attr(barrier, new_barrier);
3728 be_duplicate_deps(barrier, new_barrier);
3729 be_set_transformed_node(barrier, new_barrier);
3731 /* transform normally */
3732 return be_duplicate_node(node);
3736 * Transform a be_AddSP into an ia32_SubSP.
3738 static ir_node *gen_be_AddSP(ir_node *node)
3740 ir_node *sz = get_irn_n(node, be_pos_AddSP_size);
3741 ir_node *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3743 return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3744 match_am | match_immediate);
3748 * Transform a be_SubSP into an ia32_AddSP
3750 static ir_node *gen_be_SubSP(ir_node *node)
3752 ir_node *sz = get_irn_n(node, be_pos_SubSP_size);
3753 ir_node *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3755 return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3756 match_am | match_immediate);
3760 * Change some phi modes
3762 static ir_node *gen_Phi(ir_node *node)
3764 ir_node *block = be_transform_node(get_nodes_block(node));
3765 ir_graph *irg = current_ir_graph;
3766 dbg_info *dbgi = get_irn_dbg_info(node);
3767 ir_mode *mode = get_irn_mode(node);
3770 if (ia32_mode_needs_gp_reg(mode)) {
3771 /* we shouldn't have any 64bit stuff around anymore */
3772 assert(get_mode_size_bits(mode) <= 32);
3773 /* all integer operations are on 32bit registers now */
3775 } else if (mode_is_float(mode)) {
3776 if (ia32_cg_config.use_sse2) {
3783 /* phi nodes allow loops, so we use the old arguments for now
3784 * and fix this later */
3785 phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3786 get_irn_in(node) + 1);
3787 copy_node_attr(node, phi);
3788 be_duplicate_deps(node, phi);
3790 be_enqueue_preds(node);
3798 static ir_node *gen_IJmp(ir_node *node)
3800 ir_node *block = get_nodes_block(node);
3801 ir_node *new_block = be_transform_node(block);
3802 dbg_info *dbgi = get_irn_dbg_info(node);
3803 ir_node *op = get_IJmp_target(node);
3805 ia32_address_mode_t am;
3806 ia32_address_t *addr = &am.addr;
3808 assert(get_irn_mode(op) == mode_P);
3810 match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3812 new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3813 addr->mem, am.new_op2);
3814 set_am_attributes(new_node, &am);
3815 SET_IA32_ORIG_NODE(new_node, node);
3817 new_node = fix_mem_proj(new_node, &am);
3823 * Transform a Bound node.
3825 static ir_node *gen_Bound(ir_node *node)
3828 ir_node *lower = get_Bound_lower(node);
3829 dbg_info *dbgi = get_irn_dbg_info(node);
3831 if (is_Const_0(lower)) {
3832 /* typical case for Java */
3833 ir_node *sub, *res, *flags, *block;
3834 ir_graph *irg = current_ir_graph;
3836 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3837 new_bd_ia32_Sub, match_mode_neutral | match_am | match_immediate);
3839 block = get_nodes_block(res);
3840 if (! is_Proj(res)) {
3842 set_irn_mode(sub, mode_T);
3843 res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3845 sub = get_Proj_pred(res);
3847 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3848 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3849 SET_IA32_ORIG_NODE(new_node, node);
3851 panic("generic Bound not supported in ia32 Backend");
3857 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3859 ir_node *left = get_irn_n(node, n_ia32_l_ShlDep_val);
3860 ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3862 return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3863 match_immediate | match_mode_neutral);
3866 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3868 ir_node *left = get_irn_n(node, n_ia32_l_ShrDep_val);
3869 ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3870 return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3874 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3876 ir_node *left = get_irn_n(node, n_ia32_l_SarDep_val);
3877 ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3878 return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3882 static ir_node *gen_ia32_l_Add(ir_node *node)
3884 ir_node *left = get_irn_n(node, n_ia32_l_Add_left);
3885 ir_node *right = get_irn_n(node, n_ia32_l_Add_right);
3886 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3887 match_commutative | match_am | match_immediate |
3888 match_mode_neutral);
3890 if (is_Proj(lowered)) {
3891 lowered = get_Proj_pred(lowered);
3893 assert(is_ia32_Add(lowered));
3894 set_irn_mode(lowered, mode_T);
3900 static ir_node *gen_ia32_l_Adc(ir_node *node)
3902 return gen_binop_flags(node, new_bd_ia32_Adc,
3903 match_commutative | match_am | match_immediate |
3904 match_mode_neutral);
3908 * Transforms a l_MulS into a "real" MulS node.
3910 * @return the created ia32 Mul node
3912 static ir_node *gen_ia32_l_Mul(ir_node *node)
3914 ir_node *left = get_binop_left(node);
3915 ir_node *right = get_binop_right(node);
3917 return gen_binop(node, left, right, new_bd_ia32_Mul,
3918 match_commutative | match_am | match_mode_neutral);
3922 * Transforms a l_IMulS into a "real" IMul1OPS node.
3924 * @return the created ia32 IMul1OP node
3926 static ir_node *gen_ia32_l_IMul(ir_node *node)
3928 ir_node *left = get_binop_left(node);
3929 ir_node *right = get_binop_right(node);
3931 return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3932 match_commutative | match_am | match_mode_neutral);
3935 static ir_node *gen_ia32_l_Sub(ir_node *node)
3937 ir_node *left = get_irn_n(node, n_ia32_l_Sub_minuend);
3938 ir_node *right = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3939 ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3940 match_am | match_immediate | match_mode_neutral);
3942 if (is_Proj(lowered)) {
3943 lowered = get_Proj_pred(lowered);
3945 assert(is_ia32_Sub(lowered));
3946 set_irn_mode(lowered, mode_T);
3952 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3954 return gen_binop_flags(node, new_bd_ia32_Sbb,
3955 match_am | match_immediate | match_mode_neutral);
3959 * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3960 * op1 - target to be shifted
3961 * op2 - contains bits to be shifted into target
3963 * Only op3 can be an immediate.
3965 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3966 ir_node *low, ir_node *count)
3968 ir_node *block = get_nodes_block(node);
3969 ir_node *new_block = be_transform_node(block);
3970 dbg_info *dbgi = get_irn_dbg_info(node);
3971 ir_node *new_high = be_transform_node(high);
3972 ir_node *new_low = be_transform_node(low);
3976 /* the shift amount can be any mode that is bigger than 5 bits, since all
3977 * other bits are ignored anyway */
3978 while (is_Conv(count) &&
3979 get_irn_n_edges(count) == 1 &&
3980 mode_is_int(get_irn_mode(count))) {
3981 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3982 count = get_Conv_op(count);
3984 new_count = create_immediate_or_transform(count, 0);
3986 if (is_ia32_l_ShlD(node)) {
3987 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3990 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3993 SET_IA32_ORIG_NODE(new_node, node);
3998 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4000 ir_node *high = get_irn_n(node, n_ia32_l_ShlD_val_high);
4001 ir_node *low = get_irn_n(node, n_ia32_l_ShlD_val_low);
4002 ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4003 return gen_lowered_64bit_shifts(node, high, low, count);
4006 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4008 ir_node *high = get_irn_n(node, n_ia32_l_ShrD_val_high);
4009 ir_node *low = get_irn_n(node, n_ia32_l_ShrD_val_low);
4010 ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4011 return gen_lowered_64bit_shifts(node, high, low, count);
4014 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
4016 ir_node *src_block = get_nodes_block(node);
4017 ir_node *block = be_transform_node(src_block);
4018 ir_graph *irg = current_ir_graph;
4019 dbg_info *dbgi = get_irn_dbg_info(node);
4020 ir_node *frame = get_irg_frame(irg);
4021 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4022 ir_node *nomem = new_NoMem();
4023 ir_node *val_low = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4024 ir_node *val_high = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4025 ir_node *new_val_low = be_transform_node(val_low);
4026 ir_node *new_val_high = be_transform_node(val_high);
4028 ir_node *sync, *fild, *res;
4029 ir_node *store_low, *store_high;
4031 if (ia32_cg_config.use_sse2) {
4032 panic("ia32_l_LLtoFloat not implemented for SSE2");
4036 store_low = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
4038 store_high = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
4040 SET_IA32_ORIG_NODE(store_low, node);
4041 SET_IA32_ORIG_NODE(store_high, node);
4043 set_ia32_use_frame(store_low);
4044 set_ia32_use_frame(store_high);
4045 set_ia32_op_type(store_low, ia32_AddrModeD);
4046 set_ia32_op_type(store_high, ia32_AddrModeD);
4047 set_ia32_ls_mode(store_low, mode_Iu);
4048 set_ia32_ls_mode(store_high, mode_Is);
4049 add_ia32_am_offs_int(store_high, 4);
4053 sync = new_rd_Sync(dbgi, irg, block, 2, in);
4056 fild = new_bd_ia32_vfild(dbgi, block, frame, noreg, sync);
4058 set_ia32_use_frame(fild);
4059 set_ia32_op_type(fild, ia32_AddrModeS);
4060 set_ia32_ls_mode(fild, mode_Ls);
4062 SET_IA32_ORIG_NODE(fild, node);
4064 res = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4066 if (! mode_is_signed(get_irn_mode(val_high))) {
4067 ia32_address_mode_t am;
4069 ir_node *count = create_Immediate(NULL, 0, 31);
4072 am.addr.base = ia32_new_NoReg_gp(env_cg);
4073 am.addr.index = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
4074 am.addr.mem = nomem;
4077 am.addr.symconst_ent = ia32_gen_fp_known_const(ia32_ULLBIAS);
4078 am.addr.use_frame = 0;
4079 am.addr.frame_entity = NULL;
4080 am.addr.symconst_sign = 0;
4081 am.ls_mode = mode_F;
4082 am.mem_proj = nomem;
4083 am.op_type = ia32_AddrModeS;
4085 am.new_op2 = ia32_new_NoReg_vfp(env_cg);
4086 am.pinned = op_pin_state_floats;
4088 am.ins_permuted = 0;
4090 fadd = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
4091 am.new_op1, am.new_op2, get_fpcw());
4092 set_am_attributes(fadd, &am);
4094 set_irn_mode(fadd, mode_T);
4095 res = new_rd_Proj(NULL, irg, block, fadd, mode_vfp, pn_ia32_res);
4100 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
4102 ir_node *src_block = get_nodes_block(node);
4103 ir_node *block = be_transform_node(src_block);
4104 ir_graph *irg = current_ir_graph;
4105 dbg_info *dbgi = get_irn_dbg_info(node);
4106 ir_node *frame = get_irg_frame(irg);
4107 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4108 ir_node *nomem = new_NoMem();
4109 ir_node *val = get_irn_n(node, n_ia32_l_FloattoLL_val);
4110 ir_node *new_val = be_transform_node(val);
4111 ir_node *fist, *mem;
4113 mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4114 SET_IA32_ORIG_NODE(fist, node);
4115 set_ia32_use_frame(fist);
4116 set_ia32_op_type(fist, ia32_AddrModeD);
4117 set_ia32_ls_mode(fist, mode_Ls);
4123 * the BAD transformer.
4125 static ir_node *bad_transform(ir_node *node)
4127 panic("No transform function for %+F available.", node);
4131 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
4133 ir_graph *irg = current_ir_graph;
4134 ir_node *block = be_transform_node(get_nodes_block(node));
4135 ir_node *pred = get_Proj_pred(node);
4136 ir_node *new_pred = be_transform_node(pred);
4137 ir_node *frame = get_irg_frame(irg);
4138 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4139 dbg_info *dbgi = get_irn_dbg_info(node);
4140 long pn = get_Proj_proj(node);
4145 load = new_bd_ia32_Load(dbgi, block, frame, noreg, new_pred);
4146 SET_IA32_ORIG_NODE(load, node);
4147 set_ia32_use_frame(load);
4148 set_ia32_op_type(load, ia32_AddrModeS);
4149 set_ia32_ls_mode(load, mode_Iu);
4150 /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4151 * 32 bit from it with this particular load */
4152 attr = get_ia32_attr(load);
4153 attr->data.need_64bit_stackent = 1;
4155 if (pn == pn_ia32_l_FloattoLL_res_high) {
4156 add_ia32_am_offs_int(load, 4);
4158 assert(pn == pn_ia32_l_FloattoLL_res_low);
4161 proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4167 * Transform the Projs of an AddSP.
4169 static ir_node *gen_Proj_be_AddSP(ir_node *node)
4171 ir_node *block = be_transform_node(get_nodes_block(node));
4172 ir_node *pred = get_Proj_pred(node);
4173 ir_node *new_pred = be_transform_node(pred);
4174 ir_graph *irg = current_ir_graph;
4175 dbg_info *dbgi = get_irn_dbg_info(node);
4176 long proj = get_Proj_proj(node);
4178 if (proj == pn_be_AddSP_sp) {
4179 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4180 pn_ia32_SubSP_stack);
4181 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4183 } else if (proj == pn_be_AddSP_res) {
4184 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4185 pn_ia32_SubSP_addr);
4186 } else if (proj == pn_be_AddSP_M) {
4187 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4190 panic("No idea how to transform proj->AddSP");
4194 * Transform the Projs of a SubSP.
4196 static ir_node *gen_Proj_be_SubSP(ir_node *node)
4198 ir_node *block = be_transform_node(get_nodes_block(node));
4199 ir_node *pred = get_Proj_pred(node);
4200 ir_node *new_pred = be_transform_node(pred);
4201 ir_graph *irg = current_ir_graph;
4202 dbg_info *dbgi = get_irn_dbg_info(node);
4203 long proj = get_Proj_proj(node);
4205 if (proj == pn_be_SubSP_sp) {
4206 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4207 pn_ia32_AddSP_stack);
4208 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4210 } else if (proj == pn_be_SubSP_M) {
4211 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4214 panic("No idea how to transform proj->SubSP");
4218 * Transform and renumber the Projs from a Load.
4220 static ir_node *gen_Proj_Load(ir_node *node)
4223 ir_node *block = be_transform_node(get_nodes_block(node));
4224 ir_node *pred = get_Proj_pred(node);
4225 ir_graph *irg = current_ir_graph;
4226 dbg_info *dbgi = get_irn_dbg_info(node);
4227 long proj = get_Proj_proj(node);
4229 /* loads might be part of source address mode matches, so we don't
4230 * transform the ProjMs yet (with the exception of loads whose result is
4233 if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4236 /* this is needed, because sometimes we have loops that are only
4237 reachable through the ProjM */
4238 be_enqueue_preds(node);
4239 /* do it in 2 steps, to silence firm verifier */
4240 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4241 set_Proj_proj(res, pn_ia32_mem);
4245 /* renumber the proj */
4246 new_pred = be_transform_node(pred);
4247 if (is_ia32_Load(new_pred)) {
4250 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4252 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4253 case pn_Load_X_regular:
4254 return new_rd_Jmp(dbgi, irg, block);
4255 case pn_Load_X_except:
4256 /* This Load might raise an exception. Mark it. */
4257 set_ia32_exc_label(new_pred, 1);
4258 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4262 } else if (is_ia32_Conv_I2I(new_pred) ||
4263 is_ia32_Conv_I2I8Bit(new_pred)) {
4264 set_irn_mode(new_pred, mode_T);
4265 if (proj == pn_Load_res) {
4266 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4267 } else if (proj == pn_Load_M) {
4268 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4270 } else if (is_ia32_xLoad(new_pred)) {
4273 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4275 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4276 case pn_Load_X_regular:
4277 return new_rd_Jmp(dbgi, irg, block);
4278 case pn_Load_X_except:
4279 /* This Load might raise an exception. Mark it. */
4280 set_ia32_exc_label(new_pred, 1);
4281 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4285 } else if (is_ia32_vfld(new_pred)) {
4288 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4290 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4291 case pn_Load_X_regular:
4292 return new_rd_Jmp(dbgi, irg, block);
4293 case pn_Load_X_except:
4294 /* This Load might raise an exception. Mark it. */
4295 set_ia32_exc_label(new_pred, 1);
4296 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4301 /* can happen for ProJMs when source address mode happened for the
4304 /* however it should not be the result proj, as that would mean the
4305 load had multiple users and should not have been used for
4307 if (proj != pn_Load_M) {
4308 panic("internal error: transformed node not a Load");
4310 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4313 panic("No idea how to transform proj");
4317 * Transform and renumber the Projs from a DivMod like instruction.
4319 static ir_node *gen_Proj_DivMod(ir_node *node)
4321 ir_node *block = be_transform_node(get_nodes_block(node));
4322 ir_node *pred = get_Proj_pred(node);
4323 ir_node *new_pred = be_transform_node(pred);
4324 ir_graph *irg = current_ir_graph;
4325 dbg_info *dbgi = get_irn_dbg_info(node);
4326 long proj = get_Proj_proj(node);
4328 assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4330 switch (get_irn_opcode(pred)) {
4334 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4336 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4337 case pn_Div_X_regular:
4338 return new_rd_Jmp(dbgi, irg, block);
4339 case pn_Div_X_except:
4340 set_ia32_exc_label(new_pred, 1);
4341 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4349 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4351 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4352 case pn_Mod_X_except:
4353 set_ia32_exc_label(new_pred, 1);
4354 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4362 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4363 case pn_DivMod_res_div:
4364 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4365 case pn_DivMod_res_mod:
4366 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4367 case pn_DivMod_X_regular:
4368 return new_rd_Jmp(dbgi, irg, block);
4369 case pn_DivMod_X_except:
4370 set_ia32_exc_label(new_pred, 1);
4371 return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4380 panic("No idea how to transform proj->DivMod");
4384 * Transform and renumber the Projs from a CopyB.
4386 static ir_node *gen_Proj_CopyB(ir_node *node)
4388 ir_node *block = be_transform_node(get_nodes_block(node));
4389 ir_node *pred = get_Proj_pred(node);
4390 ir_node *new_pred = be_transform_node(pred);
4391 ir_graph *irg = current_ir_graph;
4392 dbg_info *dbgi = get_irn_dbg_info(node);
4393 long proj = get_Proj_proj(node);
4396 case pn_CopyB_M_regular:
4397 if (is_ia32_CopyB_i(new_pred)) {
4398 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4399 } else if (is_ia32_CopyB(new_pred)) {
4400 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4407 panic("No idea how to transform proj->CopyB");
4411 * Transform and renumber the Projs from a Quot.
4413 static ir_node *gen_Proj_Quot(ir_node *node)
4415 ir_node *block = be_transform_node(get_nodes_block(node));
4416 ir_node *pred = get_Proj_pred(node);
4417 ir_node *new_pred = be_transform_node(pred);
4418 ir_graph *irg = current_ir_graph;
4419 dbg_info *dbgi = get_irn_dbg_info(node);
4420 long proj = get_Proj_proj(node);
4424 if (is_ia32_xDiv(new_pred)) {
4425 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4426 } else if (is_ia32_vfdiv(new_pred)) {
4427 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4431 if (is_ia32_xDiv(new_pred)) {
4432 return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4433 } else if (is_ia32_vfdiv(new_pred)) {
4434 return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4437 case pn_Quot_X_regular:
4438 case pn_Quot_X_except:
4443 panic("No idea how to transform proj->Quot");
4446 static ir_node *gen_be_Call(ir_node *node)
4448 dbg_info *const dbgi = get_irn_dbg_info(node);
4449 ir_graph *const irg = current_ir_graph;
4450 ir_node *const src_block = get_nodes_block(node);
4451 ir_node *const block = be_transform_node(src_block);
4452 ir_node *const src_mem = get_irn_n(node, be_pos_Call_mem);
4453 ir_node *const src_sp = get_irn_n(node, be_pos_Call_sp);
4454 ir_node *const sp = be_transform_node(src_sp);
4455 ir_node *const src_ptr = get_irn_n(node, be_pos_Call_ptr);
4456 ir_node *const noreg = ia32_new_NoReg_gp(env_cg);
4457 ia32_address_mode_t am;
4458 ia32_address_t *const addr = &am.addr;
4463 ir_node * eax = noreg;
4464 ir_node * ecx = noreg;
4465 ir_node * edx = noreg;
4466 unsigned const pop = be_Call_get_pop(node);
4467 ir_type *const call_tp = be_Call_get_type(node);
4469 /* Run the x87 simulator if the call returns a float value */
4470 if (get_method_n_ress(call_tp) > 0) {
4471 ir_type *const res_type = get_method_res_type(call_tp, 0);
4472 ir_mode *const res_mode = get_type_mode(res_type);
4474 if (res_mode != NULL && mode_is_float(res_mode)) {
4475 env_cg->do_x87_sim = 1;
4479 /* We do not want be_Call direct calls */
4480 assert(be_Call_get_entity(node) == NULL);
4482 match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4483 match_am | match_immediate);
4485 i = get_irn_arity(node) - 1;
4486 fpcw = be_transform_node(get_irn_n(node, i--));
4487 for (; i >= be_pos_Call_first_arg; --i) {
4488 arch_register_req_t const *const req = arch_get_register_req(node, i);
4489 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4491 assert(req->type == arch_register_req_type_limited);
4492 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4494 switch (*req->limited) {
4495 case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4496 case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4497 case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4498 default: panic("Invalid GP register for register parameter");
4502 mem = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4503 call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4504 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4505 set_am_attributes(call, &am);
4506 call = fix_mem_proj(call, &am);
4508 if (get_irn_pinned(node) == op_pin_state_pinned)
4509 set_irn_pinned(call, op_pin_state_pinned);
4511 SET_IA32_ORIG_NODE(call, node);
4515 static ir_node *gen_be_IncSP(ir_node *node)
4517 ir_node *res = be_duplicate_node(node);
4518 arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4524 * Transform the Projs from a be_Call.
4526 static ir_node *gen_Proj_be_Call(ir_node *node)
4528 ir_node *block = be_transform_node(get_nodes_block(node));
4529 ir_node *call = get_Proj_pred(node);
4530 ir_node *new_call = be_transform_node(call);
4531 ir_graph *irg = current_ir_graph;
4532 dbg_info *dbgi = get_irn_dbg_info(node);
4533 ir_type *method_type = be_Call_get_type(call);
4534 int n_res = get_method_n_ress(method_type);
4535 long proj = get_Proj_proj(node);
4536 ir_mode *mode = get_irn_mode(node);
4540 /* The following is kinda tricky: If we're using SSE, then we have to
4541 * move the result value of the call in floating point registers to an
4542 * xmm register, we therefore construct a GetST0 -> xLoad sequence
4543 * after the call, we have to make sure to correctly make the
4544 * MemProj and the result Proj use these 2 nodes
4546 if (proj == pn_be_Call_M_regular) {
4547 // get new node for result, are we doing the sse load/store hack?
4548 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4549 ir_node *call_res_new;
4550 ir_node *call_res_pred = NULL;
4552 if (call_res != NULL) {
4553 call_res_new = be_transform_node(call_res);
4554 call_res_pred = get_Proj_pred(call_res_new);
4557 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4558 return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4561 assert(is_ia32_xLoad(call_res_pred));
4562 return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4566 if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4567 && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4569 ir_node *frame = get_irg_frame(irg);
4570 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4572 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4575 /* in case there is no memory output: create one to serialize the copy
4577 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4578 pn_be_Call_M_regular);
4579 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4580 pn_be_Call_first_res);
4582 /* store st(0) onto stack */
4583 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg, call_mem,
4585 set_ia32_op_type(fstp, ia32_AddrModeD);
4586 set_ia32_use_frame(fstp);
4588 /* load into SSE register */
4589 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg, fstp, mode);
4590 set_ia32_op_type(sse_load, ia32_AddrModeS);
4591 set_ia32_use_frame(sse_load);
4593 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4599 /* transform call modes */
4600 if (mode_is_data(mode)) {
4601 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4605 /* Map from be_Call to ia32_Call proj number */
4606 if (proj == pn_be_Call_sp) {
4607 proj = pn_ia32_Call_stack;
4608 } else if (proj == pn_be_Call_M_regular) {
4609 proj = pn_ia32_Call_M;
4611 arch_register_req_t const *const req = arch_get_register_req_out(node);
4612 int const n_outs = arch_irn_get_n_outs(new_call);
4615 assert(proj >= pn_be_Call_first_res);
4616 assert(req->type & arch_register_req_type_limited);
4618 for (i = 0; i < n_outs; ++i) {
4619 arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4621 if (!(new_req->type & arch_register_req_type_limited) ||
4622 new_req->cls != req->cls ||
4623 *new_req->limited != *req->limited)
4632 res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4634 /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4636 case pn_ia32_Call_stack:
4637 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4640 case pn_ia32_Call_fpcw:
4641 arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4649 * Transform the Projs from a Cmp.
4651 static ir_node *gen_Proj_Cmp(ir_node *node)
4653 /* this probably means not all mode_b nodes were lowered... */
4654 panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4659 * Transform the Projs from a Bound.
4661 static ir_node *gen_Proj_Bound(ir_node *node)
4663 ir_node *new_node, *block;
4664 ir_node *pred = get_Proj_pred(node);
4666 switch (get_Proj_proj(node)) {
4668 return be_transform_node(get_Bound_mem(pred));
4669 case pn_Bound_X_regular:
4670 new_node = be_transform_node(pred);
4671 block = get_nodes_block(new_node);
4672 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4673 case pn_Bound_X_except:
4674 new_node = be_transform_node(pred);
4675 block = get_nodes_block(new_node);
4676 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4678 return be_transform_node(get_Bound_index(pred));
4680 panic("unsupported Proj from Bound");
4684 static ir_node *gen_Proj_ASM(ir_node *node)
4690 if (get_irn_mode(node) != mode_M)
4691 return be_duplicate_node(node);
4693 pred = get_Proj_pred(node);
4694 new_pred = be_transform_node(pred);
4695 block = get_nodes_block(new_pred);
4696 return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4697 arch_irn_get_n_outs(new_pred) + 1);
4701 * Transform and potentially renumber Proj nodes.
4703 static ir_node *gen_Proj(ir_node *node)
4705 ir_node *pred = get_Proj_pred(node);
4708 switch (get_irn_opcode(pred)) {
4710 proj = get_Proj_proj(node);
4711 if (proj == pn_Store_M) {
4712 return be_transform_node(pred);
4714 panic("No idea how to transform proj->Store");
4717 return gen_Proj_Load(node);
4719 return gen_Proj_ASM(node);
4723 return gen_Proj_DivMod(node);
4725 return gen_Proj_CopyB(node);
4727 return gen_Proj_Quot(node);
4729 return gen_Proj_be_SubSP(node);
4731 return gen_Proj_be_AddSP(node);
4733 return gen_Proj_be_Call(node);
4735 return gen_Proj_Cmp(node);
4737 return gen_Proj_Bound(node);
4739 proj = get_Proj_proj(node);
4741 case pn_Start_X_initial_exec: {
4742 ir_node *block = get_nodes_block(pred);
4743 ir_node *new_block = be_transform_node(block);
4744 dbg_info *dbgi = get_irn_dbg_info(node);
4745 /* we exchange the ProjX with a jump */
4746 ir_node *jump = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4751 case pn_Start_P_tls:
4752 return gen_Proj_tls(node);
4757 if (is_ia32_l_FloattoLL(pred)) {
4758 return gen_Proj_l_FloattoLL(node);
4760 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4764 ir_mode *mode = get_irn_mode(node);
4765 if (ia32_mode_needs_gp_reg(mode)) {
4766 ir_node *new_pred = be_transform_node(pred);
4767 ir_node *block = be_transform_node(get_nodes_block(node));
4768 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4769 mode_Iu, get_Proj_proj(node));
4770 #ifdef DEBUG_libfirm
4771 new_proj->node_nr = node->node_nr;
4777 return be_duplicate_node(node);
4781 * Enters all transform functions into the generic pointer
4783 static void register_transformers(void)
4787 /* first clear the generic function pointer for all ops */
4788 clear_irp_opcodes_generic_func();
4790 #define GEN(a) { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4791 #define BAD(a) op_##a->ops.generic = (op_func)bad_transform
4829 /* transform ops from intrinsic lowering */
4841 GEN(ia32_l_LLtoFloat);
4842 GEN(ia32_l_FloattoLL);
4848 /* we should never see these nodes */
4863 /* handle generic backend nodes */
4872 op_Mulh = get_op_Mulh();
4881 * Pre-transform all unknown and noreg nodes.
4883 static void ia32_pretransform_node(void)
4885 ia32_code_gen_t *cg = env_cg;
4887 cg->unknown_gp = be_pre_transform_node(cg->unknown_gp);
4888 cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4889 cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4890 cg->noreg_gp = be_pre_transform_node(cg->noreg_gp);
4891 cg->noreg_vfp = be_pre_transform_node(cg->noreg_vfp);
4892 cg->noreg_xmm = be_pre_transform_node(cg->noreg_xmm);
4897 * Walker, checks if all ia32 nodes producing more than one result have their
4898 * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4900 static void add_missing_keep_walker(ir_node *node, void *data)
4903 unsigned found_projs = 0;
4904 const ir_edge_t *edge;
4905 ir_mode *mode = get_irn_mode(node);
4910 if (!is_ia32_irn(node))
4913 n_outs = arch_irn_get_n_outs(node);
4916 if (is_ia32_SwitchJmp(node))
4919 assert(n_outs < (int) sizeof(unsigned) * 8);
4920 foreach_out_edge(node, edge) {
4921 ir_node *proj = get_edge_src_irn(edge);
4924 /* The node could be kept */
4928 if (get_irn_mode(proj) == mode_M)
4931 pn = get_Proj_proj(proj);
4932 assert(pn < n_outs);
4933 found_projs |= 1 << pn;
4937 /* are keeps missing? */
4939 for (i = 0; i < n_outs; ++i) {
4942 const arch_register_req_t *req;
4943 const arch_register_class_t *cls;
4945 if (found_projs & (1 << i)) {
4949 req = get_ia32_out_req(node, i);
4954 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4958 block = get_nodes_block(node);
4959 in[0] = new_r_Proj(current_ir_graph, block, node,
4960 arch_register_class_mode(cls), i);
4961 if (last_keep != NULL) {
4962 be_Keep_add_node(last_keep, cls, in[0]);
4964 last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4965 if (sched_is_scheduled(node)) {
4966 sched_add_after(node, last_keep);
4973 * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4976 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4978 ir_graph *irg = be_get_birg_irg(cg->birg);
4979 irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4982 /* do the transformation */
4983 void ia32_transform_graph(ia32_code_gen_t *cg)
4987 register_transformers();
4989 initial_fpcw = NULL;
4991 BE_TIMER_PUSH(t_heights);
4992 heights = heights_new(cg->irg);
4993 BE_TIMER_POP(t_heights);
4994 ia32_calculate_non_address_mode_nodes(cg->birg);
4996 /* the transform phase is not safe for CSE (yet) because several nodes get
4997 * attributes set after their creation */
4998 cse_last = get_opt_cse();
5001 be_transform_graph(cg->birg, ia32_pretransform_node);
5003 set_opt_cse(cse_last);
5005 ia32_free_non_address_mode_nodes();
5006 heights_free(heights);
5010 void ia32_init_transform(void)
5012 FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");