Defer decision whether to create Test(x, x) instead of Cmp(x, 0) until peephole optim...
[libfirm] / ir / be / ia32 / ia32_transform.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
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.
10  *
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.
14  *
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
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       This file implements the IR transformation from firm into
23  *              ia32-Firm.
24  * @author      Christian Wuerdig, Matthias Braun
25  * @version     $Id$
26  */
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <limits.h>
32
33 #include "irargs_t.h"
34 #include "irnode_t.h"
35 #include "irgraph_t.h"
36 #include "irmode_t.h"
37 #include "iropt_t.h"
38 #include "irop_t.h"
39 #include "irprog_t.h"
40 #include "iredges_t.h"
41 #include "irgmod.h"
42 #include "irvrfy.h"
43 #include "ircons.h"
44 #include "irgwalk.h"
45 #include "irprintf.h"
46 #include "debug.h"
47 #include "irdom.h"
48 #include "archop.h"
49 #include "error.h"
50 #include "height.h"
51
52 #include "../benode_t.h"
53 #include "../besched.h"
54 #include "../beabi.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
58 #include "../be_t.h"
59
60 #include "bearch_ia32_t.h"
61 #include "ia32_common_transform.h"
62 #include "ia32_nodes_attr.h"
63 #include "ia32_transform.h"
64 #include "ia32_new_nodes.h"
65 #include "ia32_map_regs.h"
66 #include "ia32_dbg_stat.h"
67 #include "ia32_optimize.h"
68 #include "ia32_util.h"
69 #include "ia32_address_mode.h"
70 #include "ia32_architecture.h"
71
72 #include "gen_ia32_regalloc_if.h"
73
74 #define SFP_SIGN   "0x80000000"
75 #define DFP_SIGN   "0x8000000000000000"
76 #define SFP_ABS    "0x7FFFFFFF"
77 #define DFP_ABS    "0x7FFFFFFFFFFFFFFF"
78 #define DFP_INTMAX "9223372036854775807"
79
80 #define TP_SFP_SIGN "ia32_sfp_sign"
81 #define TP_DFP_SIGN "ia32_dfp_sign"
82 #define TP_SFP_ABS  "ia32_sfp_abs"
83 #define TP_DFP_ABS  "ia32_dfp_abs"
84 #define TP_INT_MAX  "ia32_int_max"
85
86 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
87 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
88 #define ENT_SFP_ABS  "IA32_SFP_ABS"
89 #define ENT_DFP_ABS  "IA32_DFP_ABS"
90 #define ENT_INT_MAX  "IA32_INT_MAX"
91
92 #define mode_vfp        (ia32_reg_classes[CLASS_ia32_vfp].mode)
93 #define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)
94
95 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
96
97 static ir_node         *initial_fpcw = NULL;
98
99 extern ir_op *get_op_Mulh(void);
100
101 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
102         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
103         ir_node *op1, ir_node *op2);
104
105 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
106         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
107         ir_node *op1, ir_node *op2, ir_node *flags);
108
109 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
110         ir_node *block, ir_node *op1, ir_node *op2);
111
112 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
113         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
114         ir_node *op);
115
116 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
117         ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
118
119 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
120         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
121         ir_node *op1, ir_node *op2, ir_node *fpcw);
122
123 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
124         ir_node *block, ir_node *op);
125
126 static ir_node *create_immediate_or_transform(ir_node *node,
127                                               char immediate_constraint_type);
128
129 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
130                                 dbg_info *dbgi, ir_node *block,
131                                 ir_node *op, ir_node *orig_node);
132
133 /** Return non-zero is a node represents the 0 constant. */
134 static int is_Const_0(ir_node *node) {
135         return is_Const(node) && is_Const_null(node);
136 }
137
138 /** Return non-zero is a node represents the 1 constant. */
139 static int is_Const_1(ir_node *node) {
140         return is_Const(node) && is_Const_one(node);
141 }
142
143 /** Return non-zero is a node represents the -1 constant. */
144 static int is_Const_Minus_1(ir_node *node) {
145         return is_Const(node) && is_Const_all_one(node);
146 }
147
148 /**
149  * returns true if constant can be created with a simple float command
150  */
151 static int is_simple_x87_Const(ir_node *node)
152 {
153         tarval *tv = get_Const_tarval(node);
154         if (tarval_is_null(tv) || tarval_is_one(tv))
155                 return 1;
156
157         /* TODO: match all the other float constants */
158         return 0;
159 }
160
161 /**
162  * returns true if constant can be created with a simple float command
163  */
164 static int is_simple_sse_Const(ir_node *node)
165 {
166         tarval  *tv   = get_Const_tarval(node);
167         ir_mode *mode = get_tarval_mode(tv);
168
169         if (mode == mode_F)
170                 return 1;
171
172         if (tarval_is_null(tv) || tarval_is_one(tv))
173                 return 1;
174
175         if (mode == mode_D) {
176                 unsigned val = get_tarval_sub_bits(tv, 0) |
177                         (get_tarval_sub_bits(tv, 1) << 8) |
178                         (get_tarval_sub_bits(tv, 2) << 16) |
179                         (get_tarval_sub_bits(tv, 3) << 24);
180                 if (val == 0)
181                         /* lower 32bit are zero, really a 32bit constant */
182                         return 1;
183         }
184
185         /* TODO: match all the other float constants */
186         return 0;
187 }
188
189 /**
190  * Transforms a Const.
191  */
192 static ir_node *gen_Const(ir_node *node) {
193         ir_graph        *irg   = current_ir_graph;
194         ir_node         *old_block = get_nodes_block(node);
195         ir_node         *block = be_transform_node(old_block);
196         dbg_info        *dbgi  = get_irn_dbg_info(node);
197         ir_mode         *mode  = get_irn_mode(node);
198
199         assert(is_Const(node));
200
201         if (mode_is_float(mode)) {
202                 ir_node   *res   = NULL;
203                 ir_node   *noreg = ia32_new_NoReg_gp(env_cg);
204                 ir_node   *nomem = new_NoMem();
205                 ir_node   *load;
206                 ir_entity *floatent;
207
208                 if (ia32_cg_config.use_sse2) {
209                         tarval *tv = get_Const_tarval(node);
210                         if (tarval_is_null(tv)) {
211                                 load = new_rd_ia32_xZero(dbgi, irg, block);
212                                 set_ia32_ls_mode(load, mode);
213                                 res  = load;
214                         } else if (tarval_is_one(tv)) {
215                                 int     cnst  = mode == mode_F ? 26 : 55;
216                                 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
217                                 ir_node *imm2 = create_Immediate(NULL, 0, 2);
218                                 ir_node *pslld, *psrld;
219
220                                 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
221                                 set_ia32_ls_mode(load, mode);
222                                 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
223                                 set_ia32_ls_mode(pslld, mode);
224                                 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
225                                 set_ia32_ls_mode(psrld, mode);
226                                 res = psrld;
227                         } else if (mode == mode_F) {
228                                 /* we can place any 32bit constant by using a movd gp, sse */
229                                 unsigned val = get_tarval_sub_bits(tv, 0) |
230                                                (get_tarval_sub_bits(tv, 1) << 8) |
231                                                (get_tarval_sub_bits(tv, 2) << 16) |
232                                                (get_tarval_sub_bits(tv, 3) << 24);
233                                 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
234                                 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
235                                 set_ia32_ls_mode(load, mode);
236                                 res = load;
237                         } else {
238                                 if (mode == mode_D) {
239                                         unsigned val = get_tarval_sub_bits(tv, 0) |
240                                                 (get_tarval_sub_bits(tv, 1) << 8) |
241                                                 (get_tarval_sub_bits(tv, 2) << 16) |
242                                                 (get_tarval_sub_bits(tv, 3) << 24);
243                                         if (val == 0) {
244                                                 ir_node *imm32 = create_Immediate(NULL, 0, 32);
245                                                 ir_node *cnst, *psllq;
246
247                                                 /* fine, lower 32bit are zero, produce 32bit value */
248                                                 val = get_tarval_sub_bits(tv, 4) |
249                                                         (get_tarval_sub_bits(tv, 5) << 8) |
250                                                         (get_tarval_sub_bits(tv, 6) << 16) |
251                                                         (get_tarval_sub_bits(tv, 7) << 24);
252                                                 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
253                                                 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
254                                                 set_ia32_ls_mode(load, mode);
255                                                 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
256                                                 set_ia32_ls_mode(psllq, mode);
257                                                 res = psllq;
258                                                 goto end;
259                                         }
260                                 }
261                                 floatent = create_float_const_entity(node);
262
263                                 load     = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
264                                                              mode);
265                                 set_ia32_op_type(load, ia32_AddrModeS);
266                                 set_ia32_am_sc(load, floatent);
267                                 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
268                                 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
269                         }
270                 } else {
271                         if (is_Const_null(node)) {
272                                 load = new_rd_ia32_vfldz(dbgi, irg, block);
273                                 res  = load;
274                                 set_ia32_ls_mode(load, mode);
275                         } else if (is_Const_one(node)) {
276                                 load = new_rd_ia32_vfld1(dbgi, irg, block);
277                                 res  = load;
278                                 set_ia32_ls_mode(load, mode);
279                         } else {
280                                 floatent = create_float_const_entity(node);
281
282                                 load     = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
283                                 set_ia32_op_type(load, ia32_AddrModeS);
284                                 set_ia32_am_sc(load, floatent);
285                                 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
286                                 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
287                                 /* take the mode from the entity */
288                                 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
289                         }
290                 }
291 end:
292                 /* Const Nodes before the initial IncSP are a bad idea, because
293                  * they could be spilled and we have no SP ready at that point yet.
294                  * So add a dependency to the initial frame pointer calculation to
295                  * avoid that situation.
296                  */
297                 if (get_irg_start_block(irg) == block) {
298                         add_irn_dep(load, get_irg_frame(irg));
299                 }
300
301                 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
302                 return res;
303         } else { /* non-float mode */
304                 ir_node *cnst;
305                 tarval  *tv = get_Const_tarval(node);
306                 long     val;
307
308                 tv = tarval_convert_to(tv, mode_Iu);
309
310                 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
311                     tv == NULL) {
312                         panic("couldn't convert constant tarval (%+F)", node);
313                 }
314                 val = get_tarval_long(tv);
315
316                 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
317                 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
318
319                 /* see above */
320                 if (get_irg_start_block(irg) == block) {
321                         add_irn_dep(cnst, get_irg_frame(irg));
322                 }
323
324                 return cnst;
325         }
326 }
327
328 /**
329  * Transforms a SymConst.
330  */
331 static ir_node *gen_SymConst(ir_node *node) {
332         ir_graph *irg   = current_ir_graph;
333         ir_node  *old_block = get_nodes_block(node);
334         ir_node  *block = be_transform_node(old_block);
335         dbg_info *dbgi  = get_irn_dbg_info(node);
336         ir_mode  *mode  = get_irn_mode(node);
337         ir_node  *cnst;
338
339         if (mode_is_float(mode)) {
340                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
341                 ir_node *nomem = new_NoMem();
342
343                 if (ia32_cg_config.use_sse2)
344                         cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
345                 else
346                         cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
347                 set_ia32_am_sc(cnst, get_SymConst_entity(node));
348                 set_ia32_use_frame(cnst);
349         } else {
350                 ir_entity *entity;
351
352                 if(get_SymConst_kind(node) != symconst_addr_ent) {
353                         panic("backend only support symconst_addr_ent (at %+F)", node);
354                 }
355                 entity = get_SymConst_entity(node);
356                 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
357         }
358
359         /* Const Nodes before the initial IncSP are a bad idea, because
360          * they could be spilled and we have no SP ready at that point yet
361          */
362         if (get_irg_start_block(irg) == block) {
363                 add_irn_dep(cnst, get_irg_frame(irg));
364         }
365
366         SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
367
368         return cnst;
369 }
370
371 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
372 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
373         static const struct {
374                 const char *tp_name;
375                 const char *ent_name;
376                 const char *cnst_str;
377                 char mode;
378                 char align;
379         } names [ia32_known_const_max] = {
380                 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN,   0, 16 },       /* ia32_SSIGN */
381                 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN,   1, 16 },       /* ia32_DSIGN */
382                 { TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS,    0, 16 },       /* ia32_SABS */
383                 { TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS,    1, 16 },       /* ia32_DABS */
384                 { TP_INT_MAX,  ENT_INT_MAX,  DFP_INTMAX, 2, 4 }         /* ia32_INTMAX */
385         };
386         static ir_entity *ent_cache[ia32_known_const_max];
387
388         const char    *tp_name, *ent_name, *cnst_str;
389         ir_type       *tp;
390         ir_node       *cnst;
391         ir_graph      *rem;
392         ir_entity     *ent;
393         tarval        *tv;
394         ir_mode       *mode;
395
396         ent_name = names[kct].ent_name;
397         if (! ent_cache[kct]) {
398                 tp_name  = names[kct].tp_name;
399                 cnst_str = names[kct].cnst_str;
400
401                 switch (names[kct].mode) {
402                 case 0:  mode = mode_Iu; break;
403                 case 1:  mode = mode_Lu; break;
404                 default: mode = mode_F; break;
405                 }
406                 tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
407                 tp  = new_type_primitive(new_id_from_str(tp_name), mode);
408                 /* set the specified alignment */
409                 set_type_alignment_bytes(tp, names[kct].align);
410
411                 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
412
413                 set_entity_ld_ident(ent, get_entity_ident(ent));
414                 set_entity_visibility(ent, visibility_local);
415                 set_entity_variability(ent, variability_constant);
416                 set_entity_allocation(ent, allocation_static);
417
418                 /* we create a new entity here: It's initialization must resist on the
419                     const code irg */
420                 rem = current_ir_graph;
421                 current_ir_graph = get_const_code_irg();
422                 cnst = new_Const(mode, tv);
423                 current_ir_graph = rem;
424
425                 set_atomic_ent_value(ent, cnst);
426
427                 /* cache the entry */
428                 ent_cache[kct] = ent;
429         }
430
431         return ent_cache[kct];
432 }
433
434 /**
435  * return true if the node is a Proj(Load) and could be used in source address
436  * mode for another node. Will return only true if the @p other node is not
437  * dependent on the memory of the Load (for binary operations use the other
438  * input here, for unary operations use NULL).
439  */
440 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
441                                         ir_node *other, ir_node *other2, match_flags_t flags)
442 {
443         ir_node *load;
444         long     pn;
445
446         /* float constants are always available */
447         if (is_Const(node)) {
448                 ir_mode *mode = get_irn_mode(node);
449                 if (mode_is_float(mode)) {
450                         if (ia32_cg_config.use_sse2) {
451                                 if (is_simple_sse_Const(node))
452                                         return 0;
453                         } else {
454                                 if (is_simple_x87_Const(node))
455                                         return 0;
456                         }
457                         if (get_irn_n_edges(node) > 1)
458                                 return 0;
459                         return 1;
460                 }
461         }
462
463         if (!is_Proj(node))
464                 return 0;
465         load = get_Proj_pred(node);
466         pn   = get_Proj_proj(node);
467         if (!is_Load(load) || pn != pn_Load_res)
468                 return 0;
469         if (get_nodes_block(load) != block)
470                 return 0;
471         /* we only use address mode if we're the only user of the load */
472         if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
473                 return 0;
474         /* in some edge cases with address mode we might reach the load normally
475          * and through some AM sequence, if it is already materialized then we
476          * can't create an AM node from it */
477         if (be_is_transformed(node))
478                 return 0;
479
480         /* don't do AM if other node inputs depend on the load (via mem-proj) */
481         if (other != NULL && get_nodes_block(other) == block &&
482             heights_reachable_in_block(heights, other, load))
483                 return 0;
484         if (other2 != NULL && get_nodes_block(other2) == block &&
485             heights_reachable_in_block(heights, other2, load))
486                 return 0;
487
488         return 1;
489 }
490
491 typedef struct ia32_address_mode_t ia32_address_mode_t;
492 struct ia32_address_mode_t {
493         ia32_address_t  addr;
494         ir_mode        *ls_mode;
495         ir_node        *mem_proj;
496         ia32_op_type_t  op_type;
497         ir_node        *new_op1;
498         ir_node        *new_op2;
499         op_pin_state    pinned;
500         unsigned        commutative  : 1;
501         unsigned        ins_permuted : 1;
502 };
503
504 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
505 {
506         ir_node *noreg_gp;
507
508         /* construct load address */
509         memset(addr, 0, sizeof(addr[0]));
510         ia32_create_address_mode(addr, ptr, /*force=*/0);
511
512         noreg_gp    = ia32_new_NoReg_gp(env_cg);
513         addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_gp;
514         addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
515         addr->mem   = be_transform_node(mem);
516 }
517
518 static void build_address(ia32_address_mode_t *am, ir_node *node)
519 {
520         ir_node        *noreg_gp = ia32_new_NoReg_gp(env_cg);
521         ia32_address_t *addr     = &am->addr;
522         ir_node        *load;
523         ir_node        *ptr;
524         ir_node        *mem;
525         ir_node        *new_mem;
526
527         if (is_Const(node)) {
528                 ir_entity *entity  = create_float_const_entity(node);
529                 addr->base         = noreg_gp;
530                 addr->index        = noreg_gp;
531                 addr->mem          = new_NoMem();
532                 addr->symconst_ent = entity;
533                 addr->use_frame    = 1;
534                 am->ls_mode        = get_type_mode(get_entity_type(entity));
535                 am->pinned         = op_pin_state_floats;
536                 return;
537         }
538
539         load         = get_Proj_pred(node);
540         ptr          = get_Load_ptr(load);
541         mem          = get_Load_mem(load);
542         new_mem      = be_transform_node(mem);
543         am->pinned   = get_irn_pinned(load);
544         am->ls_mode  = get_Load_mode(load);
545         am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
546
547         /* construct load address */
548         ia32_create_address_mode(addr, ptr, /*force=*/0);
549
550         addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_gp;
551         addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
552         addr->mem   = new_mem;
553 }
554
555 static void set_address(ir_node *node, const ia32_address_t *addr)
556 {
557         set_ia32_am_scale(node, addr->scale);
558         set_ia32_am_sc(node, addr->symconst_ent);
559         set_ia32_am_offs_int(node, addr->offset);
560         if(addr->symconst_sign)
561                 set_ia32_am_sc_sign(node);
562         if(addr->use_frame)
563                 set_ia32_use_frame(node);
564         set_ia32_frame_ent(node, addr->frame_entity);
565 }
566
567 /**
568  * Apply attributes of a given address mode to a node.
569  */
570 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
571 {
572         set_address(node, &am->addr);
573
574         set_ia32_op_type(node, am->op_type);
575         set_ia32_ls_mode(node, am->ls_mode);
576         if (am->pinned == op_pin_state_pinned) {
577                 /* beware: some nodes are already pinned and did not allow to change the state */
578                 if (get_irn_pinned(node) != op_pin_state_pinned)
579                         set_irn_pinned(node, op_pin_state_pinned);
580         }
581         if (am->commutative)
582                 set_ia32_commutative(node);
583 }
584
585 /**
586  * Check, if a given node is a Down-Conv, ie. a integer Conv
587  * from a mode with a mode with more bits to a mode with lesser bits.
588  * Moreover, we return only true if the node has not more than 1 user.
589  *
590  * @param node   the node
591  * @return non-zero if node is a Down-Conv
592  */
593 static int is_downconv(const ir_node *node)
594 {
595         ir_mode *src_mode;
596         ir_mode *dest_mode;
597
598         if(!is_Conv(node))
599                 return 0;
600
601         /* we only want to skip the conv when we're the only user
602          * (not optimal but for now...)
603          */
604         if(get_irn_n_edges(node) > 1)
605                 return 0;
606
607         src_mode  = get_irn_mode(get_Conv_op(node));
608         dest_mode = get_irn_mode(node);
609         return ia32_mode_needs_gp_reg(src_mode)
610                 && ia32_mode_needs_gp_reg(dest_mode)
611                 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
612 }
613
614 /* Skip all Down-Conv's on a given node and return the resulting node. */
615 ir_node *ia32_skip_downconv(ir_node *node) {
616         while (is_downconv(node))
617                 node = get_Conv_op(node);
618
619         return node;
620 }
621
622 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
623 {
624         ir_mode  *mode = get_irn_mode(node);
625         ir_node  *block;
626         ir_mode  *tgt_mode;
627         dbg_info *dbgi;
628
629         if(mode_is_signed(mode)) {
630                 tgt_mode = mode_Is;
631         } else {
632                 tgt_mode = mode_Iu;
633         }
634         block = get_nodes_block(node);
635         dbgi  = get_irn_dbg_info(node);
636
637         return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
638 }
639
640 /**
641  * matches operands of a node into ia32 addressing/operand modes. This covers
642  * usage of source address mode, immediates, operations with non 32-bit modes,
643  * ...
644  * The resulting data is filled into the @p am struct. block is the block
645  * of the node whose arguments are matched. op1, op2 are the first and second
646  * input that are matched (op1 may be NULL). other_op is another unrelated
647  * input that is not matched! but which is needed sometimes to check if AM
648  * for op1/op2 is legal.
649  * @p flags describes the supported modes of the operation in detail.
650  */
651 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
652                             ir_node *op1, ir_node *op2, ir_node *other_op,
653                             match_flags_t flags)
654 {
655         ia32_address_t *addr      = &am->addr;
656         ir_mode        *mode      = get_irn_mode(op2);
657         int             mode_bits = get_mode_size_bits(mode);
658         ir_node        *noreg_gp, *new_op1, *new_op2;
659         int             use_am;
660         unsigned        commutative;
661         int             use_am_and_immediates;
662         int             use_immediate;
663
664         memset(am, 0, sizeof(am[0]));
665
666         commutative           = (flags & match_commutative) != 0;
667         use_am_and_immediates = (flags & match_am_and_immediates) != 0;
668         use_am                = (flags & match_am) != 0;
669         use_immediate         = (flags & match_immediate) != 0;
670         assert(!use_am_and_immediates || use_immediate);
671
672         assert(op2 != NULL);
673         assert(!commutative || op1 != NULL);
674         assert(use_am || !(flags & match_8bit_am));
675         assert(use_am || !(flags & match_16bit_am));
676
677         if (mode_bits == 8) {
678                 if (!(flags & match_8bit_am))
679                         use_am = 0;
680                 /* we don't automatically add upconvs yet */
681                 assert((flags & match_mode_neutral) || (flags & match_8bit));
682         } else if (mode_bits == 16) {
683                 if (!(flags & match_16bit_am))
684                         use_am = 0;
685                 /* we don't automatically add upconvs yet */
686                 assert((flags & match_mode_neutral) || (flags & match_16bit));
687         }
688
689         /* we can simply skip downconvs for mode neutral nodes: the upper bits
690          * can be random for these operations */
691         if (flags & match_mode_neutral) {
692                 op2 = ia32_skip_downconv(op2);
693                 if (op1 != NULL) {
694                         op1 = ia32_skip_downconv(op1);
695                 }
696         }
697
698         /* match immediates. firm nodes are normalized: constants are always on the
699          * op2 input */
700         new_op2 = NULL;
701         if (!(flags & match_try_am) && use_immediate) {
702                 new_op2 = try_create_Immediate(op2, 0);
703         }
704
705         noreg_gp = ia32_new_NoReg_gp(env_cg);
706         if (new_op2 == NULL &&
707             use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
708                 build_address(am, op2);
709                 new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
710                 if (mode_is_float(mode)) {
711                         new_op2 = ia32_new_NoReg_vfp(env_cg);
712                 } else {
713                         new_op2 = noreg_gp;
714                 }
715                 am->op_type = ia32_AddrModeS;
716         } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
717                        use_am &&
718                        ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
719                 ir_node *noreg;
720                 build_address(am, op1);
721
722                 if (mode_is_float(mode)) {
723                         noreg = ia32_new_NoReg_vfp(env_cg);
724                 } else {
725                         noreg = noreg_gp;
726                 }
727
728                 if (new_op2 != NULL) {
729                         new_op1 = noreg;
730                 } else {
731                         new_op1 = be_transform_node(op2);
732                         new_op2 = noreg;
733                         am->ins_permuted = 1;
734                 }
735                 am->op_type = ia32_AddrModeS;
736         } else {
737                 if (flags & match_try_am) {
738                         am->new_op1 = NULL;
739                         am->new_op2 = NULL;
740                         am->op_type = ia32_Normal;
741                         return;
742                 }
743
744                 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
745                 if (new_op2 == NULL)
746                         new_op2 = be_transform_node(op2);
747                 am->op_type = ia32_Normal;
748                 am->ls_mode = get_irn_mode(op2);
749                 if (flags & match_mode_neutral)
750                         am->ls_mode = mode_Iu;
751         }
752         if (addr->base == NULL)
753                 addr->base = noreg_gp;
754         if (addr->index == NULL)
755                 addr->index = noreg_gp;
756         if (addr->mem == NULL)
757                 addr->mem = new_NoMem();
758
759         am->new_op1     = new_op1;
760         am->new_op2     = new_op2;
761         am->commutative = commutative;
762 }
763
764 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
765 {
766         ir_mode  *mode;
767         ir_node  *load;
768
769         if (am->mem_proj == NULL)
770                 return node;
771
772         /* we have to create a mode_T so the old MemProj can attach to us */
773         mode = get_irn_mode(node);
774         load = get_Proj_pred(am->mem_proj);
775
776         mark_irn_visited(load);
777         be_set_transformed_node(load, node);
778
779         if (mode != mode_T) {
780                 set_irn_mode(node, mode_T);
781                 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
782         } else {
783                 return node;
784         }
785 }
786
787 /**
788  * Construct a standard binary operation, set AM and immediate if required.
789  *
790  * @param node  The original node for which the binop is created
791  * @param op1   The first operand
792  * @param op2   The second operand
793  * @param func  The node constructor function
794  * @return The constructed ia32 node.
795  */
796 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
797                           construct_binop_func *func, match_flags_t flags)
798 {
799         dbg_info            *dbgi;
800         ir_node             *block, *new_block, *new_node;
801         ia32_address_mode_t  am;
802         ia32_address_t      *addr = &am.addr;
803
804         block = get_nodes_block(node);
805         match_arguments(&am, block, op1, op2, NULL, flags);
806
807         dbgi      = get_irn_dbg_info(node);
808         new_block = be_transform_node(block);
809         new_node  = func(dbgi, current_ir_graph, new_block,
810                          addr->base, addr->index, addr->mem,
811                          am.new_op1, am.new_op2);
812         set_am_attributes(new_node, &am);
813         /* we can't use source address mode anymore when using immediates */
814         if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
815                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
816         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
817
818         new_node = fix_mem_proj(new_node, &am);
819
820         return new_node;
821 }
822
823 enum {
824         n_ia32_l_binop_left,
825         n_ia32_l_binop_right,
826         n_ia32_l_binop_eflags
827 };
828 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Adc_left,       n_Adc_left)
829 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Adc_right,      n_Adc_right)
830 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags,     n_Adc_eflags)
831 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Sbb_minuend,    n_Sbb_minuend)
832 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
833 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags,     n_Sbb_eflags)
834
835 /**
836  * Construct a binary operation which also consumes the eflags.
837  *
838  * @param node  The node to transform
839  * @param func  The node constructor function
840  * @param flags The match flags
841  * @return      The constructor ia32 node
842  */
843 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
844                                 match_flags_t flags)
845 {
846         ir_node             *src_block  = get_nodes_block(node);
847         ir_node             *op1        = get_irn_n(node, n_ia32_l_binop_left);
848         ir_node             *op2        = get_irn_n(node, n_ia32_l_binop_right);
849         dbg_info            *dbgi;
850         ir_node             *block, *new_node, *eflags, *new_eflags;
851         ia32_address_mode_t  am;
852         ia32_address_t      *addr       = &am.addr;
853
854         match_arguments(&am, src_block, op1, op2, NULL, flags);
855
856         dbgi       = get_irn_dbg_info(node);
857         block      = be_transform_node(src_block);
858         eflags     = get_irn_n(node, n_ia32_l_binop_eflags);
859         new_eflags = be_transform_node(eflags);
860         new_node   = func(dbgi, current_ir_graph, block, addr->base, addr->index,
861                         addr->mem, am.new_op1, am.new_op2, new_eflags);
862         set_am_attributes(new_node, &am);
863         /* we can't use source address mode anymore when using immediates */
864         if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
865                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
866         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
867
868         new_node = fix_mem_proj(new_node, &am);
869
870         return new_node;
871 }
872
873 static ir_node *get_fpcw(void)
874 {
875         ir_node *fpcw;
876         if (initial_fpcw != NULL)
877                 return initial_fpcw;
878
879         fpcw         = be_abi_get_ignore_irn(env_cg->birg->abi,
880                                              &ia32_fp_cw_regs[REG_FPCW]);
881         initial_fpcw = be_transform_node(fpcw);
882
883         return initial_fpcw;
884 }
885
886 /**
887  * Construct a standard binary operation, set AM and immediate if required.
888  *
889  * @param op1   The first operand
890  * @param op2   The second operand
891  * @param func  The node constructor function
892  * @return The constructed ia32 node.
893  */
894 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
895                                     construct_binop_float_func *func,
896                                     match_flags_t flags)
897 {
898         ir_mode             *mode  = get_irn_mode(node);
899         dbg_info            *dbgi;
900         ir_node             *block, *new_block, *new_node;
901         ia32_address_mode_t  am;
902         ia32_address_t      *addr = &am.addr;
903
904         /* cannot use address mode with long double on x87 */
905         if (get_mode_size_bits(mode) > 64)
906                 flags &= ~match_am;
907
908         block = get_nodes_block(node);
909         match_arguments(&am, block, op1, op2, NULL, flags);
910
911         dbgi      = get_irn_dbg_info(node);
912         new_block = be_transform_node(block);
913         new_node  = func(dbgi, current_ir_graph, new_block,
914                          addr->base, addr->index, addr->mem,
915                          am.new_op1, am.new_op2, get_fpcw());
916         set_am_attributes(new_node, &am);
917
918         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
919
920         new_node = fix_mem_proj(new_node, &am);
921
922         return new_node;
923 }
924
925 /**
926  * Construct a shift/rotate binary operation, sets AM and immediate if required.
927  *
928  * @param op1   The first operand
929  * @param op2   The second operand
930  * @param func  The node constructor function
931  * @return The constructed ia32 node.
932  */
933 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
934                                 construct_shift_func *func,
935                                 match_flags_t flags)
936 {
937         dbg_info *dbgi;
938         ir_node  *block, *new_block, *new_op1, *new_op2, *new_node;
939
940         assert(! mode_is_float(get_irn_mode(node)));
941         assert(flags & match_immediate);
942         assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
943
944         if (flags & match_mode_neutral) {
945                 op1     = ia32_skip_downconv(op1);
946                 new_op1 = be_transform_node(op1);
947         } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
948                 new_op1 = create_upconv(op1, node);
949         } else {
950                 new_op1 = be_transform_node(op1);
951         }
952
953         /* the shift amount can be any mode that is bigger than 5 bits, since all
954          * other bits are ignored anyway */
955         while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
956                 ir_node *const op = get_Conv_op(op2);
957                 if (mode_is_float(get_irn_mode(op)))
958                         break;
959                 op2 = op;
960                 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
961         }
962         new_op2 = create_immediate_or_transform(op2, 0);
963
964         dbgi      = get_irn_dbg_info(node);
965         block     = get_nodes_block(node);
966         new_block = be_transform_node(block);
967         new_node  = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
968         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
969
970         /* lowered shift instruction may have a dependency operand, handle it here */
971         if (get_irn_arity(node) == 3) {
972                 /* we have a dependency */
973                 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
974                 add_irn_dep(new_node, new_dep);
975         }
976
977         return new_node;
978 }
979
980
981 /**
982  * Construct a standard unary operation, set AM and immediate if required.
983  *
984  * @param op    The operand
985  * @param func  The node constructor function
986  * @return The constructed ia32 node.
987  */
988 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
989                          match_flags_t flags)
990 {
991         dbg_info *dbgi;
992         ir_node  *block, *new_block, *new_op, *new_node;
993
994         assert(flags == 0 || flags == match_mode_neutral);
995         if (flags & match_mode_neutral) {
996                 op = ia32_skip_downconv(op);
997         }
998
999         new_op    = be_transform_node(op);
1000         dbgi      = get_irn_dbg_info(node);
1001         block     = get_nodes_block(node);
1002         new_block = be_transform_node(block);
1003         new_node  = func(dbgi, current_ir_graph, new_block, new_op);
1004
1005         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1006
1007         return new_node;
1008 }
1009
1010 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1011                                         ia32_address_t *addr)
1012 {
1013         ir_node *base, *index, *res;
1014
1015         base = addr->base;
1016         if (base == NULL) {
1017                 base = ia32_new_NoReg_gp(env_cg);
1018         } else {
1019                 base = be_transform_node(base);
1020         }
1021
1022         index = addr->index;
1023         if (index == NULL) {
1024                 index = ia32_new_NoReg_gp(env_cg);
1025         } else {
1026                 index = be_transform_node(index);
1027         }
1028
1029         res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1030         set_address(res, addr);
1031
1032         return res;
1033 }
1034
1035 /**
1036  * Returns non-zero if a given address mode has a symbolic or
1037  * numerical offset != 0.
1038  */
1039 static int am_has_immediates(const ia32_address_t *addr)
1040 {
1041         return addr->offset != 0 || addr->symconst_ent != NULL
1042                 || addr->frame_entity || addr->use_frame;
1043 }
1044
1045 /**
1046  * Creates an ia32 Add.
1047  *
1048  * @return the created ia32 Add node
1049  */
1050 static ir_node *gen_Add(ir_node *node) {
1051         ir_mode  *mode = get_irn_mode(node);
1052         ir_node  *op1  = get_Add_left(node);
1053         ir_node  *op2  = get_Add_right(node);
1054         dbg_info *dbgi;
1055         ir_node  *block, *new_block, *new_node, *add_immediate_op;
1056         ia32_address_t       addr;
1057         ia32_address_mode_t  am;
1058
1059         if (mode_is_float(mode)) {
1060                 if (ia32_cg_config.use_sse2)
1061                         return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1062                                          match_commutative | match_am);
1063                 else
1064                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1065                                                    match_commutative | match_am);
1066         }
1067
1068         ia32_mark_non_am(node);
1069
1070         op2 = ia32_skip_downconv(op2);
1071         op1 = ia32_skip_downconv(op1);
1072
1073         /**
1074          * Rules for an Add:
1075          *   0. Immediate Trees (example Add(Symconst, Const) -> Const)
1076          *   1. Add with immediate -> Lea
1077          *   2. Add with possible source address mode -> Add
1078          *   3. Otherwise -> Lea
1079          */
1080         memset(&addr, 0, sizeof(addr));
1081         ia32_create_address_mode(&addr, node, /*force=*/1);
1082         add_immediate_op = NULL;
1083
1084         dbgi      = get_irn_dbg_info(node);
1085         block     = get_nodes_block(node);
1086         new_block = be_transform_node(block);
1087
1088         /* a constant? */
1089         if(addr.base == NULL && addr.index == NULL) {
1090                 ir_graph *irg = current_ir_graph;
1091                 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1092                                              addr.symconst_sign, addr.offset);
1093                 add_irn_dep(new_node, get_irg_frame(irg));
1094                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1095                 return new_node;
1096         }
1097         /* add with immediate? */
1098         if(addr.index == NULL) {
1099                 add_immediate_op = addr.base;
1100         } else if(addr.base == NULL && addr.scale == 0) {
1101                 add_immediate_op = addr.index;
1102         }
1103
1104         if(add_immediate_op != NULL) {
1105                 if(!am_has_immediates(&addr)) {
1106 #ifdef DEBUG_libfirm
1107                         ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1108                                            node);
1109 #endif
1110                         return be_transform_node(add_immediate_op);
1111                 }
1112
1113                 new_node = create_lea_from_address(dbgi, new_block, &addr);
1114                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1115                 return new_node;
1116         }
1117
1118         /* test if we can use source address mode */
1119         match_arguments(&am, block, op1, op2, NULL, match_commutative
1120                         | match_mode_neutral | match_am | match_immediate | match_try_am);
1121
1122         /* construct an Add with source address mode */
1123         if (am.op_type == ia32_AddrModeS) {
1124                 ir_graph *irg = current_ir_graph;
1125                 ia32_address_t *am_addr = &am.addr;
1126                 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1127                                          am_addr->index, am_addr->mem, am.new_op1,
1128                                          am.new_op2);
1129                 set_am_attributes(new_node, &am);
1130                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1131
1132                 new_node = fix_mem_proj(new_node, &am);
1133
1134                 return new_node;
1135         }
1136
1137         /* otherwise construct a lea */
1138         new_node = create_lea_from_address(dbgi, new_block, &addr);
1139         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1140         return new_node;
1141 }
1142
1143 /**
1144  * Creates an ia32 Mul.
1145  *
1146  * @return the created ia32 Mul node
1147  */
1148 static ir_node *gen_Mul(ir_node *node) {
1149         ir_node *op1  = get_Mul_left(node);
1150         ir_node *op2  = get_Mul_right(node);
1151         ir_mode *mode = get_irn_mode(node);
1152
1153         if (mode_is_float(mode)) {
1154                 if (ia32_cg_config.use_sse2)
1155                         return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1156                                          match_commutative | match_am);
1157                 else
1158                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1159                                                    match_commutative | match_am);
1160         }
1161         return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1162                          match_commutative | match_am | match_mode_neutral |
1163                          match_immediate | match_am_and_immediates);
1164 }
1165
1166 /**
1167  * Creates an ia32 Mulh.
1168  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1169  * this result while Mul returns the lower 32 bit.
1170  *
1171  * @return the created ia32 Mulh node
1172  */
1173 static ir_node *gen_Mulh(ir_node *node)
1174 {
1175         ir_node  *block     = get_nodes_block(node);
1176         ir_node  *new_block = be_transform_node(block);
1177         ir_graph *irg       = current_ir_graph;
1178         dbg_info *dbgi      = get_irn_dbg_info(node);
1179         ir_mode  *mode      = get_irn_mode(node);
1180         ir_node  *op1       = get_Mulh_left(node);
1181         ir_node  *op2       = get_Mulh_right(node);
1182         ir_node  *proj_res_high;
1183         ir_node  *new_node;
1184         ia32_address_mode_t  am;
1185         ia32_address_t      *addr = &am.addr;
1186
1187         assert(!mode_is_float(mode) && "Mulh with float not supported");
1188         assert(get_mode_size_bits(mode) == 32);
1189
1190         match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1191
1192         if (mode_is_signed(mode)) {
1193                 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1194                                                addr->index, addr->mem, am.new_op1,
1195                                                am.new_op2);
1196         } else {
1197                 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1198                                            addr->index, addr->mem, am.new_op1,
1199                                            am.new_op2);
1200         }
1201
1202         set_am_attributes(new_node, &am);
1203         /* we can't use source address mode anymore when using immediates */
1204         if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1205                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1206         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1207
1208         assert(get_irn_mode(new_node) == mode_T);
1209
1210         fix_mem_proj(new_node, &am);
1211
1212         assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1213         proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1214                                mode_Iu, pn_ia32_IMul1OP_res_high);
1215
1216         return proj_res_high;
1217 }
1218
1219
1220
1221 /**
1222  * Creates an ia32 And.
1223  *
1224  * @return The created ia32 And node
1225  */
1226 static ir_node *gen_And(ir_node *node) {
1227         ir_node *op1 = get_And_left(node);
1228         ir_node *op2 = get_And_right(node);
1229         assert(! mode_is_float(get_irn_mode(node)));
1230
1231         /* is it a zero extension? */
1232         if (is_Const(op2)) {
1233                 tarval   *tv    = get_Const_tarval(op2);
1234                 long      v     = get_tarval_long(tv);
1235
1236                 if (v == 0xFF || v == 0xFFFF) {
1237                         dbg_info *dbgi   = get_irn_dbg_info(node);
1238                         ir_node  *block  = get_nodes_block(node);
1239                         ir_mode  *src_mode;
1240                         ir_node  *res;
1241
1242                         if(v == 0xFF) {
1243                                 src_mode = mode_Bu;
1244                         } else {
1245                                 assert(v == 0xFFFF);
1246                                 src_mode = mode_Hu;
1247                         }
1248                         res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1249
1250                         return res;
1251                 }
1252         }
1253         return gen_binop(node, op1, op2, new_rd_ia32_And,
1254                          match_commutative | match_mode_neutral | match_am
1255                                          | match_immediate);
1256 }
1257
1258
1259
1260 /**
1261  * Creates an ia32 Or.
1262  *
1263  * @return The created ia32 Or node
1264  */
1265 static ir_node *gen_Or(ir_node *node) {
1266         ir_node *op1 = get_Or_left(node);
1267         ir_node *op2 = get_Or_right(node);
1268
1269         assert (! mode_is_float(get_irn_mode(node)));
1270         return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1271                         | match_mode_neutral | match_am | match_immediate);
1272 }
1273
1274
1275
1276 /**
1277  * Creates an ia32 Eor.
1278  *
1279  * @return The created ia32 Eor node
1280  */
1281 static ir_node *gen_Eor(ir_node *node) {
1282         ir_node *op1 = get_Eor_left(node);
1283         ir_node *op2 = get_Eor_right(node);
1284
1285         assert(! mode_is_float(get_irn_mode(node)));
1286         return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1287                         | match_mode_neutral | match_am | match_immediate);
1288 }
1289
1290
1291 /**
1292  * Creates an ia32 Sub.
1293  *
1294  * @return The created ia32 Sub node
1295  */
1296 static ir_node *gen_Sub(ir_node *node) {
1297         ir_node  *op1  = get_Sub_left(node);
1298         ir_node  *op2  = get_Sub_right(node);
1299         ir_mode  *mode = get_irn_mode(node);
1300
1301         if (mode_is_float(mode)) {
1302                 if (ia32_cg_config.use_sse2)
1303                         return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1304                 else
1305                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1306                                                    match_am);
1307         }
1308
1309         if (is_Const(op2)) {
1310                 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1311                            node);
1312         }
1313
1314         return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1315                         | match_am | match_immediate);
1316 }
1317
1318 /**
1319  * Generates an ia32 DivMod with additional infrastructure for the
1320  * register allocator if needed.
1321  */
1322 static ir_node *create_Div(ir_node *node)
1323 {
1324         ir_graph *irg       = current_ir_graph;
1325         dbg_info *dbgi      = get_irn_dbg_info(node);
1326         ir_node  *block     = get_nodes_block(node);
1327         ir_node  *new_block = be_transform_node(block);
1328         ir_node  *mem;
1329         ir_node  *new_mem;
1330         ir_node  *op1;
1331         ir_node  *op2;
1332         ir_node  *new_node;
1333         ir_mode  *mode;
1334         ir_node  *sign_extension;
1335         ia32_address_mode_t  am;
1336         ia32_address_t      *addr = &am.addr;
1337
1338         /* the upper bits have random contents for smaller modes */
1339         switch (get_irn_opcode(node)) {
1340         case iro_Div:
1341                 op1     = get_Div_left(node);
1342                 op2     = get_Div_right(node);
1343                 mem     = get_Div_mem(node);
1344                 mode    = get_Div_resmode(node);
1345                 break;
1346         case iro_Mod:
1347                 op1     = get_Mod_left(node);
1348                 op2     = get_Mod_right(node);
1349                 mem     = get_Mod_mem(node);
1350                 mode    = get_Mod_resmode(node);
1351                 break;
1352         case iro_DivMod:
1353                 op1     = get_DivMod_left(node);
1354                 op2     = get_DivMod_right(node);
1355                 mem     = get_DivMod_mem(node);
1356                 mode    = get_DivMod_resmode(node);
1357                 break;
1358         default:
1359                 panic("invalid divmod node %+F", node);
1360         }
1361
1362         match_arguments(&am, block, op1, op2, NULL, match_am);
1363
1364         /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1365            is the memory of the consumed address. We can have only the second op as address
1366            in Div nodes, so check only op2. */
1367         if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1368                 new_mem = be_transform_node(mem);
1369                 if(!is_NoMem(addr->mem)) {
1370                         ir_node *in[2];
1371                         in[0] = new_mem;
1372                         in[1] = addr->mem;
1373                         new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1374                 }
1375         } else {
1376                 new_mem = addr->mem;
1377         }
1378
1379         if (mode_is_signed(mode)) {
1380                 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1381                 add_irn_dep(produceval, get_irg_frame(irg));
1382                 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1383                                                   produceval);
1384
1385                 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1386                                             addr->index, new_mem, am.new_op2,
1387                                             am.new_op1, sign_extension);
1388         } else {
1389                 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1390                 add_irn_dep(sign_extension, get_irg_frame(irg));
1391
1392                 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1393                                            addr->index, new_mem, am.new_op2,
1394                                            am.new_op1, sign_extension);
1395         }
1396
1397         set_irn_pinned(new_node, get_irn_pinned(node));
1398
1399         set_am_attributes(new_node, &am);
1400         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1401
1402         new_node = fix_mem_proj(new_node, &am);
1403
1404         return new_node;
1405 }
1406
1407
1408 static ir_node *gen_Mod(ir_node *node) {
1409         return create_Div(node);
1410 }
1411
1412 static ir_node *gen_Div(ir_node *node) {
1413         return create_Div(node);
1414 }
1415
1416 static ir_node *gen_DivMod(ir_node *node) {
1417         return create_Div(node);
1418 }
1419
1420
1421
1422 /**
1423  * Creates an ia32 floating Div.
1424  *
1425  * @return The created ia32 xDiv node
1426  */
1427 static ir_node *gen_Quot(ir_node *node)
1428 {
1429         ir_node *op1 = get_Quot_left(node);
1430         ir_node *op2 = get_Quot_right(node);
1431
1432         if (ia32_cg_config.use_sse2) {
1433                 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1434         } else {
1435                 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1436         }
1437 }
1438
1439
1440 /**
1441  * Creates an ia32 Shl.
1442  *
1443  * @return The created ia32 Shl node
1444  */
1445 static ir_node *gen_Shl(ir_node *node) {
1446         ir_node *left  = get_Shl_left(node);
1447         ir_node *right = get_Shl_right(node);
1448
1449         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1450                                match_mode_neutral | match_immediate);
1451 }
1452
1453 /**
1454  * Creates an ia32 Shr.
1455  *
1456  * @return The created ia32 Shr node
1457  */
1458 static ir_node *gen_Shr(ir_node *node) {
1459         ir_node *left  = get_Shr_left(node);
1460         ir_node *right = get_Shr_right(node);
1461
1462         return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1463 }
1464
1465
1466
1467 /**
1468  * Creates an ia32 Sar.
1469  *
1470  * @return The created ia32 Shrs node
1471  */
1472 static ir_node *gen_Shrs(ir_node *node) {
1473         ir_node *left  = get_Shrs_left(node);
1474         ir_node *right = get_Shrs_right(node);
1475         ir_mode *mode  = get_irn_mode(node);
1476
1477         if(is_Const(right) && mode == mode_Is) {
1478                 tarval *tv = get_Const_tarval(right);
1479                 long val = get_tarval_long(tv);
1480                 if(val == 31) {
1481                         /* this is a sign extension */
1482                         ir_graph *irg    = current_ir_graph;
1483                         dbg_info *dbgi   = get_irn_dbg_info(node);
1484                         ir_node  *block  = be_transform_node(get_nodes_block(node));
1485                         ir_node  *op     = left;
1486                         ir_node  *new_op = be_transform_node(op);
1487                         ir_node  *pval   = new_rd_ia32_ProduceVal(dbgi, irg, block);
1488                         add_irn_dep(pval, get_irg_frame(irg));
1489
1490                         return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1491                 }
1492         }
1493
1494         /* 8 or 16 bit sign extension? */
1495         if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1496                 ir_node *shl_left  = get_Shl_left(left);
1497                 ir_node *shl_right = get_Shl_right(left);
1498                 if(is_Const(shl_right)) {
1499                         tarval *tv1 = get_Const_tarval(right);
1500                         tarval *tv2 = get_Const_tarval(shl_right);
1501                         if(tv1 == tv2 && tarval_is_long(tv1)) {
1502                                 long val = get_tarval_long(tv1);
1503                                 if(val == 16 || val == 24) {
1504                                         dbg_info *dbgi   = get_irn_dbg_info(node);
1505                                         ir_node  *block  = get_nodes_block(node);
1506                                         ir_mode  *src_mode;
1507                                         ir_node  *res;
1508
1509                                         if(val == 24) {
1510                                                 src_mode = mode_Bs;
1511                                         } else {
1512                                                 assert(val == 16);
1513                                                 src_mode = mode_Hs;
1514                                         }
1515                                         res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1516                                                               shl_left, node);
1517
1518                                         return res;
1519                                 }
1520                         }
1521                 }
1522         }
1523
1524         return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1525 }
1526
1527
1528
1529 /**
1530  * Creates an ia32 Rol.
1531  *
1532  * @param op1   The first operator
1533  * @param op2   The second operator
1534  * @return The created ia32 RotL node
1535  */
1536 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2) {
1537         return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1538 }
1539
1540
1541
1542 /**
1543  * Creates an ia32 Ror.
1544  * NOTE: There is no RotR with immediate because this would always be a RotL
1545  *       "imm-mode_size_bits" which can be pre-calculated.
1546  *
1547  * @param op1   The first operator
1548  * @param op2   The second operator
1549  * @return The created ia32 RotR node
1550  */
1551 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2) {
1552         return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1553 }
1554
1555
1556
1557 /**
1558  * Creates an ia32 RotR or RotL (depending on the found pattern).
1559  *
1560  * @return The created ia32 RotL or RotR node
1561  */
1562 static ir_node *gen_Rotl(ir_node *node) {
1563         ir_node *rotate = NULL;
1564         ir_node *op1    = get_Rotl_left(node);
1565         ir_node *op2    = get_Rotl_right(node);
1566
1567         /* Firm has only RotL, so we are looking for a right (op2)
1568                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1569                  that means we can create a RotR instead of an Add and a RotL */
1570
1571         if (is_Add(op2)) {
1572                 ir_node *add = op2;
1573                 ir_node *left = get_Add_left(add);
1574                 ir_node *right = get_Add_right(add);
1575                 if (is_Const(right)) {
1576                         tarval  *tv   = get_Const_tarval(right);
1577                         ir_mode *mode = get_irn_mode(node);
1578                         long     bits = get_mode_size_bits(mode);
1579
1580                         if (is_Minus(left) &&
1581                             tarval_is_long(tv)       &&
1582                             get_tarval_long(tv) == bits &&
1583                             bits                == 32)
1584                         {
1585                                 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1586                                 rotate = gen_Ror(node, op1, get_Minus_op(left));
1587                         }
1588                 }
1589         }
1590
1591         if (rotate == NULL) {
1592                 rotate = gen_Rol(node, op1, op2);
1593         }
1594
1595         return rotate;
1596 }
1597
1598
1599
1600 /**
1601  * Transforms a Minus node.
1602  *
1603  * @return The created ia32 Minus node
1604  */
1605 static ir_node *gen_Minus(ir_node *node)
1606 {
1607         ir_node   *op    = get_Minus_op(node);
1608         ir_node   *block = be_transform_node(get_nodes_block(node));
1609         ir_graph  *irg   = current_ir_graph;
1610         dbg_info  *dbgi  = get_irn_dbg_info(node);
1611         ir_mode   *mode  = get_irn_mode(node);
1612         ir_entity *ent;
1613         ir_node   *new_node;
1614         int        size;
1615
1616         if (mode_is_float(mode)) {
1617                 ir_node *new_op = be_transform_node(op);
1618                 if (ia32_cg_config.use_sse2) {
1619                         /* TODO: non-optimal... if we have many xXors, then we should
1620                          * rather create a load for the const and use that instead of
1621                          * several AM nodes... */
1622                         ir_node *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1623                         ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1624                         ir_node *nomem     = new_rd_NoMem(irg);
1625
1626                         new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1627                                                     nomem, new_op, noreg_xmm);
1628
1629                         size = get_mode_size_bits(mode);
1630                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1631
1632                         set_ia32_am_sc(new_node, ent);
1633                         set_ia32_op_type(new_node, ia32_AddrModeS);
1634                         set_ia32_ls_mode(new_node, mode);
1635                 } else {
1636                         new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1637                 }
1638         } else {
1639                 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1640         }
1641
1642         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1643
1644         return new_node;
1645 }
1646
1647 /**
1648  * Transforms a Not node.
1649  *
1650  * @return The created ia32 Not node
1651  */
1652 static ir_node *gen_Not(ir_node *node) {
1653         ir_node *op   = get_Not_op(node);
1654
1655         assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1656         assert (! mode_is_float(get_irn_mode(node)));
1657
1658         return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1659 }
1660
1661
1662
1663 /**
1664  * Transforms an Abs node.
1665  *
1666  * @return The created ia32 Abs node
1667  */
1668 static ir_node *gen_Abs(ir_node *node)
1669 {
1670         ir_node   *block     = get_nodes_block(node);
1671         ir_node   *new_block = be_transform_node(block);
1672         ir_node   *op        = get_Abs_op(node);
1673         ir_graph  *irg       = current_ir_graph;
1674         dbg_info  *dbgi      = get_irn_dbg_info(node);
1675         ir_mode   *mode      = get_irn_mode(node);
1676         ir_node   *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1677         ir_node   *nomem     = new_NoMem();
1678         ir_node   *new_op;
1679         ir_node   *new_node;
1680         int        size;
1681         ir_entity *ent;
1682
1683         if (mode_is_float(mode)) {
1684                 new_op = be_transform_node(op);
1685
1686                 if (ia32_cg_config.use_sse2) {
1687                         ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1688                         new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1689                                                     nomem, new_op, noreg_fp);
1690
1691                         size = get_mode_size_bits(mode);
1692                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1693
1694                         set_ia32_am_sc(new_node, ent);
1695
1696                         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1697
1698                         set_ia32_op_type(new_node, ia32_AddrModeS);
1699                         set_ia32_ls_mode(new_node, mode);
1700                 } else {
1701                         new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1702                         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1703                 }
1704         } else {
1705                 ir_node *xor, *pval, *sign_extension;
1706
1707                 if (get_mode_size_bits(mode) == 32) {
1708                         new_op = be_transform_node(op);
1709                 } else {
1710                         new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1711                 }
1712
1713                 pval           = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1714                 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1715                                                            new_op, pval);
1716
1717                 add_irn_dep(pval, get_irg_frame(irg));
1718                 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1719
1720                 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1721                                       nomem, new_op, sign_extension);
1722                 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1723
1724                 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1725                                            nomem, xor, sign_extension);
1726                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1727         }
1728
1729         return new_node;
1730 }
1731
1732 /**
1733  * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1734  */
1735 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1736         dbg_info *dbgi      = get_irn_dbg_info(cmp);
1737         ir_node  *block     = get_nodes_block(cmp);
1738         ir_node  *new_block = be_transform_node(block);
1739         ir_node  *op1       = be_transform_node(x);
1740         ir_node  *op2       = be_transform_node(n);
1741
1742         return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1743 }
1744
1745 /**
1746  * Transform a node returning a "flag" result.
1747  *
1748  * @param node     the node to transform
1749  * @param pnc_out  the compare mode to use
1750  */
1751 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1752 {
1753         ir_node  *flags;
1754         ir_node  *new_op;
1755         ir_node  *noreg;
1756         ir_node  *nomem;
1757         ir_node  *new_block;
1758         dbg_info *dbgi;
1759
1760         /* we have a Cmp as input */
1761         if (is_Proj(node)) {
1762                 ir_node *pred = get_Proj_pred(node);
1763                 if (is_Cmp(pred)) {
1764                         pn_Cmp pnc = get_Proj_proj(node);
1765                         if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1766                                 ir_node *l = get_Cmp_left(pred);
1767                                 ir_node *r = get_Cmp_right(pred);
1768                                 if (is_And(l)) {
1769                                         ir_node *la = get_And_left(l);
1770                                         ir_node *ra = get_And_right(l);
1771                                         if (is_Shl(la)) {
1772                                                 ir_node *c = get_Shl_left(la);
1773                                                 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1774                                                         /* (1 << n) & ra) */
1775                                                         ir_node *n = get_Shl_right(la);
1776                                                         flags    = gen_bt(pred, ra, n);
1777                                                         /* we must generate a Jc/Jnc jump */
1778                                                         pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1779                                                         if (r == la)
1780                                                                 pnc ^= pn_Cmp_Leg;
1781                                                         *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1782                                                         return flags;
1783                                                 }
1784                                         }
1785                                         if (is_Shl(ra)) {
1786                                                 ir_node *c = get_Shl_left(ra);
1787                                                 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1788                                                         /* la & (1 << n)) */
1789                                                         ir_node *n = get_Shl_right(ra);
1790                                                         flags    = gen_bt(pred, la, n);
1791                                                         /* we must generate a Jc/Jnc jump */
1792                                                         pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1793                                                         if (r == ra)
1794                                                                 pnc ^= pn_Cmp_Leg;
1795                                                         *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1796                                                         return flags;
1797                                                 }
1798                                         }
1799                                 }
1800                         }
1801                         flags    = be_transform_node(pred);
1802                         *pnc_out = pnc;
1803                         return flags;
1804                 }
1805         }
1806
1807         /* a mode_b value, we have to compare it against 0 */
1808         dbgi      = get_irn_dbg_info(node);
1809         new_block = be_transform_node(get_nodes_block(node));
1810         new_op    = be_transform_node(node);
1811         noreg     = ia32_new_NoReg_gp(env_cg);
1812         nomem     = new_NoMem();
1813         flags     = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1814                                      new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1815         *pnc_out  = pn_Cmp_Lg;
1816         return flags;
1817 }
1818
1819 /**
1820  * Transforms a Load.
1821  *
1822  * @return the created ia32 Load node
1823  */
1824 static ir_node *gen_Load(ir_node *node) {
1825         ir_node  *old_block = get_nodes_block(node);
1826         ir_node  *block   = be_transform_node(old_block);
1827         ir_node  *ptr     = get_Load_ptr(node);
1828         ir_node  *mem     = get_Load_mem(node);
1829         ir_node  *new_mem = be_transform_node(mem);
1830         ir_node  *base;
1831         ir_node  *index;
1832         ir_graph *irg     = current_ir_graph;
1833         dbg_info *dbgi    = get_irn_dbg_info(node);
1834         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
1835         ir_mode  *mode    = get_Load_mode(node);
1836         ir_mode  *res_mode;
1837         ir_node  *new_node;
1838         ia32_address_t addr;
1839
1840         /* construct load address */
1841         memset(&addr, 0, sizeof(addr));
1842         ia32_create_address_mode(&addr, ptr, /*force=*/0);
1843         base  = addr.base;
1844         index = addr.index;
1845
1846         if(base == NULL) {
1847                 base = noreg;
1848         } else {
1849                 base = be_transform_node(base);
1850         }
1851
1852         if(index == NULL) {
1853                 index = noreg;
1854         } else {
1855                 index = be_transform_node(index);
1856         }
1857
1858         if (mode_is_float(mode)) {
1859                 if (ia32_cg_config.use_sse2) {
1860                         new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1861                                                      mode);
1862                         res_mode = mode_xmm;
1863                 } else {
1864                         new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
1865                                                     mode);
1866                         res_mode = mode_vfp;
1867                 }
1868         } else {
1869                 assert(mode != mode_b);
1870
1871                 /* create a conv node with address mode for smaller modes */
1872                 if(get_mode_size_bits(mode) < 32) {
1873                         new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
1874                                                         new_mem, noreg, mode);
1875                 } else {
1876                         new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
1877                 }
1878                 res_mode = mode_Iu;
1879         }
1880
1881         set_irn_pinned(new_node, get_irn_pinned(node));
1882         set_ia32_op_type(new_node, ia32_AddrModeS);
1883         set_ia32_ls_mode(new_node, mode);
1884         set_address(new_node, &addr);
1885
1886         if(get_irn_pinned(node) == op_pin_state_floats) {
1887                 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
1888         }
1889
1890         /* make sure we are scheduled behind the initial IncSP/Barrier
1891          * to avoid spills being placed before it
1892          */
1893         if (block == get_irg_start_block(irg)) {
1894                 add_irn_dep(new_node, get_irg_frame(irg));
1895         }
1896
1897         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1898
1899         return new_node;
1900 }
1901
1902 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1903                        ir_node *ptr, ir_node *other)
1904 {
1905         ir_node *load;
1906
1907         if(!is_Proj(node))
1908                 return 0;
1909
1910         /* we only use address mode if we're the only user of the load */
1911         if(get_irn_n_edges(node) > 1)
1912                 return 0;
1913
1914         load = get_Proj_pred(node);
1915         if(!is_Load(load))
1916                 return 0;
1917         if(get_nodes_block(load) != block)
1918                 return 0;
1919
1920         /* Store should be attached to the load */
1921         if(!is_Proj(mem) || get_Proj_pred(mem) != load)
1922                 return 0;
1923         /* store should have the same pointer as the load */
1924         if(get_Load_ptr(load) != ptr)
1925                 return 0;
1926
1927         /* don't do AM if other node inputs depend on the load (via mem-proj) */
1928         if(other != NULL && get_nodes_block(other) == block
1929                         && heights_reachable_in_block(heights, other, load))
1930                 return 0;
1931
1932         return 1;
1933 }
1934
1935 static void set_transformed_and_mark(ir_node *const old_node, ir_node *const new_node)
1936 {
1937         mark_irn_visited(old_node);
1938         be_set_transformed_node(old_node, new_node);
1939 }
1940
1941 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1942                               ir_node *mem, ir_node *ptr, ir_mode *mode,
1943                               construct_binop_dest_func *func,
1944                               construct_binop_dest_func *func8bit,
1945                                                           match_flags_t flags)
1946 {
1947         ir_node  *src_block = get_nodes_block(node);
1948         ir_node  *block;
1949         ir_node  *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1950         ir_graph *irg      = current_ir_graph;
1951         dbg_info *dbgi;
1952         ir_node  *new_node;
1953         ir_node  *new_op;
1954         ir_node  *mem_proj;
1955         int       commutative;
1956         ia32_address_mode_t  am;
1957         ia32_address_t      *addr = &am.addr;
1958         memset(&am, 0, sizeof(am));
1959
1960         assert(flags & match_dest_am);
1961         assert(flags & match_immediate); /* there is no destam node without... */
1962         commutative = (flags & match_commutative) != 0;
1963
1964         if(use_dest_am(src_block, op1, mem, ptr, op2)) {
1965                 build_address(&am, op1);
1966                 new_op = create_immediate_or_transform(op2, 0);
1967         } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1968                 build_address(&am, op2);
1969                 new_op = create_immediate_or_transform(op1, 0);
1970         } else {
1971                 return NULL;
1972         }
1973
1974         if(addr->base == NULL)
1975                 addr->base = noreg_gp;
1976         if(addr->index == NULL)
1977                 addr->index = noreg_gp;
1978         if(addr->mem == NULL)
1979                 addr->mem = new_NoMem();
1980
1981         dbgi  = get_irn_dbg_info(node);
1982         block = be_transform_node(src_block);
1983         if(get_mode_size_bits(mode) == 8) {
1984                 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
1985                                     addr->mem, new_op);
1986         } else {
1987                 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
1988                                 new_op);
1989         }
1990         set_address(new_node, addr);
1991         set_ia32_op_type(new_node, ia32_AddrModeD);
1992         set_ia32_ls_mode(new_node, mode);
1993         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1994
1995         set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
1996         mem_proj = be_transform_node(am.mem_proj);
1997         set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
1998
1999         return new_node;
2000 }
2001
2002 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2003                              ir_node *ptr, ir_mode *mode,
2004                              construct_unop_dest_func *func)
2005 {
2006         ir_graph *irg      = current_ir_graph;
2007         ir_node *src_block = get_nodes_block(node);
2008         ir_node *block;
2009         dbg_info *dbgi;
2010         ir_node *new_node;
2011         ir_node *mem_proj;
2012         ia32_address_mode_t  am;
2013         ia32_address_t *addr = &am.addr;
2014         memset(&am, 0, sizeof(am));
2015
2016         if(!use_dest_am(src_block, op, mem, ptr, NULL))
2017                 return NULL;
2018
2019         build_address(&am, op);
2020
2021         dbgi     = get_irn_dbg_info(node);
2022         block    = be_transform_node(src_block);
2023         new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2024         set_address(new_node, addr);
2025         set_ia32_op_type(new_node, ia32_AddrModeD);
2026         set_ia32_ls_mode(new_node, mode);
2027         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2028
2029         set_transformed_and_mark(get_Proj_pred(am.mem_proj), new_node);
2030         mem_proj = be_transform_node(am.mem_proj);
2031         set_transformed_and_mark(mem_proj ? mem_proj : am.mem_proj, new_node);
2032
2033         return new_node;
2034 }
2035
2036 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2037         ir_mode  *mode        = get_irn_mode(node);
2038         ir_node  *mux_true    = get_Mux_true(node);
2039         ir_node  *mux_false   = get_Mux_false(node);
2040         ir_graph *irg;
2041         ir_node  *cond;
2042         ir_node  *new_mem;
2043         dbg_info *dbgi;
2044         ir_node  *block;
2045         ir_node  *new_block;
2046         ir_node  *flags;
2047         ir_node  *new_node;
2048         int       negated;
2049         pn_Cmp    pnc;
2050         ia32_address_t addr;
2051
2052         if(get_mode_size_bits(mode) != 8)
2053                 return NULL;
2054
2055         if(is_Const_1(mux_true) && is_Const_0(mux_false)) {
2056                 negated = 0;
2057         } else if(is_Const_0(mux_true) && is_Const_1(mux_false)) {
2058                 negated = 1;
2059         } else {
2060                 return NULL;
2061         }
2062
2063         build_address_ptr(&addr, ptr, mem);
2064
2065         irg       = current_ir_graph;
2066         dbgi      = get_irn_dbg_info(node);
2067         block     = get_nodes_block(node);
2068         new_block = be_transform_node(block);
2069         cond      = get_Mux_sel(node);
2070         flags     = get_flags_node(cond, &pnc);
2071         new_mem   = be_transform_node(mem);
2072         new_node  = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2073                                        addr.index, addr.mem, flags, pnc, negated);
2074         set_address(new_node, &addr);
2075         set_ia32_op_type(new_node, ia32_AddrModeD);
2076         set_ia32_ls_mode(new_node, mode);
2077         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2078
2079         return new_node;
2080 }
2081
2082 static ir_node *try_create_dest_am(ir_node *node) {
2083         ir_node  *val  = get_Store_value(node);
2084         ir_node  *mem  = get_Store_mem(node);
2085         ir_node  *ptr  = get_Store_ptr(node);
2086         ir_mode  *mode = get_irn_mode(val);
2087         unsigned  bits = get_mode_size_bits(mode);
2088         ir_node  *op1;
2089         ir_node  *op2;
2090         ir_node  *new_node;
2091
2092         /* handle only GP modes for now... */
2093         if(!ia32_mode_needs_gp_reg(mode))
2094                 return NULL;
2095
2096         while(1) {
2097                 /* store must be the only user of the val node */
2098                 if(get_irn_n_edges(val) > 1)
2099                         return NULL;
2100                 /* skip pointless convs */
2101                 if(is_Conv(val)) {
2102                         ir_node *conv_op   = get_Conv_op(val);
2103                         ir_mode *pred_mode = get_irn_mode(conv_op);
2104                         if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2105                                 val = conv_op;
2106                                 continue;
2107                         }
2108                 }
2109                 break;
2110         }
2111
2112         /* value must be in the same block */
2113         if(get_nodes_block(node) != get_nodes_block(val))
2114                 return NULL;
2115
2116         switch (get_irn_opcode(val)) {
2117         case iro_Add:
2118                 op1      = get_Add_left(val);
2119                 op2      = get_Add_right(val);
2120                 if(is_Const_1(op2)) {
2121                         new_node = dest_am_unop(val, op1, mem, ptr, mode,
2122                                                 new_rd_ia32_IncMem);
2123                         break;
2124                 } else if(is_Const_Minus_1(op2)) {
2125                         new_node = dest_am_unop(val, op1, mem, ptr, mode,
2126                                                 new_rd_ia32_DecMem);
2127                         break;
2128                 }
2129                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2130                                          new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2131                                          match_dest_am | match_commutative |
2132                                          match_immediate);
2133                 break;
2134         case iro_Sub:
2135                 op1      = get_Sub_left(val);
2136                 op2      = get_Sub_right(val);
2137                 if(is_Const(op2)) {
2138                         ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2139                                    "found\n");
2140                 }
2141                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2142                                          new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2143                                          match_dest_am | match_immediate |
2144                                          match_immediate);
2145                 break;
2146         case iro_And:
2147                 op1      = get_And_left(val);
2148                 op2      = get_And_right(val);
2149                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2150                                          new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2151                                          match_dest_am | match_commutative |
2152                                          match_immediate);
2153                 break;
2154         case iro_Or:
2155                 op1      = get_Or_left(val);
2156                 op2      = get_Or_right(val);
2157                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2158                                          new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2159                                          match_dest_am | match_commutative |
2160                                          match_immediate);
2161                 break;
2162         case iro_Eor:
2163                 op1      = get_Eor_left(val);
2164                 op2      = get_Eor_right(val);
2165                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2166                                          new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2167                                          match_dest_am | match_commutative |
2168                                          match_immediate);
2169                 break;
2170         case iro_Shl:
2171                 op1      = get_Shl_left(val);
2172                 op2      = get_Shl_right(val);
2173                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2174                                          new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2175                                          match_dest_am | match_immediate);
2176                 break;
2177         case iro_Shr:
2178                 op1      = get_Shr_left(val);
2179                 op2      = get_Shr_right(val);
2180                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2181                                          new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2182                                          match_dest_am | match_immediate);
2183                 break;
2184         case iro_Shrs:
2185                 op1      = get_Shrs_left(val);
2186                 op2      = get_Shrs_right(val);
2187                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2188                                          new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2189                                          match_dest_am | match_immediate);
2190                 break;
2191         case iro_Rotl:
2192                 op1      = get_Rotl_left(val);
2193                 op2      = get_Rotl_right(val);
2194                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2195                                          new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2196                                          match_dest_am | match_immediate);
2197                 break;
2198         /* TODO: match ROR patterns... */
2199         case iro_Mux:
2200                 new_node = try_create_SetMem(val, ptr, mem);
2201                 break;
2202         case iro_Minus:
2203                 op1      = get_Minus_op(val);
2204                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2205                 break;
2206         case iro_Not:
2207                 /* should be lowered already */
2208                 assert(mode != mode_b);
2209                 op1      = get_Not_op(val);
2210                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2211                 break;
2212         default:
2213                 return NULL;
2214         }
2215
2216         if(new_node != NULL) {
2217                 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2218                                 get_irn_pinned(node) == op_pin_state_pinned) {
2219                         set_irn_pinned(new_node, op_pin_state_pinned);
2220                 }
2221         }
2222
2223         return new_node;
2224 }
2225
2226 static int is_float_to_int32_conv(const ir_node *node)
2227 {
2228         ir_mode  *mode = get_irn_mode(node);
2229         ir_node  *conv_op;
2230         ir_mode  *conv_mode;
2231
2232         if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode))
2233                 return 0;
2234         /* don't report unsigned as conv to 32bit, because we really need to do
2235          * a vfist with 64bit signed in this case */
2236         if(!mode_is_signed(mode))
2237                 return 0;
2238
2239         if(!is_Conv(node))
2240                 return 0;
2241         conv_op   = get_Conv_op(node);
2242         conv_mode = get_irn_mode(conv_op);
2243
2244         if(!mode_is_float(conv_mode))
2245                 return 0;
2246
2247         return 1;
2248 }
2249
2250 /**
2251  * Transform a Store(floatConst).
2252  *
2253  * @return the created ia32 Store node
2254  */
2255 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2256         ir_mode  *mode      = get_irn_mode(cns);
2257         int      size       = get_mode_size_bits(mode);
2258         tarval   *tv        = get_Const_tarval(cns);
2259         ir_node  *block     = get_nodes_block(node);
2260         ir_node  *new_block = be_transform_node(block);
2261         ir_node  *ptr       = get_Store_ptr(node);
2262         ir_node  *mem       = get_Store_mem(node);
2263         ir_graph *irg       = current_ir_graph;
2264         dbg_info *dbgi      = get_irn_dbg_info(node);
2265         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2266         int      ofs        = 4;
2267         ir_node  *new_node;
2268         ia32_address_t addr;
2269
2270         unsigned val = get_tarval_sub_bits(tv, 0) |
2271                 (get_tarval_sub_bits(tv, 1) << 8) |
2272                 (get_tarval_sub_bits(tv, 2) << 16) |
2273                 (get_tarval_sub_bits(tv, 3) << 24);
2274         ir_node *imm = create_Immediate(NULL, 0, val);
2275
2276         /* construct store address */
2277         memset(&addr, 0, sizeof(addr));
2278         ia32_create_address_mode(&addr, ptr, /*force=*/0);
2279
2280         if (addr.base == NULL) {
2281                 addr.base = noreg;
2282         } else {
2283                 addr.base = be_transform_node(addr.base);
2284         }
2285
2286         if (addr.index == NULL) {
2287                 addr.index = noreg;
2288         } else {
2289                 addr.index = be_transform_node(addr.index);
2290         }
2291         addr.mem = be_transform_node(mem);
2292
2293         new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2294                 addr.index, addr.mem, imm);
2295
2296         set_irn_pinned(new_node, get_irn_pinned(node));
2297         set_ia32_op_type(new_node, ia32_AddrModeD);
2298         set_ia32_ls_mode(new_node, mode_Iu);
2299
2300         set_address(new_node, &addr);
2301
2302         /** add more stores if needed */
2303         while (size > 32) {
2304                 unsigned val = get_tarval_sub_bits(tv, ofs) |
2305                         (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2306                         (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2307                         (get_tarval_sub_bits(tv, ofs + 3) << 24);
2308                 ir_node *imm = create_Immediate(NULL, 0, val);
2309
2310                 addr.offset += 4;
2311                 addr.mem = new_node;
2312
2313                 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2314                         addr.index, addr.mem, imm);
2315
2316                 set_irn_pinned(new_node, get_irn_pinned(node));
2317                 set_ia32_op_type(new_node, ia32_AddrModeD);
2318                 set_ia32_ls_mode(new_node, mode_Iu);
2319
2320                 set_address(new_node, &addr);
2321                 size -= 32;
2322                 ofs  += 4;
2323         }
2324
2325         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2326         return new_node;
2327 }
2328
2329 /**
2330  * Generate a vfist or vfisttp instruction.
2331  */
2332 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2333                           ir_node *mem,  ir_node *val, ir_node **fist)
2334 {
2335         ir_node *new_node;
2336
2337         if (ia32_cg_config.use_fisttp) {
2338                 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2339                 if other users exists */
2340                 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2341                 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2342                 ir_node *value   = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2343                 be_new_Keep(reg_class, irg, block, 1, &value);
2344
2345                 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2346                 *fist    = vfisttp;
2347         } else {
2348                 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2349
2350                 /* do a fist */
2351                 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2352                 *fist    = new_node;
2353         }
2354         return new_node;
2355 }
2356 /**
2357  * Transforms a normal Store.
2358  *
2359  * @return the created ia32 Store node
2360  */
2361 static ir_node *gen_normal_Store(ir_node *node)
2362 {
2363         ir_node  *val       = get_Store_value(node);
2364         ir_mode  *mode      = get_irn_mode(val);
2365         ir_node  *block     = get_nodes_block(node);
2366         ir_node  *new_block = be_transform_node(block);
2367         ir_node  *ptr       = get_Store_ptr(node);
2368         ir_node  *mem       = get_Store_mem(node);
2369         ir_graph *irg       = current_ir_graph;
2370         dbg_info *dbgi      = get_irn_dbg_info(node);
2371         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2372         ir_node  *new_val, *new_node, *store;
2373         ia32_address_t addr;
2374
2375         /* check for destination address mode */
2376         new_node = try_create_dest_am(node);
2377         if (new_node != NULL)
2378                 return new_node;
2379
2380         /* construct store address */
2381         memset(&addr, 0, sizeof(addr));
2382         ia32_create_address_mode(&addr, ptr, /*force=*/0);
2383
2384         if (addr.base == NULL) {
2385                 addr.base = noreg;
2386         } else {
2387                 addr.base = be_transform_node(addr.base);
2388         }
2389
2390         if (addr.index == NULL) {
2391                 addr.index = noreg;
2392         } else {
2393                 addr.index = be_transform_node(addr.index);
2394         }
2395         addr.mem = be_transform_node(mem);
2396
2397         if (mode_is_float(mode)) {
2398                 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2399                    is the same. */
2400                 while (is_Conv(val) && mode == get_irn_mode(val)) {
2401                         ir_node *op = get_Conv_op(val);
2402                         if (!mode_is_float(get_irn_mode(op)))
2403                                 break;
2404                         val = op;
2405                 }
2406                 new_val = be_transform_node(val);
2407                 if (ia32_cg_config.use_sse2) {
2408                         new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2409                                                       addr.index, addr.mem, new_val);
2410                 } else {
2411                         new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2412                                                     addr.index, addr.mem, new_val, mode);
2413                 }
2414                 store = new_node;
2415         } else if (!ia32_cg_config.use_sse2 && is_float_to_int32_conv(val)) {
2416                 val = get_Conv_op(val);
2417
2418                 /* TODO: is this optimisation still necessary at all (middleend)? */
2419                 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2420                 while (is_Conv(val)) {
2421                         ir_node *op = get_Conv_op(val);
2422                         if (!mode_is_float(get_irn_mode(op)))
2423                                 break;
2424                         if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2425                                 break;
2426                         val = op;
2427                 }
2428                 new_val  = be_transform_node(val);
2429                 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2430         } else {
2431                 new_val = create_immediate_or_transform(val, 0);
2432                 assert(mode != mode_b);
2433
2434                 if (get_mode_size_bits(mode) == 8) {
2435                         new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2436                                                          addr.index, addr.mem, new_val);
2437                 } else {
2438                         new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2439                                                      addr.index, addr.mem, new_val);
2440                 }
2441                 store = new_node;
2442         }
2443
2444         set_irn_pinned(store, get_irn_pinned(node));
2445         set_ia32_op_type(store, ia32_AddrModeD);
2446         set_ia32_ls_mode(store, mode);
2447
2448         set_address(store, &addr);
2449         SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2450
2451         return new_node;
2452 }
2453
2454 /**
2455  * Transforms a Store.
2456  *
2457  * @return the created ia32 Store node
2458  */
2459 static ir_node *gen_Store(ir_node *node)
2460 {
2461         ir_node  *val  = get_Store_value(node);
2462         ir_mode  *mode = get_irn_mode(val);
2463
2464         if (mode_is_float(mode) && is_Const(val)) {
2465                 int transform = 1;
2466
2467                 /* we are storing a floating point constant */
2468                 if (ia32_cg_config.use_sse2) {
2469                         transform = !is_simple_sse_Const(val);
2470                 } else {
2471                         transform = !is_simple_x87_Const(val);
2472                 }
2473                 if (transform)
2474                         return gen_float_const_Store(node, val);
2475         }
2476         return gen_normal_Store(node);
2477 }
2478
2479 /**
2480  * Transforms a Switch.
2481  *
2482  * @return the created ia32 SwitchJmp node
2483  */
2484 static ir_node *create_Switch(ir_node *node)
2485 {
2486         ir_graph *irg        = current_ir_graph;
2487         dbg_info *dbgi       = get_irn_dbg_info(node);
2488         ir_node  *block      = be_transform_node(get_nodes_block(node));
2489         ir_node  *sel        = get_Cond_selector(node);
2490         ir_node  *new_sel    = be_transform_node(sel);
2491         int       switch_min = INT_MAX;
2492         int       switch_max = INT_MIN;
2493         long      default_pn = get_Cond_defaultProj(node);
2494         ir_node  *new_node;
2495         const ir_edge_t *edge;
2496
2497         assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2498
2499         /* determine the smallest switch case value */
2500         foreach_out_edge(node, edge) {
2501                 ir_node *proj = get_edge_src_irn(edge);
2502                 long     pn   = get_Proj_proj(proj);
2503                 if(pn == default_pn)
2504                         continue;
2505
2506                 if(pn < switch_min)
2507                         switch_min = pn;
2508                 if(pn > switch_max)
2509                         switch_max = pn;
2510         }
2511
2512         if((unsigned) (switch_max - switch_min) > 256000) {
2513                 panic("Size of switch %+F bigger than 256000", node);
2514         }
2515
2516         if (switch_min != 0) {
2517                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2518
2519                 /* if smallest switch case is not 0 we need an additional sub */
2520                 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2521                 add_ia32_am_offs_int(new_sel, -switch_min);
2522                 set_ia32_op_type(new_sel, ia32_AddrModeS);
2523
2524                 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2525         }
2526
2527         new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2528         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2529
2530         return new_node;
2531 }
2532
2533 /**
2534  * Transform a Cond node.
2535  */
2536 static ir_node *gen_Cond(ir_node *node) {
2537         ir_node  *block     = get_nodes_block(node);
2538         ir_node  *new_block = be_transform_node(block);
2539         ir_graph *irg       = current_ir_graph;
2540         dbg_info *dbgi      = get_irn_dbg_info(node);
2541         ir_node  *sel       = get_Cond_selector(node);
2542         ir_mode  *sel_mode  = get_irn_mode(sel);
2543         ir_node  *flags     = NULL;
2544         ir_node  *new_node;
2545         pn_Cmp    pnc;
2546
2547         if (sel_mode != mode_b) {
2548                 return create_Switch(node);
2549         }
2550
2551         /* we get flags from a Cmp */
2552         flags = get_flags_node(sel, &pnc);
2553
2554         new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2555         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2556
2557         return new_node;
2558 }
2559
2560 /**
2561  * Transforms a CopyB node.
2562  *
2563  * @return The transformed node.
2564  */
2565 static ir_node *gen_CopyB(ir_node *node) {
2566         ir_node  *block    = be_transform_node(get_nodes_block(node));
2567         ir_node  *src      = get_CopyB_src(node);
2568         ir_node  *new_src  = be_transform_node(src);
2569         ir_node  *dst      = get_CopyB_dst(node);
2570         ir_node  *new_dst  = be_transform_node(dst);
2571         ir_node  *mem      = get_CopyB_mem(node);
2572         ir_node  *new_mem  = be_transform_node(mem);
2573         ir_node  *res      = NULL;
2574         ir_graph *irg      = current_ir_graph;
2575         dbg_info *dbgi     = get_irn_dbg_info(node);
2576         int      size      = get_type_size_bytes(get_CopyB_type(node));
2577         int      rem;
2578
2579         /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2580         /* then we need the size explicitly in ECX.                    */
2581         if (size >= 32 * 4) {
2582                 rem = size & 0x3; /* size % 4 */
2583                 size >>= 2;
2584
2585                 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2586                 add_irn_dep(res, get_irg_frame(irg));
2587
2588                 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2589         } else {
2590                 if(size == 0) {
2591                         ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2592                                    node);
2593                 }
2594                 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2595         }
2596
2597         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2598
2599         return res;
2600 }
2601
2602 static ir_node *gen_be_Copy(ir_node *node)
2603 {
2604         ir_node *new_node = be_duplicate_node(node);
2605         ir_mode *mode     = get_irn_mode(new_node);
2606
2607         if (ia32_mode_needs_gp_reg(mode)) {
2608                 set_irn_mode(new_node, mode_Iu);
2609         }
2610
2611         return new_node;
2612 }
2613
2614 static ir_node *create_Fucom(ir_node *node)
2615 {
2616         ir_graph *irg       = current_ir_graph;
2617         dbg_info *dbgi      = get_irn_dbg_info(node);
2618         ir_node  *block     = get_nodes_block(node);
2619         ir_node  *new_block = be_transform_node(block);
2620         ir_node  *left      = get_Cmp_left(node);
2621         ir_node  *new_left  = be_transform_node(left);
2622         ir_node  *right     = get_Cmp_right(node);
2623         ir_node  *new_right;
2624         ir_node  *new_node;
2625
2626         if(ia32_cg_config.use_fucomi) {
2627                 new_right = be_transform_node(right);
2628                 new_node  = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2629                                                 new_right, 0);
2630                 set_ia32_commutative(new_node);
2631                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2632         } else {
2633                 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2634                         new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2635                                                            0);
2636                 } else {
2637                         new_right = be_transform_node(right);
2638                         new_node  = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2639                                                                                                  new_right, 0);
2640                 }
2641
2642                 set_ia32_commutative(new_node);
2643
2644                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2645
2646                 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2647                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2648         }
2649
2650         return new_node;
2651 }
2652
2653 static ir_node *create_Ucomi(ir_node *node)
2654 {
2655         ir_graph *irg       = current_ir_graph;
2656         dbg_info *dbgi      = get_irn_dbg_info(node);
2657         ir_node  *src_block = get_nodes_block(node);
2658         ir_node  *new_block = be_transform_node(src_block);
2659         ir_node  *left      = get_Cmp_left(node);
2660         ir_node  *right     = get_Cmp_right(node);
2661         ir_node  *new_node;
2662         ia32_address_mode_t  am;
2663         ia32_address_t      *addr = &am.addr;
2664
2665         match_arguments(&am, src_block, left, right, NULL,
2666                         match_commutative | match_am);
2667
2668         new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2669                                      addr->mem, am.new_op1, am.new_op2,
2670                                      am.ins_permuted);
2671         set_am_attributes(new_node, &am);
2672
2673         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2674
2675         new_node = fix_mem_proj(new_node, &am);
2676
2677         return new_node;
2678 }
2679
2680 /**
2681  * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2682  * to fold an and into a test node
2683  */
2684 static int can_fold_test_and(ir_node *node)
2685 {
2686         const ir_edge_t *edge;
2687
2688         /** we can only have eq and lg projs */
2689         foreach_out_edge(node, edge) {
2690                 ir_node *proj = get_edge_src_irn(edge);
2691                 pn_Cmp   pnc  = get_Proj_proj(proj);
2692                 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2693                         return 0;
2694         }
2695
2696         return 1;
2697 }
2698
2699 /**
2700  * Generate code for a Cmp.
2701  */
2702 static ir_node *gen_Cmp(ir_node *node)
2703 {
2704         ir_graph *irg       = current_ir_graph;
2705         dbg_info *dbgi      = get_irn_dbg_info(node);
2706         ir_node  *block     = get_nodes_block(node);
2707         ir_node  *new_block = be_transform_node(block);
2708         ir_node  *left      = get_Cmp_left(node);
2709         ir_node  *right     = get_Cmp_right(node);
2710         ir_mode  *cmp_mode  = get_irn_mode(left);
2711         ir_node  *new_node;
2712         ia32_address_mode_t  am;
2713         ia32_address_t      *addr = &am.addr;
2714         int                  cmp_unsigned;
2715
2716         if(mode_is_float(cmp_mode)) {
2717                 if (ia32_cg_config.use_sse2) {
2718                         return create_Ucomi(node);
2719                 } else {
2720                         return create_Fucom(node);
2721                 }
2722         }
2723
2724         assert(ia32_mode_needs_gp_reg(cmp_mode));
2725
2726         /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2727         cmp_unsigned = !mode_is_signed(cmp_mode);
2728         if (is_Const_0(right)          &&
2729             is_And(left)               &&
2730             get_irn_n_edges(left) == 1 &&
2731             can_fold_test_and(node)) {
2732                 /* Test(and_left, and_right) */
2733                 ir_node *and_left  = get_And_left(left);
2734                 ir_node *and_right = get_And_right(left);
2735                 ir_mode *mode      = get_irn_mode(and_left);
2736
2737                 match_arguments(&am, block, and_left, and_right, NULL,
2738                                                                                 match_commutative |
2739                                                                                 match_am | match_8bit_am | match_16bit_am |
2740                                                                                 match_am_and_immediates | match_immediate |
2741                                                                                 match_8bit | match_16bit);
2742                 if (get_mode_size_bits(mode) == 8) {
2743                         new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2744                                                                                                                                                         addr->index, addr->mem, am.new_op1,
2745                                                                                                                                                         am.new_op2, am.ins_permuted,
2746                                                                                                                                                         cmp_unsigned);
2747                 } else {
2748                         new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2749                                                                                                                                         addr->index, addr->mem, am.new_op1,
2750                                                                                                                                         am.new_op2, am.ins_permuted, cmp_unsigned);
2751                 }
2752         } else {
2753                 /* Cmp(left, right) */
2754                 match_arguments(&am, block, left, right, NULL,
2755                                 match_commutative | match_am | match_8bit_am |
2756                                 match_16bit_am | match_am_and_immediates |
2757                                 match_immediate | match_8bit | match_16bit);
2758                 if (get_mode_size_bits(cmp_mode) == 8) {
2759                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2760                                                        addr->index, addr->mem, am.new_op1,
2761                                                        am.new_op2, am.ins_permuted,
2762                                                        cmp_unsigned);
2763                 } else {
2764                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2765                                                    addr->index, addr->mem, am.new_op1,
2766                                                    am.new_op2, am.ins_permuted, cmp_unsigned);
2767                 }
2768         }
2769         set_am_attributes(new_node, &am);
2770         set_ia32_ls_mode(new_node, cmp_mode);
2771
2772         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2773
2774         new_node = fix_mem_proj(new_node, &am);
2775
2776         return new_node;
2777 }
2778
2779 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2780                             pn_Cmp pnc)
2781 {
2782         ir_graph            *irg           = current_ir_graph;
2783         dbg_info            *dbgi          = get_irn_dbg_info(node);
2784         ir_node             *block         = get_nodes_block(node);
2785         ir_node             *new_block     = be_transform_node(block);
2786         ir_node             *val_true      = get_Mux_true(node);
2787         ir_node             *val_false     = get_Mux_false(node);
2788         ir_node             *new_node;
2789         match_flags_t        match_flags;
2790         ia32_address_mode_t  am;
2791         ia32_address_t      *addr;
2792
2793         assert(ia32_cg_config.use_cmov);
2794         assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2795
2796         addr = &am.addr;
2797
2798         match_flags = match_commutative | match_am | match_16bit_am |
2799                       match_mode_neutral;
2800
2801         match_arguments(&am, block, val_false, val_true, flags, match_flags);
2802
2803         new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2804                                     addr->mem, am.new_op1, am.new_op2, new_flags,
2805                                     am.ins_permuted, pnc);
2806         set_am_attributes(new_node, &am);
2807
2808         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2809
2810         new_node = fix_mem_proj(new_node, &am);
2811
2812         return new_node;
2813 }
2814
2815 /**
2816  * Creates a ia32 Setcc instruction.
2817  */
2818 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2819                                  ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2820                                  int ins_permuted)
2821 {
2822         ir_graph *irg   = current_ir_graph;
2823         ir_node  *noreg = ia32_new_NoReg_gp(env_cg);
2824         ir_node  *nomem = new_NoMem();
2825         ir_mode  *mode  = get_irn_mode(orig_node);
2826         ir_node  *new_node;
2827
2828         new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2829         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2830
2831         /* we might need to conv the result up */
2832         if (get_mode_size_bits(mode) > 8) {
2833                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2834                                                     nomem, new_node, mode_Bu);
2835                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2836         }
2837
2838         return new_node;
2839 }
2840
2841 /**
2842  * Create instruction for an unsigned Difference or Zero.
2843  */
2844 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2845         ir_graph *irg   = current_ir_graph;
2846         ir_mode  *mode  = get_irn_mode(psi);
2847         ir_node  *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2848         dbg_info *dbgi;
2849
2850         new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2851                 match_mode_neutral | match_am | match_immediate | match_two_users);
2852
2853         block = get_nodes_block(new_node);
2854
2855         if (is_Proj(new_node)) {
2856                 sub = get_Proj_pred(new_node);
2857                 assert(is_ia32_Sub(sub));
2858         } else {
2859                 sub = new_node;
2860                 set_irn_mode(sub, mode_T);
2861                 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2862         }
2863         eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2864
2865         dbgi   = get_irn_dbg_info(psi);
2866         noreg  = ia32_new_NoReg_gp(env_cg);
2867         tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2868         nomem  = new_NoMem();
2869         sbb    = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2870
2871         new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2872         set_ia32_commutative(new_node);
2873         return new_node;
2874 }
2875
2876 /**
2877  * Transforms a Mux node into CMov.
2878  *
2879  * @return The transformed node.
2880  */
2881 static ir_node *gen_Mux(ir_node *node)
2882 {
2883         dbg_info *dbgi        = get_irn_dbg_info(node);
2884         ir_node  *block       = get_nodes_block(node);
2885         ir_node  *new_block   = be_transform_node(block);
2886         ir_node  *mux_true    = get_Mux_true(node);
2887         ir_node  *mux_false   = get_Mux_false(node);
2888         ir_node  *cond        = get_Mux_sel(node);
2889         ir_mode  *mode        = get_irn_mode(node);
2890         pn_Cmp   pnc;
2891
2892         assert(get_irn_mode(cond) == mode_b);
2893
2894         /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2895         if (mode_is_float(mode)) {
2896                 ir_node  *cmp         = get_Proj_pred(cond);
2897                 ir_node  *cmp_left    = get_Cmp_left(cmp);
2898                 ir_node  *cmp_right   = get_Cmp_right(cmp);
2899                 pn_Cmp   pnc          = get_Proj_proj(cond);
2900
2901                 if (ia32_cg_config.use_sse2) {
2902                         if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2903                                 if (cmp_left == mux_true && cmp_right == mux_false) {
2904                                         /* Mux(a <= b, a, b) => MIN */
2905                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2906                                          match_commutative | match_am | match_two_users);
2907                                 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2908                                         /* Mux(a <= b, b, a) => MAX */
2909                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2910                                          match_commutative | match_am | match_two_users);
2911                                 }
2912                         } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2913                                 if (cmp_left == mux_true && cmp_right == mux_false) {
2914                                         /* Mux(a >= b, a, b) => MAX */
2915                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2916                                          match_commutative | match_am | match_two_users);
2917                                 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2918                                         /* Mux(a >= b, b, a) => MIN */
2919                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2920                                          match_commutative | match_am | match_two_users);
2921                                 }
2922                         }
2923                 }
2924                 panic("cannot transform floating point Mux");
2925
2926         } else {
2927                 ir_node *flags;
2928                 ir_node *new_node;
2929
2930                 assert(ia32_mode_needs_gp_reg(mode));
2931
2932                 if (is_Proj(cond)) {
2933                         ir_node *cmp = get_Proj_pred(cond);
2934                         if (is_Cmp(cmp)) {
2935                                 ir_node  *cmp_left    = get_Cmp_left(cmp);
2936                                 ir_node  *cmp_right   = get_Cmp_right(cmp);
2937                                 pn_Cmp   pnc          = get_Proj_proj(cond);
2938
2939                                 /* check for unsigned Doz first */
2940                                 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2941                                         is_Const_0(mux_false) && is_Sub(mux_true) &&
2942                                         get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2943                                         /* Mux(a >=u b, a - b, 0) unsigned Doz */
2944                                         return create_Doz(node, cmp_left, cmp_right);
2945                                 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2946                                         is_Const_0(mux_true) && is_Sub(mux_false) &&
2947                                         get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2948                                         /* Mux(a <=u b, 0, a - b) unsigned Doz */
2949                                         return create_Doz(node, cmp_left, cmp_right);
2950                                 }
2951                         }
2952                 }
2953
2954                 flags = get_flags_node(cond, &pnc);
2955
2956                 if (is_Const(mux_true) && is_Const(mux_false)) {
2957                         /* both are const, good */
2958                         if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2959                                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2960                         } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2961                                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2962                         } else {
2963                                 /* Not that simple. */
2964                                 goto need_cmov;
2965                         }
2966                 } else {
2967 need_cmov:
2968                         new_node = create_CMov(node, cond, flags, pnc);
2969                 }
2970                 return new_node;
2971         }
2972 }
2973
2974
2975 /**
2976  * Create a conversion from x87 state register to general purpose.
2977  */
2978 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
2979         ir_node         *block      = be_transform_node(get_nodes_block(node));
2980         ir_node         *op         = get_Conv_op(node);
2981         ir_node         *new_op     = be_transform_node(op);
2982         ia32_code_gen_t *cg         = env_cg;
2983         ir_graph        *irg        = current_ir_graph;
2984         dbg_info        *dbgi       = get_irn_dbg_info(node);
2985         ir_node         *noreg      = ia32_new_NoReg_gp(cg);
2986         ir_mode         *mode       = get_irn_mode(node);
2987         ir_node         *fist, *load, *mem;
2988
2989         mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
2990         set_irn_pinned(fist, op_pin_state_floats);
2991         set_ia32_use_frame(fist);
2992         set_ia32_op_type(fist, ia32_AddrModeD);
2993
2994         assert(get_mode_size_bits(mode) <= 32);
2995         /* exception we can only store signed 32 bit integers, so for unsigned
2996            we store a 64bit (signed) integer and load the lower bits */
2997         if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
2998                 set_ia32_ls_mode(fist, mode_Ls);
2999         } else {
3000                 set_ia32_ls_mode(fist, mode_Is);
3001         }
3002         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3003
3004         /* do a Load */
3005         load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3006
3007         set_irn_pinned(load, op_pin_state_floats);
3008         set_ia32_use_frame(load);
3009         set_ia32_op_type(load, ia32_AddrModeS);
3010         set_ia32_ls_mode(load, mode_Is);
3011         if(get_ia32_ls_mode(fist) == mode_Ls) {
3012                 ia32_attr_t *attr = get_ia32_attr(load);
3013                 attr->data.need_64bit_stackent = 1;
3014         } else {
3015                 ia32_attr_t *attr = get_ia32_attr(load);
3016                 attr->data.need_32bit_stackent = 1;
3017         }
3018         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3019
3020         return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3021 }
3022
3023 /**
3024  * Creates a x87 strict Conv by placing a Store and a Load
3025  */
3026 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3027 {
3028         ir_node  *block    = get_nodes_block(node);
3029         ir_graph *irg      = current_ir_graph;
3030         dbg_info *dbgi     = get_irn_dbg_info(node);
3031         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
3032         ir_node  *nomem    = new_NoMem();
3033         ir_node  *frame    = get_irg_frame(irg);
3034         ir_node  *store, *load;
3035         ir_node  *new_node;
3036
3037         store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3038                                  tgt_mode);
3039         set_ia32_use_frame(store);
3040         set_ia32_op_type(store, ia32_AddrModeD);
3041         SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3042
3043         load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3044                                 tgt_mode);
3045         set_ia32_use_frame(load);
3046         set_ia32_op_type(load, ia32_AddrModeS);
3047         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3048
3049         new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3050         return new_node;
3051 }
3052
3053 /**
3054  * Create a conversion from general purpose to x87 register
3055  */
3056 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3057         ir_node  *src_block = get_nodes_block(node);
3058         ir_node  *block     = be_transform_node(src_block);
3059         ir_graph *irg       = current_ir_graph;
3060         dbg_info *dbgi      = get_irn_dbg_info(node);
3061         ir_node  *op        = get_Conv_op(node);
3062         ir_node  *new_op    = NULL;
3063         ir_node  *noreg;
3064         ir_node  *nomem;
3065         ir_mode  *mode;
3066         ir_mode  *store_mode;
3067         ir_node  *fild;
3068         ir_node  *store;
3069         ir_node  *new_node;
3070         int       src_bits;
3071
3072         /* fild can use source AM if the operand is a signed 32bit integer */
3073         if (src_mode == mode_Is) {
3074                 ia32_address_mode_t am;
3075
3076                 match_arguments(&am, src_block, NULL, op, NULL,
3077                                 match_am | match_try_am);
3078                 if (am.op_type == ia32_AddrModeS) {
3079                         ia32_address_t *addr = &am.addr;
3080
3081                         fild     = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3082                                                      addr->index, addr->mem);
3083                         new_node = new_r_Proj(irg, block, fild, mode_vfp,
3084                                               pn_ia32_vfild_res);
3085
3086                         set_am_attributes(fild, &am);
3087                         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3088
3089                         fix_mem_proj(fild, &am);
3090
3091                         return new_node;
3092                 }
3093         }
3094         if(new_op == NULL) {
3095                 new_op = be_transform_node(op);
3096         }
3097
3098         noreg  = ia32_new_NoReg_gp(env_cg);
3099         nomem  = new_NoMem();
3100         mode   = get_irn_mode(op);
3101
3102         /* first convert to 32 bit signed if necessary */
3103         src_bits = get_mode_size_bits(src_mode);
3104         if (src_bits == 8) {
3105                 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3106                                                   new_op, src_mode);
3107                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3108                 mode = mode_Is;
3109         } else if (src_bits < 32) {
3110                 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3111                                               new_op, src_mode);
3112                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3113                 mode = mode_Is;
3114         }
3115
3116         assert(get_mode_size_bits(mode) == 32);
3117
3118         /* do a store */
3119         store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3120                                   new_op);
3121
3122         set_ia32_use_frame(store);
3123         set_ia32_op_type(store, ia32_AddrModeD);
3124         set_ia32_ls_mode(store, mode_Iu);
3125
3126         /* exception for 32bit unsigned, do a 64bit spill+load */
3127         if(!mode_is_signed(mode)) {
3128                 ir_node *in[2];
3129                 /* store a zero */
3130                 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3131
3132                 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3133                                                         get_irg_frame(irg), noreg, nomem,
3134                                                         zero_const);
3135
3136                 set_ia32_use_frame(zero_store);
3137                 set_ia32_op_type(zero_store, ia32_AddrModeD);
3138                 add_ia32_am_offs_int(zero_store, 4);
3139                 set_ia32_ls_mode(zero_store, mode_Iu);
3140
3141                 in[0] = zero_store;
3142                 in[1] = store;
3143
3144                 store      = new_rd_Sync(dbgi, irg, block, 2, in);
3145                 store_mode = mode_Ls;
3146         } else {
3147                 store_mode = mode_Is;
3148         }
3149
3150         /* do a fild */
3151         fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3152
3153         set_ia32_use_frame(fild);
3154         set_ia32_op_type(fild, ia32_AddrModeS);
3155         set_ia32_ls_mode(fild, store_mode);
3156
3157         new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3158
3159         return new_node;
3160 }
3161
3162 /**
3163  * Create a conversion from one integer mode into another one
3164  */
3165 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3166                                 dbg_info *dbgi, ir_node *block, ir_node *op,
3167                                 ir_node *node)
3168 {
3169         ir_graph *irg       = current_ir_graph;
3170         int       src_bits  = get_mode_size_bits(src_mode);
3171         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3172         ir_node  *new_block = be_transform_node(block);
3173         ir_node  *new_node;
3174         ir_mode  *smaller_mode;
3175         int       smaller_bits;
3176         ia32_address_mode_t  am;
3177         ia32_address_t      *addr = &am.addr;
3178
3179         (void) node;
3180         if (src_bits < tgt_bits) {
3181                 smaller_mode = src_mode;
3182                 smaller_bits = src_bits;
3183         } else {
3184                 smaller_mode = tgt_mode;
3185                 smaller_bits = tgt_bits;
3186         }
3187
3188 #ifdef DEBUG_libfirm
3189         if(is_Const(op)) {
3190                 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3191                            op);
3192         }
3193 #endif
3194
3195         match_arguments(&am, block, NULL, op, NULL,
3196                         match_8bit | match_16bit |
3197                         match_am | match_8bit_am | match_16bit_am);
3198         if (smaller_bits == 8) {
3199                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3200                                                     addr->index, addr->mem, am.new_op2,
3201                                                     smaller_mode);
3202         } else {
3203                 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3204                                                 addr->index, addr->mem, am.new_op2,
3205                                                 smaller_mode);
3206         }
3207         set_am_attributes(new_node, &am);
3208         /* match_arguments assume that out-mode = in-mode, this isn't true here
3209          * so fix it */
3210         set_ia32_ls_mode(new_node, smaller_mode);
3211         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3212         new_node = fix_mem_proj(new_node, &am);
3213         return new_node;
3214 }
3215
3216 /**
3217  * Transforms a Conv node.
3218  *
3219  * @return The created ia32 Conv node
3220  */
3221 static ir_node *gen_Conv(ir_node *node) {
3222         ir_node  *block     = get_nodes_block(node);
3223         ir_node  *new_block = be_transform_node(block);
3224         ir_node  *op        = get_Conv_op(node);
3225         ir_node  *new_op    = NULL;
3226         ir_graph *irg       = current_ir_graph;
3227         dbg_info *dbgi      = get_irn_dbg_info(node);
3228         ir_mode  *src_mode  = get_irn_mode(op);
3229         ir_mode  *tgt_mode  = get_irn_mode(node);
3230         int       src_bits  = get_mode_size_bits(src_mode);
3231         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3232         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
3233         ir_node  *nomem     = new_rd_NoMem(irg);
3234         ir_node  *res       = NULL;
3235
3236         if (src_mode == mode_b) {
3237                 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3238                 /* nothing to do, we already model bools as 0/1 ints */
3239                 return be_transform_node(op);
3240         }
3241
3242         if (src_mode == tgt_mode) {
3243                 if (get_Conv_strict(node)) {
3244                         if (ia32_cg_config.use_sse2) {
3245                                 /* when we are in SSE mode, we can kill all strict no-op conversion */
3246                                 return be_transform_node(op);
3247                         }
3248                 } else {
3249                         /* this should be optimized already, but who knows... */
3250                         DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3251                         DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3252                         return be_transform_node(op);
3253                 }
3254         }
3255
3256         if (mode_is_float(src_mode)) {
3257                 new_op = be_transform_node(op);
3258                 /* we convert from float ... */
3259                 if (mode_is_float(tgt_mode)) {
3260                         if(src_mode == mode_E && tgt_mode == mode_D
3261                                         && !get_Conv_strict(node)) {
3262                                 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3263                                 return new_op;
3264                         }
3265
3266                         /* ... to float */
3267                         if (ia32_cg_config.use_sse2) {
3268                                 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3269                                 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3270                                                              nomem, new_op);
3271                                 set_ia32_ls_mode(res, tgt_mode);
3272                         } else {
3273                                 if(get_Conv_strict(node)) {
3274                                         res = gen_x87_strict_conv(tgt_mode, new_op);
3275                                         SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3276                                         return res;
3277                                 }
3278                                 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3279                                 return new_op;
3280                         }
3281                 } else {
3282                         /* ... to int */
3283                         DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3284                         if (ia32_cg_config.use_sse2) {
3285                                 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3286                                                             nomem, new_op);
3287                                 set_ia32_ls_mode(res, src_mode);
3288                         } else {
3289                                 return gen_x87_fp_to_gp(node);
3290                         }
3291                 }
3292         } else {
3293                 /* we convert from int ... */
3294                 if (mode_is_float(tgt_mode)) {
3295                         /* ... to float */
3296                         DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3297                         if (ia32_cg_config.use_sse2) {
3298                                 new_op = be_transform_node(op);
3299                                 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3300                                                             nomem, new_op);
3301                                 set_ia32_ls_mode(res, tgt_mode);
3302                         } else {
3303                                 res = gen_x87_gp_to_fp(node, src_mode);
3304                                 if(get_Conv_strict(node)) {
3305                                         /* The strict-Conv is only necessary, if the int mode has more bits
3306                                          * than the float mantissa */
3307                                         size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3308                                         size_t float_mantissa;
3309                                         /* FIXME There is no way to get the mantissa size of a mode */
3310                                         switch (get_mode_size_bits(tgt_mode)) {
3311                                                 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3312                                                 case 64: float_mantissa = 52 + 1; break;
3313                                                 case 80: float_mantissa = 64 + 1; break;
3314                                                 default: float_mantissa = 0;      break;
3315                                         }
3316                                         if (float_mantissa < int_mantissa) {
3317                                                 res = gen_x87_strict_conv(tgt_mode, res);
3318                                                 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3319                                         }
3320                                 }
3321                                 return res;
3322                         }
3323                 } else if(tgt_mode == mode_b) {
3324                         /* mode_b lowering already took care that we only have 0/1 values */
3325                         DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3326                             src_mode, tgt_mode));
3327                         return be_transform_node(op);
3328                 } else {
3329                         /* to int */
3330                         if (src_bits == tgt_bits) {
3331                                 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3332                                     src_mode, tgt_mode));
3333                                 return be_transform_node(op);
3334                         }
3335
3336                         res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3337                         return res;
3338                 }
3339         }
3340
3341         return res;
3342 }
3343
3344 static ir_node *create_immediate_or_transform(ir_node *node,
3345                                               char immediate_constraint_type)
3346 {
3347         ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3348         if (new_node == NULL) {
3349                 new_node = be_transform_node(node);
3350         }
3351         return new_node;
3352 }
3353
3354 /**
3355  * Transforms a FrameAddr into an ia32 Add.
3356  */
3357 static ir_node *gen_be_FrameAddr(ir_node *node) {
3358         ir_node  *block  = be_transform_node(get_nodes_block(node));
3359         ir_node  *op     = be_get_FrameAddr_frame(node);
3360         ir_node  *new_op = be_transform_node(op);
3361         ir_graph *irg    = current_ir_graph;
3362         dbg_info *dbgi   = get_irn_dbg_info(node);
3363         ir_node  *noreg  = ia32_new_NoReg_gp(env_cg);
3364         ir_node  *new_node;
3365
3366         new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3367         set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3368         set_ia32_use_frame(new_node);
3369
3370         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3371
3372         return new_node;
3373 }
3374
3375 /**
3376  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3377  */
3378 static ir_node *gen_be_Return(ir_node *node) {
3379         ir_graph  *irg     = current_ir_graph;
3380         ir_node   *ret_val = get_irn_n(node, be_pos_Return_val);
3381         ir_node   *ret_mem = get_irn_n(node, be_pos_Return_mem);
3382         ir_entity *ent     = get_irg_entity(irg);
3383         ir_type   *tp      = get_entity_type(ent);
3384         dbg_info  *dbgi;
3385         ir_node   *block;
3386         ir_type   *res_type;
3387         ir_mode   *mode;
3388         ir_node   *frame, *sse_store, *fld, *mproj, *barrier;
3389         ir_node   *new_barrier, *new_ret_val, *new_ret_mem;
3390         ir_node   *noreg;
3391         ir_node   **in;
3392         int       pn_ret_val, pn_ret_mem, arity, i;
3393
3394         assert(ret_val != NULL);
3395         if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3396                 return be_duplicate_node(node);
3397         }
3398
3399         res_type = get_method_res_type(tp, 0);
3400
3401         if (! is_Primitive_type(res_type)) {
3402                 return be_duplicate_node(node);
3403         }
3404
3405         mode = get_type_mode(res_type);
3406         if (! mode_is_float(mode)) {
3407                 return be_duplicate_node(node);
3408         }
3409
3410         assert(get_method_n_ress(tp) == 1);
3411
3412         pn_ret_val = get_Proj_proj(ret_val);
3413         pn_ret_mem = get_Proj_proj(ret_mem);
3414
3415         /* get the Barrier */
3416         barrier = get_Proj_pred(ret_val);
3417
3418         /* get result input of the Barrier */
3419         ret_val     = get_irn_n(barrier, pn_ret_val);
3420         new_ret_val = be_transform_node(ret_val);
3421
3422         /* get memory input of the Barrier */
3423         ret_mem     = get_irn_n(barrier, pn_ret_mem);
3424         new_ret_mem = be_transform_node(ret_mem);
3425
3426         frame = get_irg_frame(irg);
3427
3428         dbgi  = get_irn_dbg_info(barrier);
3429         block = be_transform_node(get_nodes_block(barrier));
3430
3431         noreg = ia32_new_NoReg_gp(env_cg);
3432
3433         /* store xmm0 onto stack */
3434         sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3435                                              new_ret_mem, new_ret_val);
3436         set_ia32_ls_mode(sse_store, mode);
3437         set_ia32_op_type(sse_store, ia32_AddrModeD);
3438         set_ia32_use_frame(sse_store);
3439
3440         /* load into x87 register */
3441         fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3442         set_ia32_op_type(fld, ia32_AddrModeS);
3443         set_ia32_use_frame(fld);
3444
3445         mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3446         fld   = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3447
3448         /* create a new barrier */
3449         arity = get_irn_arity(barrier);
3450         in = alloca(arity * sizeof(in[0]));
3451         for (i = 0; i < arity; ++i) {
3452                 ir_node *new_in;
3453
3454                 if (i == pn_ret_val) {
3455                         new_in = fld;
3456                 } else if (i == pn_ret_mem) {
3457                         new_in = mproj;
3458                 } else {
3459                         ir_node *in = get_irn_n(barrier, i);
3460                         new_in = be_transform_node(in);
3461                 }
3462                 in[i] = new_in;
3463         }
3464
3465         new_barrier = new_ir_node(dbgi, irg, block,
3466                                   get_irn_op(barrier), get_irn_mode(barrier),
3467                                   arity, in);
3468         copy_node_attr(barrier, new_barrier);
3469         be_duplicate_deps(barrier, new_barrier);
3470         be_set_transformed_node(barrier, new_barrier);
3471         mark_irn_visited(barrier);
3472
3473         /* transform normally */
3474         return be_duplicate_node(node);
3475 }
3476
3477 /**
3478  * Transform a be_AddSP into an ia32_SubSP.
3479  */
3480 static ir_node *gen_be_AddSP(ir_node *node)
3481 {
3482         ir_node  *sz = get_irn_n(node, be_pos_AddSP_size);
3483         ir_node  *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3484
3485         return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
3486 }
3487
3488 /**
3489  * Transform a be_SubSP into an ia32_AddSP
3490  */
3491 static ir_node *gen_be_SubSP(ir_node *node)
3492 {
3493         ir_node  *sz = get_irn_n(node, be_pos_SubSP_size);
3494         ir_node  *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3495
3496         return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
3497 }
3498
3499 /**
3500  * Change some phi modes
3501  */
3502 static ir_node *gen_Phi(ir_node *node) {
3503         ir_node  *block = be_transform_node(get_nodes_block(node));
3504         ir_graph *irg   = current_ir_graph;
3505         dbg_info *dbgi  = get_irn_dbg_info(node);
3506         ir_mode  *mode  = get_irn_mode(node);
3507         ir_node  *phi;
3508
3509         if(ia32_mode_needs_gp_reg(mode)) {
3510                 /* we shouldn't have any 64bit stuff around anymore */
3511                 assert(get_mode_size_bits(mode) <= 32);
3512                 /* all integer operations are on 32bit registers now */
3513                 mode = mode_Iu;
3514         } else if(mode_is_float(mode)) {
3515                 if (ia32_cg_config.use_sse2) {
3516                         mode = mode_xmm;
3517                 } else {
3518                         mode = mode_vfp;
3519                 }
3520         }
3521
3522         /* phi nodes allow loops, so we use the old arguments for now
3523          * and fix this later */
3524         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3525                           get_irn_in(node) + 1);
3526         copy_node_attr(node, phi);
3527         be_duplicate_deps(node, phi);
3528
3529         be_set_transformed_node(node, phi);
3530         be_enqueue_preds(node);
3531
3532         return phi;
3533 }
3534
3535 /**
3536  * Transform IJmp
3537  */
3538 static ir_node *gen_IJmp(ir_node *node)
3539 {
3540         ir_node  *block     = get_nodes_block(node);
3541         ir_node  *new_block = be_transform_node(block);
3542         dbg_info *dbgi      = get_irn_dbg_info(node);
3543         ir_node  *op        = get_IJmp_target(node);
3544         ir_node  *new_node;
3545         ia32_address_mode_t  am;
3546         ia32_address_t      *addr = &am.addr;
3547
3548         assert(get_irn_mode(op) == mode_P);
3549
3550         match_arguments(&am, block, NULL, op, NULL,
3551                         match_am | match_8bit_am | match_16bit_am |
3552                         match_immediate | match_8bit | match_16bit);
3553
3554         new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3555                                     addr->base, addr->index, addr->mem,
3556                                     am.new_op2);
3557         set_am_attributes(new_node, &am);
3558         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3559
3560         new_node = fix_mem_proj(new_node, &am);
3561
3562         return new_node;
3563 }
3564
3565 /**
3566  * Transform a Bound node.
3567  */
3568 static ir_node *gen_Bound(ir_node *node)
3569 {
3570         ir_node  *new_node;
3571         ir_node  *lower = get_Bound_lower(node);
3572         dbg_info *dbgi  = get_irn_dbg_info(node);
3573
3574         if (is_Const_0(lower)) {
3575                 /* typical case for Java */
3576                 ir_node  *sub, *res, *flags, *block;
3577                 ir_graph *irg  = current_ir_graph;
3578
3579                 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3580                         new_rd_ia32_Sub, match_mode_neutral     | match_am | match_immediate);
3581
3582                 block = get_nodes_block(res);
3583                 if (! is_Proj(res)) {
3584                         sub = res;
3585                         set_irn_mode(sub, mode_T);
3586                         res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3587                 } else {
3588                         sub = get_Proj_pred(res);
3589                 }
3590                 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3591                 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3592                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3593         } else {
3594                 panic("generic Bound not supported in ia32 Backend");
3595         }
3596         return new_node;
3597 }
3598
3599
3600 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3601                                      ir_node *mem);
3602
3603 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3604                                       ir_node *val, ir_node *mem);
3605
3606 /**
3607  * Transforms a lowered Load into a "real" one.
3608  */
3609 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
3610 {
3611         ir_node  *block   = be_transform_node(get_nodes_block(node));
3612         ir_node  *ptr     = get_irn_n(node, 0);
3613         ir_node  *new_ptr = be_transform_node(ptr);
3614         ir_node  *mem     = get_irn_n(node, 1);
3615         ir_node  *new_mem = be_transform_node(mem);
3616         ir_graph *irg     = current_ir_graph;
3617         dbg_info *dbgi    = get_irn_dbg_info(node);
3618         ir_mode  *mode    = get_ia32_ls_mode(node);
3619         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
3620         ir_node  *new_op;
3621
3622         new_op  = func(dbgi, irg, block, new_ptr, noreg, new_mem);
3623
3624         set_ia32_op_type(new_op, ia32_AddrModeS);
3625         set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
3626         set_ia32_am_scale(new_op, get_ia32_am_scale(node));
3627         set_ia32_am_sc(new_op, get_ia32_am_sc(node));
3628         if (is_ia32_am_sc_sign(node))
3629                 set_ia32_am_sc_sign(new_op);
3630         set_ia32_ls_mode(new_op, mode);
3631         if (is_ia32_use_frame(node)) {
3632                 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3633                 set_ia32_use_frame(new_op);
3634         }
3635
3636         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3637
3638         return new_op;
3639 }
3640
3641 /**
3642  * Transforms a lowered Store into a "real" one.
3643  */
3644 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
3645 {
3646         ir_node  *block   = be_transform_node(get_nodes_block(node));
3647         ir_node  *ptr     = get_irn_n(node, 0);
3648         ir_node  *new_ptr = be_transform_node(ptr);
3649         ir_node  *val     = get_irn_n(node, 1);
3650         ir_node  *new_val = be_transform_node(val);
3651         ir_node  *mem     = get_irn_n(node, 2);
3652         ir_node  *new_mem = be_transform_node(mem);
3653         ir_graph *irg     = current_ir_graph;
3654         dbg_info *dbgi    = get_irn_dbg_info(node);
3655         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
3656         ir_mode  *mode    = get_ia32_ls_mode(node);
3657         ir_node  *new_op;
3658         long     am_offs;
3659
3660         new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
3661
3662         am_offs = get_ia32_am_offs_int(node);
3663         add_ia32_am_offs_int(new_op, am_offs);
3664
3665         set_ia32_op_type(new_op, ia32_AddrModeD);
3666         set_ia32_ls_mode(new_op, mode);
3667         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3668         set_ia32_use_frame(new_op);
3669
3670         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3671
3672         return new_op;
3673 }
3674
3675 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3676 {
3677         ir_node *left  = get_irn_n(node, n_ia32_l_ShlDep_val);
3678         ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3679
3680         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3681                                match_immediate | match_mode_neutral);
3682 }
3683
3684 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3685 {
3686         ir_node *left  = get_irn_n(node, n_ia32_l_ShrDep_val);
3687         ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3688         return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3689                                match_immediate);
3690 }
3691
3692 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3693 {
3694         ir_node *left  = get_irn_n(node, n_ia32_l_SarDep_val);
3695         ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3696         return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3697                                match_immediate);
3698 }
3699
3700 static ir_node *gen_ia32_l_Add(ir_node *node) {
3701         ir_node *left    = get_irn_n(node, n_ia32_l_Add_left);
3702         ir_node *right   = get_irn_n(node, n_ia32_l_Add_right);
3703         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3704                         match_commutative | match_am | match_immediate |
3705                         match_mode_neutral);
3706
3707         if(is_Proj(lowered)) {
3708                 lowered = get_Proj_pred(lowered);
3709         } else {
3710                 assert(is_ia32_Add(lowered));
3711                 set_irn_mode(lowered, mode_T);
3712         }
3713
3714         return lowered;
3715 }
3716
3717 static ir_node *gen_ia32_l_Adc(ir_node *node)
3718 {
3719         return gen_binop_flags(node, new_rd_ia32_Adc,
3720                         match_commutative | match_am | match_immediate |
3721                         match_mode_neutral);
3722 }
3723
3724 /**
3725  * Transforms an ia32_l_vfild into a "real" ia32_vfild node
3726  *
3727  * @param node   The node to transform
3728  * @return the created ia32 vfild node
3729  */
3730 static ir_node *gen_ia32_l_vfild(ir_node *node) {
3731         return gen_lowered_Load(node, new_rd_ia32_vfild);
3732 }
3733
3734 /**
3735  * Transforms an ia32_l_Load into a "real" ia32_Load node
3736  *
3737  * @param node   The node to transform
3738  * @return the created ia32 Load node
3739  */
3740 static ir_node *gen_ia32_l_Load(ir_node *node) {
3741         return gen_lowered_Load(node, new_rd_ia32_Load);
3742 }
3743
3744 /**
3745  * Transforms an ia32_l_Store into a "real" ia32_Store node
3746  *
3747  * @param node   The node to transform
3748  * @return the created ia32 Store node
3749  */
3750 static ir_node *gen_ia32_l_Store(ir_node *node) {
3751         return gen_lowered_Store(node, new_rd_ia32_Store);
3752 }
3753
3754 /**
3755  * Transforms a l_vfist into a "real" vfist node.
3756  *
3757  * @param node   The node to transform
3758  * @return the created ia32 vfist node
3759  */
3760 static ir_node *gen_ia32_l_vfist(ir_node *node) {
3761         ir_node  *block      = be_transform_node(get_nodes_block(node));
3762         ir_node  *ptr        = get_irn_n(node, 0);
3763         ir_node  *new_ptr    = be_transform_node(ptr);
3764         ir_node  *val        = get_irn_n(node, 1);
3765         ir_node  *new_val    = be_transform_node(val);
3766         ir_node  *mem        = get_irn_n(node, 2);
3767         ir_node  *new_mem    = be_transform_node(mem);
3768         ir_graph *irg        = current_ir_graph;
3769         dbg_info *dbgi       = get_irn_dbg_info(node);
3770         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
3771         ir_mode  *mode       = get_ia32_ls_mode(node);
3772         ir_node  *memres, *fist;
3773         long     am_offs;
3774
3775         memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
3776         am_offs = get_ia32_am_offs_int(node);
3777         add_ia32_am_offs_int(fist, am_offs);
3778
3779         set_ia32_op_type(fist, ia32_AddrModeD);
3780         set_ia32_ls_mode(fist, mode);
3781         set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
3782         set_ia32_use_frame(fist);
3783
3784         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3785
3786         return memres;
3787 }
3788
3789 /**
3790  * Transforms a l_MulS into a "real" MulS node.
3791  *
3792  * @return the created ia32 Mul node
3793  */
3794 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3795         ir_node *left  = get_binop_left(node);
3796         ir_node *right = get_binop_right(node);
3797
3798         return gen_binop(node, left, right, new_rd_ia32_Mul,
3799                          match_commutative | match_am | match_mode_neutral);
3800 }
3801
3802 /**
3803  * Transforms a l_IMulS into a "real" IMul1OPS node.
3804  *
3805  * @return the created ia32 IMul1OP node
3806  */
3807 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3808         ir_node  *left  = get_binop_left(node);
3809         ir_node  *right = get_binop_right(node);
3810
3811         return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3812                          match_commutative | match_am | match_mode_neutral);
3813 }
3814
3815 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3816         ir_node *left    = get_irn_n(node, n_ia32_l_Sub_minuend);
3817         ir_node *right   = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3818         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3819                         match_am | match_immediate | match_mode_neutral);
3820
3821         if(is_Proj(lowered)) {
3822                 lowered = get_Proj_pred(lowered);
3823         } else {
3824                 assert(is_ia32_Sub(lowered));
3825                 set_irn_mode(lowered, mode_T);
3826         }
3827
3828         return lowered;
3829 }
3830
3831 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3832         return gen_binop_flags(node, new_rd_ia32_Sbb,
3833                         match_am | match_immediate | match_mode_neutral);
3834 }
3835
3836 /**
3837  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3838  * op1 - target to be shifted
3839  * op2 - contains bits to be shifted into target
3840  * op3 - shift count
3841  * Only op3 can be an immediate.
3842  */
3843 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3844                                          ir_node *low, ir_node *count)
3845 {
3846         ir_node  *block     = get_nodes_block(node);
3847         ir_node  *new_block = be_transform_node(block);
3848         ir_graph *irg       = current_ir_graph;
3849         dbg_info *dbgi      = get_irn_dbg_info(node);
3850         ir_node  *new_high  = be_transform_node(high);
3851         ir_node  *new_low   = be_transform_node(low);
3852         ir_node  *new_count;
3853         ir_node  *new_node;
3854
3855         /* the shift amount can be any mode that is bigger than 5 bits, since all
3856          * other bits are ignored anyway */
3857         while (is_Conv(count) && get_irn_n_edges(count) == 1) {
3858                 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3859                 count = get_Conv_op(count);
3860         }
3861         new_count = create_immediate_or_transform(count, 0);
3862
3863         if (is_ia32_l_ShlD(node)) {
3864                 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3865                                             new_count);
3866         } else {
3867                 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3868                                             new_count);
3869         }
3870         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3871
3872         return new_node;
3873 }
3874
3875 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3876 {
3877         ir_node *high  = get_irn_n(node, n_ia32_l_ShlD_val_high);
3878         ir_node *low   = get_irn_n(node, n_ia32_l_ShlD_val_low);
3879         ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3880         return gen_lowered_64bit_shifts(node, high, low, count);
3881 }
3882
3883 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3884 {
3885         ir_node *high  = get_irn_n(node, n_ia32_l_ShrD_val_high);
3886         ir_node *low   = get_irn_n(node, n_ia32_l_ShrD_val_low);
3887         ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3888         return gen_lowered_64bit_shifts(node, high, low, count);
3889 }
3890
3891 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3892         ir_node  *src_block    = get_nodes_block(node);
3893         ir_node  *block        = be_transform_node(src_block);
3894         ir_graph *irg          = current_ir_graph;
3895         dbg_info *dbgi         = get_irn_dbg_info(node);
3896         ir_node  *frame        = get_irg_frame(irg);
3897         ir_node  *noreg        = ia32_new_NoReg_gp(env_cg);
3898         ir_node  *nomem        = new_NoMem();
3899         ir_node  *val_low      = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3900         ir_node  *val_high     = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3901         ir_node  *new_val_low  = be_transform_node(val_low);
3902         ir_node  *new_val_high = be_transform_node(val_high);
3903         ir_node  *in[2];
3904         ir_node  *sync;
3905         ir_node  *fild;
3906         ir_node  *store_low;
3907         ir_node  *store_high;
3908
3909         if(!mode_is_signed(get_irn_mode(val_high))) {
3910                 panic("unsigned long long -> float not supported yet (%+F)", node);
3911         }
3912
3913         /* do a store */
3914         store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3915                                       new_val_low);
3916         store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3917                                        new_val_high);
3918         SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3919         SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3920
3921         set_ia32_use_frame(store_low);
3922         set_ia32_use_frame(store_high);
3923         set_ia32_op_type(store_low, ia32_AddrModeD);
3924         set_ia32_op_type(store_high, ia32_AddrModeD);
3925         set_ia32_ls_mode(store_low, mode_Iu);
3926         set_ia32_ls_mode(store_high, mode_Is);
3927         add_ia32_am_offs_int(store_high, 4);
3928
3929         in[0] = store_low;
3930         in[1] = store_high;
3931         sync  = new_rd_Sync(dbgi, irg, block, 2, in);
3932
3933         /* do a fild */
3934         fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3935
3936         set_ia32_use_frame(fild);
3937         set_ia32_op_type(fild, ia32_AddrModeS);
3938         set_ia32_ls_mode(fild, mode_Ls);
3939
3940         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3941
3942         return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3943 }
3944
3945 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3946         ir_node  *src_block  = get_nodes_block(node);
3947         ir_node  *block      = be_transform_node(src_block);
3948         ir_graph *irg        = current_ir_graph;
3949         dbg_info *dbgi       = get_irn_dbg_info(node);
3950         ir_node  *frame      = get_irg_frame(irg);
3951         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
3952         ir_node  *nomem      = new_NoMem();
3953         ir_node  *val        = get_irn_n(node, n_ia32_l_FloattoLL_val);
3954         ir_node  *new_val    = be_transform_node(val);
3955         ir_node  *fist, *mem;
3956
3957         mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3958         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3959         set_ia32_use_frame(fist);
3960         set_ia32_op_type(fist, ia32_AddrModeD);
3961         set_ia32_ls_mode(fist, mode_Ls);
3962
3963         return mem;
3964 }
3965
3966 /**
3967  * the BAD transformer.
3968  */
3969 static ir_node *bad_transform(ir_node *node) {
3970         panic("No transform function for %+F available.\n", node);
3971         return NULL;
3972 }
3973
3974 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
3975         ir_graph *irg      = current_ir_graph;
3976         ir_node  *block    = be_transform_node(get_nodes_block(node));
3977         ir_node  *pred     = get_Proj_pred(node);
3978         ir_node  *new_pred = be_transform_node(pred);
3979         ir_node  *frame    = get_irg_frame(irg);
3980         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
3981         dbg_info *dbgi     = get_irn_dbg_info(node);
3982         long      pn       = get_Proj_proj(node);
3983         ir_node  *load;
3984         ir_node  *proj;
3985         ia32_attr_t *attr;
3986
3987         load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
3988         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3989         set_ia32_use_frame(load);
3990         set_ia32_op_type(load, ia32_AddrModeS);
3991         set_ia32_ls_mode(load, mode_Iu);
3992         /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3993          * 32 bit from it with this particular load */
3994         attr = get_ia32_attr(load);
3995         attr->data.need_64bit_stackent = 1;
3996
3997         if (pn == pn_ia32_l_FloattoLL_res_high) {
3998                 add_ia32_am_offs_int(load, 4);
3999         } else {
4000                 assert(pn == pn_ia32_l_FloattoLL_res_low);
4001         }
4002
4003         proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4004
4005         return proj;
4006 }
4007
4008 /**
4009  * Transform the Projs of an AddSP.
4010  */
4011 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4012         ir_node  *block    = be_transform_node(get_nodes_block(node));
4013         ir_node  *pred     = get_Proj_pred(node);
4014         ir_node  *new_pred = be_transform_node(pred);
4015         ir_graph *irg      = current_ir_graph;
4016         dbg_info *dbgi     = get_irn_dbg_info(node);
4017         long     proj      = get_Proj_proj(node);
4018
4019         if (proj == pn_be_AddSP_sp) {
4020                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4021                                            pn_ia32_SubSP_stack);
4022                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4023                 return res;
4024         } else if(proj == pn_be_AddSP_res) {
4025                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4026                                    pn_ia32_SubSP_addr);
4027         } else if (proj == pn_be_AddSP_M) {
4028                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4029         }
4030
4031         assert(0);
4032         return new_rd_Unknown(irg, get_irn_mode(node));
4033 }
4034
4035 /**
4036  * Transform the Projs of a SubSP.
4037  */
4038 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4039         ir_node  *block    = be_transform_node(get_nodes_block(node));
4040         ir_node  *pred     = get_Proj_pred(node);
4041         ir_node  *new_pred = be_transform_node(pred);
4042         ir_graph *irg      = current_ir_graph;
4043         dbg_info *dbgi     = get_irn_dbg_info(node);
4044         long     proj      = get_Proj_proj(node);
4045
4046         if (proj == pn_be_SubSP_sp) {
4047                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4048                                            pn_ia32_AddSP_stack);
4049                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4050                 return res;
4051         } else if (proj == pn_be_SubSP_M) {
4052                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4053         }
4054
4055         assert(0);
4056         return new_rd_Unknown(irg, get_irn_mode(node));
4057 }
4058
4059 /**
4060  * Transform and renumber the Projs from a Load.
4061  */
4062 static ir_node *gen_Proj_Load(ir_node *node) {
4063         ir_node  *new_pred;
4064         ir_node  *block    = be_transform_node(get_nodes_block(node));
4065         ir_node  *pred     = get_Proj_pred(node);
4066         ir_graph *irg      = current_ir_graph;
4067         dbg_info *dbgi     = get_irn_dbg_info(node);
4068         long     proj      = get_Proj_proj(node);
4069
4070         /* loads might be part of source address mode matches, so we don't
4071          * transform the ProjMs yet (with the exception of loads whose result is
4072          * not used)
4073          */
4074         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4075                 ir_node *res;
4076
4077                 /* this is needed, because sometimes we have loops that are only
4078                    reachable through the ProjM */
4079                 be_enqueue_preds(node);
4080                 /* do it in 2 steps, to silence firm verifier */
4081                 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4082                 set_Proj_proj(res, pn_ia32_mem);
4083                 return res;
4084         }
4085
4086         /* renumber the proj */
4087         new_pred = be_transform_node(pred);
4088         if (is_ia32_Load(new_pred)) {
4089                 switch (proj) {
4090                 case pn_Load_res:
4091                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4092                 case pn_Load_M:
4093                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4094                 case pn_Load_X_regular:
4095                         return new_rd_Jmp(dbgi, irg, block);
4096                 case pn_Load_X_except:
4097                         /* This Load might raise an exception. Mark it. */
4098                         set_ia32_exc_label(new_pred, 1);
4099                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4100                 default:
4101                         break;
4102                 }
4103         } else if (is_ia32_Conv_I2I(new_pred) ||
4104                    is_ia32_Conv_I2I8Bit(new_pred)) {
4105                 set_irn_mode(new_pred, mode_T);
4106                 if (proj == pn_Load_res) {
4107                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4108                 } else if (proj == pn_Load_M) {
4109                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4110                 }
4111         } else if (is_ia32_xLoad(new_pred)) {
4112                 switch (proj) {
4113                 case pn_Load_res:
4114                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4115                 case pn_Load_M:
4116                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4117                 case pn_Load_X_regular:
4118                         return new_rd_Jmp(dbgi, irg, block);
4119                 case pn_Load_X_except:
4120                         /* This Load might raise an exception. Mark it. */
4121                         set_ia32_exc_label(new_pred, 1);
4122                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4123                 default:
4124                         break;
4125                 }
4126         } else if (is_ia32_vfld(new_pred)) {
4127                 switch (proj) {
4128                 case pn_Load_res:
4129                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4130                 case pn_Load_M:
4131                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4132                 case pn_Load_X_regular:
4133                         return new_rd_Jmp(dbgi, irg, block);
4134                 case pn_Load_X_except:
4135                         /* This Load might raise an exception. Mark it. */
4136                         set_ia32_exc_label(new_pred, 1);
4137                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4138                 default:
4139                         break;
4140                 }
4141         } else {
4142                 /* can happen for ProJMs when source address mode happened for the
4143                    node */
4144
4145                 /* however it should not be the result proj, as that would mean the
4146                    load had multiple users and should not have been used for
4147                    SourceAM */
4148                 if (proj != pn_Load_M) {
4149                         panic("internal error: transformed node not a Load");
4150                 }
4151                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4152         }
4153
4154         assert(0);
4155         return new_rd_Unknown(irg, get_irn_mode(node));
4156 }
4157
4158 /**
4159  * Transform and renumber the Projs from a DivMod like instruction.
4160  */
4161 static ir_node *gen_Proj_DivMod(ir_node *node) {
4162         ir_node  *block    = be_transform_node(get_nodes_block(node));
4163         ir_node  *pred     = get_Proj_pred(node);
4164         ir_node  *new_pred = be_transform_node(pred);
4165         ir_graph *irg      = current_ir_graph;
4166         dbg_info *dbgi     = get_irn_dbg_info(node);
4167         ir_mode  *mode     = get_irn_mode(node);
4168         long     proj      = get_Proj_proj(node);
4169
4170         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4171
4172         switch (get_irn_opcode(pred)) {
4173         case iro_Div:
4174                 switch (proj) {
4175                 case pn_Div_M:
4176                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4177                 case pn_Div_res:
4178                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4179                 case pn_Div_X_regular:
4180                         return new_rd_Jmp(dbgi, irg, block);
4181                 case pn_Div_X_except:
4182                         set_ia32_exc_label(new_pred, 1);
4183                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4184                 default:
4185                         break;
4186                 }
4187                 break;
4188         case iro_Mod:
4189                 switch (proj) {
4190                 case pn_Mod_M:
4191                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4192                 case pn_Mod_res:
4193                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4194                 case pn_Mod_X_except:
4195                         set_ia32_exc_label(new_pred, 1);
4196                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4197                 default:
4198                         break;
4199                 }
4200                 break;
4201         case iro_DivMod:
4202                 switch (proj) {
4203                 case pn_DivMod_M:
4204                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4205                 case pn_DivMod_res_div:
4206                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4207                 case pn_DivMod_res_mod:
4208                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4209                 case pn_DivMod_X_regular:
4210                         return new_rd_Jmp(dbgi, irg, block);
4211                 case pn_DivMod_X_except:
4212                         set_ia32_exc_label(new_pred, 1);
4213                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4214                 default:
4215                         break;
4216                 }
4217                 break;
4218         default:
4219                 break;
4220         }
4221
4222         assert(0);
4223         return new_rd_Unknown(irg, mode);
4224 }
4225
4226 /**
4227  * Transform and renumber the Projs from a CopyB.
4228  */
4229 static ir_node *gen_Proj_CopyB(ir_node *node) {
4230         ir_node  *block    = be_transform_node(get_nodes_block(node));
4231         ir_node  *pred     = get_Proj_pred(node);
4232         ir_node  *new_pred = be_transform_node(pred);
4233         ir_graph *irg      = current_ir_graph;
4234         dbg_info *dbgi     = get_irn_dbg_info(node);
4235         ir_mode  *mode     = get_irn_mode(node);
4236         long     proj      = get_Proj_proj(node);
4237
4238         switch(proj) {
4239         case pn_CopyB_M_regular:
4240                 if (is_ia32_CopyB_i(new_pred)) {
4241                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4242                 } else if (is_ia32_CopyB(new_pred)) {
4243                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4244                 }
4245                 break;
4246         default:
4247                 break;
4248         }
4249
4250         assert(0);
4251         return new_rd_Unknown(irg, mode);
4252 }
4253
4254 /**
4255  * Transform and renumber the Projs from a Quot.
4256  */
4257 static ir_node *gen_Proj_Quot(ir_node *node) {
4258         ir_node  *block    = be_transform_node(get_nodes_block(node));
4259         ir_node  *pred     = get_Proj_pred(node);
4260         ir_node  *new_pred = be_transform_node(pred);
4261         ir_graph *irg      = current_ir_graph;
4262         dbg_info *dbgi     = get_irn_dbg_info(node);
4263         ir_mode  *mode     = get_irn_mode(node);
4264         long     proj      = get_Proj_proj(node);
4265
4266         switch(proj) {
4267         case pn_Quot_M:
4268                 if (is_ia32_xDiv(new_pred)) {
4269                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4270                 } else if (is_ia32_vfdiv(new_pred)) {
4271                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4272                 }
4273                 break;
4274         case pn_Quot_res:
4275                 if (is_ia32_xDiv(new_pred)) {
4276                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4277                 } else if (is_ia32_vfdiv(new_pred)) {
4278                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4279                 }
4280                 break;
4281         case pn_Quot_X_regular:
4282         case pn_Quot_X_except:
4283         default:
4284                 break;
4285         }
4286
4287         assert(0);
4288         return new_rd_Unknown(irg, mode);
4289 }
4290
4291 /**
4292  * Transform the Thread Local Storage Proj.
4293  */
4294 static ir_node *gen_Proj_tls(ir_node *node) {
4295         ir_node  *block = be_transform_node(get_nodes_block(node));
4296         ir_graph *irg   = current_ir_graph;
4297         dbg_info *dbgi  = NULL;
4298         ir_node  *res   = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4299
4300         return res;
4301 }
4302
4303 static ir_node *gen_be_Call(ir_node *node) {
4304         ir_node *res = be_duplicate_node(node);
4305         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4306
4307         return res;
4308 }
4309
4310 static ir_node *gen_be_IncSP(ir_node *node) {
4311         ir_node *res = be_duplicate_node(node);
4312         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4313
4314         return res;
4315 }
4316
4317 /**
4318  * Transform the Projs from a be_Call.
4319  */
4320 static ir_node *gen_Proj_be_Call(ir_node *node) {
4321         ir_node  *block       = be_transform_node(get_nodes_block(node));
4322         ir_node  *call        = get_Proj_pred(node);
4323         ir_node  *new_call    = be_transform_node(call);
4324         ir_graph *irg         = current_ir_graph;
4325         dbg_info *dbgi        = get_irn_dbg_info(node);
4326         ir_type  *method_type = be_Call_get_type(call);
4327         int       n_res       = get_method_n_ress(method_type);
4328         long      proj        = get_Proj_proj(node);
4329         ir_mode  *mode        = get_irn_mode(node);
4330         ir_node  *sse_load;
4331         const arch_register_class_t *cls;
4332
4333         /* The following is kinda tricky: If we're using SSE, then we have to
4334          * move the result value of the call in floating point registers to an
4335          * xmm register, we therefore construct a GetST0 -> xLoad sequence
4336          * after the call, we have to make sure to correctly make the
4337          * MemProj and the result Proj use these 2 nodes
4338          */
4339         if (proj == pn_be_Call_M_regular) {
4340                 // get new node for result, are we doing the sse load/store hack?
4341                 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4342                 ir_node *call_res_new;
4343                 ir_node *call_res_pred = NULL;
4344
4345                 if (call_res != NULL) {
4346                         call_res_new  = be_transform_node(call_res);
4347                         call_res_pred = get_Proj_pred(call_res_new);
4348                 }
4349
4350                 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4351                         return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4352                                            pn_be_Call_M_regular);
4353                 } else {
4354                         assert(is_ia32_xLoad(call_res_pred));
4355                         return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4356                                            pn_ia32_xLoad_M);
4357                 }
4358         }
4359         if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4360                         && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4361                 ir_node *fstp;
4362                 ir_node *frame = get_irg_frame(irg);
4363                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4364                 //ir_node *p;
4365                 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4366                 ir_node *call_res;
4367
4368                 /* in case there is no memory output: create one to serialize the copy
4369                    FPU -> SSE */
4370                 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4371                                        pn_be_Call_M_regular);
4372                 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4373                                        pn_be_Call_first_res);
4374
4375                 /* store st(0) onto stack */
4376                 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4377                                         call_res, mode);
4378                 set_ia32_op_type(fstp, ia32_AddrModeD);
4379                 set_ia32_use_frame(fstp);
4380
4381                 /* load into SSE register */
4382                 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4383                                              mode);
4384                 set_ia32_op_type(sse_load, ia32_AddrModeS);
4385                 set_ia32_use_frame(sse_load);
4386
4387                 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4388                                        pn_ia32_xLoad_res);
4389
4390                 return sse_load;
4391         }
4392
4393         /* transform call modes */
4394         if (mode_is_data(mode)) {
4395                 cls  = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4396                 mode = cls->mode;
4397         }
4398
4399         return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4400 }
4401
4402 /**
4403  * Transform the Projs from a Cmp.
4404  */
4405 static ir_node *gen_Proj_Cmp(ir_node *node)
4406 {
4407         /* this probably means not all mode_b nodes were lowered... */
4408         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4409               node);
4410 }
4411
4412 /**
4413  * Transform the Projs from a Bound.
4414  */
4415 static ir_node *gen_Proj_Bound(ir_node *node)
4416 {
4417         ir_node *new_node, *block;
4418         ir_node *pred = get_Proj_pred(node);
4419
4420         switch (get_Proj_proj(node)) {
4421         case pn_Bound_M:
4422                 return be_transform_node(get_Bound_mem(pred));
4423         case pn_Bound_X_regular:
4424                 new_node = be_transform_node(pred);
4425                 block    = get_nodes_block(new_node);
4426                 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4427         case pn_Bound_X_except:
4428                 new_node = be_transform_node(pred);
4429                 block    = get_nodes_block(new_node);
4430                 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4431         case pn_Bound_res:
4432                 return be_transform_node(get_Bound_index(pred));
4433         default:
4434                 panic("unsupported Proj from Bound");
4435         }
4436 }
4437
4438 static ir_node *gen_Proj_ASM(ir_node *node)
4439 {
4440         ir_node *pred;
4441         ir_node *new_pred;
4442         ir_node *block;
4443
4444         if (get_irn_mode(node) != mode_M)
4445                 return be_duplicate_node(node);
4446
4447         pred     = get_Proj_pred(node);
4448         new_pred = be_transform_node(pred);
4449         block    = get_nodes_block(new_pred);
4450         return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4451                         get_ia32_n_res(new_pred) + 1);
4452 }
4453
4454 /**
4455  * Transform and potentially renumber Proj nodes.
4456  */
4457 static ir_node *gen_Proj(ir_node *node) {
4458         ir_node *pred = get_Proj_pred(node);
4459         long    proj;
4460
4461         switch (get_irn_opcode(pred)) {
4462         case iro_Store:
4463                 proj = get_Proj_proj(node);
4464                 if (proj == pn_Store_M) {
4465                         return be_transform_node(pred);
4466                 } else {
4467                         assert(0);
4468                         return new_r_Bad(current_ir_graph);
4469                 }
4470         case iro_Load:
4471                 return gen_Proj_Load(node);
4472         case iro_ASM:
4473                 return gen_Proj_ASM(node);
4474         case iro_Div:
4475         case iro_Mod:
4476         case iro_DivMod:
4477                 return gen_Proj_DivMod(node);
4478         case iro_CopyB:
4479                 return gen_Proj_CopyB(node);
4480         case iro_Quot:
4481                 return gen_Proj_Quot(node);
4482         case beo_SubSP:
4483                 return gen_Proj_be_SubSP(node);
4484         case beo_AddSP:
4485                 return gen_Proj_be_AddSP(node);
4486         case beo_Call:
4487                 return gen_Proj_be_Call(node);
4488         case iro_Cmp:
4489                 return gen_Proj_Cmp(node);
4490         case iro_Bound:
4491                 return gen_Proj_Bound(node);
4492         case iro_Start:
4493                 proj = get_Proj_proj(node);
4494                 if (proj == pn_Start_X_initial_exec) {
4495                         ir_node *block = get_nodes_block(pred);
4496                         dbg_info *dbgi = get_irn_dbg_info(node);
4497                         ir_node *jump;
4498
4499                         /* we exchange the ProjX with a jump */
4500                         block = be_transform_node(block);
4501                         jump  = new_rd_Jmp(dbgi, current_ir_graph, block);
4502                         return jump;
4503                 }
4504                 if (node == be_get_old_anchor(anchor_tls)) {
4505                         return gen_Proj_tls(node);
4506                 }
4507                 break;
4508
4509         default:
4510                 if (is_ia32_l_FloattoLL(pred)) {
4511                         return gen_Proj_l_FloattoLL(node);
4512 #ifdef FIRM_EXT_GRS
4513                 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4514 #else
4515                 } else {
4516 #endif
4517                         ir_mode *mode = get_irn_mode(node);
4518                         if (ia32_mode_needs_gp_reg(mode)) {
4519                                 ir_node *new_pred = be_transform_node(pred);
4520                                 ir_node *block    = be_transform_node(get_nodes_block(node));
4521                                 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4522                                                                                            mode_Iu, get_Proj_proj(node));
4523 #ifdef DEBUG_libfirm
4524                                 new_proj->node_nr = node->node_nr;
4525 #endif
4526                                 return new_proj;
4527                         }
4528                 }
4529         }
4530         return be_duplicate_node(node);
4531 }
4532
4533 /**
4534  * Enters all transform functions into the generic pointer
4535  */
4536 static void register_transformers(void)
4537 {
4538         ir_op *op_Mulh;
4539
4540         /* first clear the generic function pointer for all ops */
4541         clear_irp_opcodes_generic_func();
4542
4543 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4544 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
4545
4546         GEN(Add);
4547         GEN(Sub);
4548         GEN(Mul);
4549         GEN(And);
4550         GEN(Or);
4551         GEN(Eor);
4552
4553         GEN(Shl);
4554         GEN(Shr);
4555         GEN(Shrs);
4556         GEN(Rotl);
4557
4558         GEN(Quot);
4559
4560         GEN(Div);
4561         GEN(Mod);
4562         GEN(DivMod);
4563
4564         GEN(Minus);
4565         GEN(Conv);
4566         GEN(Abs);
4567         GEN(Not);
4568
4569         GEN(Load);
4570         GEN(Store);
4571         GEN(Cond);
4572
4573         GEN(Cmp);
4574         GEN(ASM);
4575         GEN(CopyB);
4576         GEN(Mux);
4577         GEN(Proj);
4578         GEN(Phi);
4579         GEN(IJmp);
4580         GEN(Bound);
4581
4582         /* transform ops from intrinsic lowering */
4583         GEN(ia32_l_Add);
4584         GEN(ia32_l_Adc);
4585         GEN(ia32_l_Mul);
4586         GEN(ia32_l_IMul);
4587         GEN(ia32_l_ShlDep);
4588         GEN(ia32_l_ShrDep);
4589         GEN(ia32_l_SarDep);
4590         GEN(ia32_l_ShlD);
4591         GEN(ia32_l_ShrD);
4592         GEN(ia32_l_Sub);
4593         GEN(ia32_l_Sbb);
4594         GEN(ia32_l_vfild);
4595         GEN(ia32_l_Load);
4596         GEN(ia32_l_vfist);
4597         GEN(ia32_l_Store);
4598         GEN(ia32_l_LLtoFloat);
4599         GEN(ia32_l_FloattoLL);
4600
4601         GEN(Const);
4602         GEN(SymConst);
4603         GEN(Unknown);
4604
4605         /* we should never see these nodes */
4606         BAD(Raise);
4607         BAD(Sel);
4608         BAD(InstOf);
4609         BAD(Cast);
4610         BAD(Free);
4611         BAD(Tuple);
4612         BAD(Id);
4613         //BAD(Bad);
4614         BAD(Confirm);
4615         BAD(Filter);
4616         BAD(CallBegin);
4617         BAD(EndReg);
4618         BAD(EndExcept);
4619
4620         /* handle generic backend nodes */
4621         GEN(be_FrameAddr);
4622         GEN(be_Call);
4623         GEN(be_IncSP);
4624         GEN(be_Return);
4625         GEN(be_AddSP);
4626         GEN(be_SubSP);
4627         GEN(be_Copy);
4628
4629         op_Mulh = get_op_Mulh();
4630         if (op_Mulh)
4631                 GEN(Mulh);
4632
4633 #undef GEN
4634 #undef BAD
4635 }
4636
4637 /**
4638  * Pre-transform all unknown and noreg nodes.
4639  */
4640 static void ia32_pretransform_node(void *arch_cg) {
4641         ia32_code_gen_t *cg = arch_cg;
4642
4643         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
4644         cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4645         cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4646         cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
4647         cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
4648         cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
4649         get_fpcw();
4650 }
4651
4652 /**
4653  * Walker, checks if all ia32 nodes producing more than one result have
4654  * its Projs, otherwise creates new Projs and keep them using a be_Keep node.
4655  */
4656 static void add_missing_keep_walker(ir_node *node, void *data)
4657 {
4658         int              n_outs, i;
4659         unsigned         found_projs = 0;
4660         const ir_edge_t *edge;
4661         ir_mode         *mode = get_irn_mode(node);
4662         ir_node         *last_keep;
4663         (void) data;
4664         if(mode != mode_T)
4665                 return;
4666         if(!is_ia32_irn(node))
4667                 return;
4668
4669         n_outs = get_ia32_n_res(node);
4670         if(n_outs <= 0)
4671                 return;
4672         if(is_ia32_SwitchJmp(node))
4673                 return;
4674
4675         assert(n_outs < (int) sizeof(unsigned) * 8);
4676         foreach_out_edge(node, edge) {
4677                 ir_node *proj = get_edge_src_irn(edge);
4678                 int      pn   = get_Proj_proj(proj);
4679
4680                 if (get_irn_mode(proj) == mode_M)
4681                         continue;
4682
4683                 assert(pn < n_outs);
4684                 found_projs |= 1 << pn;
4685         }
4686
4687
4688         /* are keeps missing? */
4689         last_keep = NULL;
4690         for(i = 0; i < n_outs; ++i) {
4691                 ir_node                     *block;
4692                 ir_node                     *in[1];
4693                 const arch_register_req_t   *req;
4694                 const arch_register_class_t *cls;
4695
4696                 if(found_projs & (1 << i)) {
4697                         continue;
4698                 }
4699
4700                 req = get_ia32_out_req(node, i);
4701                 cls = req->cls;
4702                 if(cls == NULL) {
4703                         continue;
4704                 }
4705                 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4706                         continue;
4707                 }
4708
4709                 block = get_nodes_block(node);
4710                 in[0] = new_r_Proj(current_ir_graph, block, node,
4711                                    arch_register_class_mode(cls), i);
4712                 if(last_keep != NULL) {
4713                         be_Keep_add_node(last_keep, cls, in[0]);
4714                 } else {
4715                         last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4716                         if(sched_is_scheduled(node)) {
4717                                 sched_add_after(node, last_keep);
4718                         }
4719                 }
4720         }
4721 }
4722
4723 /**
4724  * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4725  * and keeps them.
4726  */
4727 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4728 {
4729         ir_graph *irg = be_get_birg_irg(cg->birg);
4730         irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4731 }
4732
4733 /* do the transformation */
4734 void ia32_transform_graph(ia32_code_gen_t *cg) {
4735         int cse_last;
4736         ir_graph *irg = cg->irg;
4737
4738         register_transformers();
4739         env_cg       = cg;
4740         initial_fpcw = NULL;
4741
4742         BE_TIMER_PUSH(t_heights);
4743         heights      = heights_new(irg);
4744         BE_TIMER_POP(t_heights);
4745         ia32_calculate_non_address_mode_nodes(cg->birg);
4746
4747         /* the transform phase is not safe for CSE (yet) because several nodes get
4748          * attributes set after their creation */
4749         cse_last = get_opt_cse();
4750         set_opt_cse(0);
4751
4752         be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4753
4754         set_opt_cse(cse_last);
4755
4756         ia32_free_non_address_mode_nodes();
4757         heights_free(heights);
4758         heights = NULL;
4759 }
4760
4761 void ia32_init_transform(void)
4762 {
4763         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
4764 }