Remove pointless assert (the node of modes is rather seldom 0 and the pointer has...
[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         /* we prefer the Test instruction where possible except cases where
2727          * we can use SourceAM */
2728         cmp_unsigned = !mode_is_signed(cmp_mode);
2729         if (is_Const_0(right)) {
2730                 if (is_And(left) &&
2731                                 get_irn_n_edges(left) == 1 &&
2732                                 can_fold_test_and(node)) {
2733                         /* Test(and_left, and_right) */
2734                         ir_node *and_left  = get_And_left(left);
2735                         ir_node *and_right = get_And_right(left);
2736                         ir_mode *mode      = get_irn_mode(and_left);
2737
2738                         match_arguments(&am, block, and_left, and_right, NULL,
2739                                         match_commutative |
2740                                         match_am | match_8bit_am | match_16bit_am |
2741                                         match_am_and_immediates | match_immediate |
2742                                         match_8bit | match_16bit);
2743                         if (get_mode_size_bits(mode) == 8) {
2744                                 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2745                                                                 addr->index, addr->mem, am.new_op1,
2746                                                                 am.new_op2, am.ins_permuted,
2747                                                                 cmp_unsigned);
2748                         } else {
2749                                 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2750                                                             addr->index, addr->mem, am.new_op1,
2751                                                             am.new_op2, am.ins_permuted, cmp_unsigned);
2752                         }
2753                 } else {
2754                         match_arguments(&am, block, NULL, left, NULL,
2755                                         match_am | match_8bit_am | match_16bit_am |
2756                                         match_8bit | match_16bit);
2757                         if (am.op_type == ia32_AddrModeS) {
2758                                 /* Cmp(AM, 0) */
2759                                 ir_node *imm_zero = try_create_Immediate(right, 0);
2760                                 if (get_mode_size_bits(cmp_mode) == 8) {
2761                                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2762                                                                        addr->index, addr->mem, am.new_op2,
2763                                                                        imm_zero, am.ins_permuted,
2764                                                                        cmp_unsigned);
2765                                 } else {
2766                                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2767                                                                    addr->index, addr->mem, am.new_op2,
2768                                                                    imm_zero, am.ins_permuted, cmp_unsigned);
2769                                 }
2770                         } else {
2771                                 /* Test(left, left) */
2772                                 if (get_mode_size_bits(cmp_mode) == 8) {
2773                                         new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2774                                                                         addr->index, addr->mem, am.new_op2,
2775                                                                         am.new_op2, am.ins_permuted,
2776                                                                         cmp_unsigned);
2777                                 } else {
2778                                         new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2779                                                                     addr->index, addr->mem, am.new_op2,
2780                                                                     am.new_op2, am.ins_permuted,
2781                                                                     cmp_unsigned);
2782                                 }
2783                         }
2784                 }
2785         } else {
2786                 /* Cmp(left, right) */
2787                 match_arguments(&am, block, left, right, NULL,
2788                                 match_commutative | match_am | match_8bit_am |
2789                                 match_16bit_am | match_am_and_immediates |
2790                                 match_immediate | match_8bit | match_16bit);
2791                 if (get_mode_size_bits(cmp_mode) == 8) {
2792                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2793                                                        addr->index, addr->mem, am.new_op1,
2794                                                        am.new_op2, am.ins_permuted,
2795                                                        cmp_unsigned);
2796                 } else {
2797                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2798                                                    addr->index, addr->mem, am.new_op1,
2799                                                    am.new_op2, am.ins_permuted, cmp_unsigned);
2800                 }
2801         }
2802         set_am_attributes(new_node, &am);
2803         set_ia32_ls_mode(new_node, cmp_mode);
2804
2805         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2806
2807         new_node = fix_mem_proj(new_node, &am);
2808
2809         return new_node;
2810 }
2811
2812 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2813                             pn_Cmp pnc)
2814 {
2815         ir_graph            *irg           = current_ir_graph;
2816         dbg_info            *dbgi          = get_irn_dbg_info(node);
2817         ir_node             *block         = get_nodes_block(node);
2818         ir_node             *new_block     = be_transform_node(block);
2819         ir_node             *val_true      = get_Mux_true(node);
2820         ir_node             *val_false     = get_Mux_false(node);
2821         ir_node             *new_node;
2822         match_flags_t        match_flags;
2823         ia32_address_mode_t  am;
2824         ia32_address_t      *addr;
2825
2826         assert(ia32_cg_config.use_cmov);
2827         assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2828
2829         addr = &am.addr;
2830
2831         match_flags = match_commutative | match_am | match_16bit_am |
2832                       match_mode_neutral;
2833
2834         match_arguments(&am, block, val_false, val_true, flags, match_flags);
2835
2836         new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2837                                     addr->mem, am.new_op1, am.new_op2, new_flags,
2838                                     am.ins_permuted, pnc);
2839         set_am_attributes(new_node, &am);
2840
2841         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2842
2843         new_node = fix_mem_proj(new_node, &am);
2844
2845         return new_node;
2846 }
2847
2848 /**
2849  * Creates a ia32 Setcc instruction.
2850  */
2851 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2852                                  ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2853                                  int ins_permuted)
2854 {
2855         ir_graph *irg   = current_ir_graph;
2856         ir_node  *noreg = ia32_new_NoReg_gp(env_cg);
2857         ir_node  *nomem = new_NoMem();
2858         ir_mode  *mode  = get_irn_mode(orig_node);
2859         ir_node  *new_node;
2860
2861         new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2862         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2863
2864         /* we might need to conv the result up */
2865         if (get_mode_size_bits(mode) > 8) {
2866                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2867                                                     nomem, new_node, mode_Bu);
2868                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2869         }
2870
2871         return new_node;
2872 }
2873
2874 /**
2875  * Create instruction for an unsigned Difference or Zero.
2876  */
2877 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b) {
2878         ir_graph *irg   = current_ir_graph;
2879         ir_mode  *mode  = get_irn_mode(psi);
2880         ir_node  *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2881         dbg_info *dbgi;
2882
2883         new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2884                 match_mode_neutral | match_am | match_immediate | match_two_users);
2885
2886         block = get_nodes_block(new_node);
2887
2888         if (is_Proj(new_node)) {
2889                 sub = get_Proj_pred(new_node);
2890                 assert(is_ia32_Sub(sub));
2891         } else {
2892                 sub = new_node;
2893                 set_irn_mode(sub, mode_T);
2894                 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2895         }
2896         eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2897
2898         dbgi   = get_irn_dbg_info(psi);
2899         noreg  = ia32_new_NoReg_gp(env_cg);
2900         tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
2901         nomem  = new_NoMem();
2902         sbb    = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2903
2904         new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
2905         set_ia32_commutative(new_node);
2906         return new_node;
2907 }
2908
2909 /**
2910  * Transforms a Mux node into CMov.
2911  *
2912  * @return The transformed node.
2913  */
2914 static ir_node *gen_Mux(ir_node *node)
2915 {
2916         dbg_info *dbgi        = get_irn_dbg_info(node);
2917         ir_node  *block       = get_nodes_block(node);
2918         ir_node  *new_block   = be_transform_node(block);
2919         ir_node  *mux_true    = get_Mux_true(node);
2920         ir_node  *mux_false   = get_Mux_false(node);
2921         ir_node  *cond        = get_Mux_sel(node);
2922         ir_mode  *mode        = get_irn_mode(node);
2923         pn_Cmp   pnc;
2924
2925         assert(get_irn_mode(cond) == mode_b);
2926
2927         /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2928         if (mode_is_float(mode)) {
2929                 ir_node  *cmp         = get_Proj_pred(cond);
2930                 ir_node  *cmp_left    = get_Cmp_left(cmp);
2931                 ir_node  *cmp_right   = get_Cmp_right(cmp);
2932                 pn_Cmp   pnc          = get_Proj_proj(cond);
2933
2934                 if (ia32_cg_config.use_sse2) {
2935                         if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2936                                 if (cmp_left == mux_true && cmp_right == mux_false) {
2937                                         /* Mux(a <= b, a, b) => MIN */
2938                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2939                                          match_commutative | match_am | match_two_users);
2940                                 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2941                                         /* Mux(a <= b, b, a) => MAX */
2942                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2943                                          match_commutative | match_am | match_two_users);
2944                                 }
2945                         } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2946                                 if (cmp_left == mux_true && cmp_right == mux_false) {
2947                                         /* Mux(a >= b, a, b) => MAX */
2948                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
2949                                          match_commutative | match_am | match_two_users);
2950                                 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2951                                         /* Mux(a >= b, b, a) => MIN */
2952                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
2953                                          match_commutative | match_am | match_two_users);
2954                                 }
2955                         }
2956                 }
2957                 panic("cannot transform floating point Mux");
2958
2959         } else {
2960                 ir_node *flags;
2961                 ir_node *new_node;
2962
2963                 assert(ia32_mode_needs_gp_reg(mode));
2964
2965                 if (is_Proj(cond)) {
2966                         ir_node *cmp = get_Proj_pred(cond);
2967                         if (is_Cmp(cmp)) {
2968                                 ir_node  *cmp_left    = get_Cmp_left(cmp);
2969                                 ir_node  *cmp_right   = get_Cmp_right(cmp);
2970                                 pn_Cmp   pnc          = get_Proj_proj(cond);
2971
2972                                 /* check for unsigned Doz first */
2973                                 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2974                                         is_Const_0(mux_false) && is_Sub(mux_true) &&
2975                                         get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2976                                         /* Mux(a >=u b, a - b, 0) unsigned Doz */
2977                                         return create_Doz(node, cmp_left, cmp_right);
2978                                 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2979                                         is_Const_0(mux_true) && is_Sub(mux_false) &&
2980                                         get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2981                                         /* Mux(a <=u b, 0, a - b) unsigned Doz */
2982                                         return create_Doz(node, cmp_left, cmp_right);
2983                                 }
2984                         }
2985                 }
2986
2987                 flags = get_flags_node(cond, &pnc);
2988
2989                 if (is_Const(mux_true) && is_Const(mux_false)) {
2990                         /* both are const, good */
2991                         if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2992                                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2993                         } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2994                                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
2995                         } else {
2996                                 /* Not that simple. */
2997                                 goto need_cmov;
2998                         }
2999                 } else {
3000 need_cmov:
3001                         new_node = create_CMov(node, cond, flags, pnc);
3002                 }
3003                 return new_node;
3004         }
3005 }
3006
3007
3008 /**
3009  * Create a conversion from x87 state register to general purpose.
3010  */
3011 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3012         ir_node         *block      = be_transform_node(get_nodes_block(node));
3013         ir_node         *op         = get_Conv_op(node);
3014         ir_node         *new_op     = be_transform_node(op);
3015         ia32_code_gen_t *cg         = env_cg;
3016         ir_graph        *irg        = current_ir_graph;
3017         dbg_info        *dbgi       = get_irn_dbg_info(node);
3018         ir_node         *noreg      = ia32_new_NoReg_gp(cg);
3019         ir_mode         *mode       = get_irn_mode(node);
3020         ir_node         *fist, *load, *mem;
3021
3022         mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3023         set_irn_pinned(fist, op_pin_state_floats);
3024         set_ia32_use_frame(fist);
3025         set_ia32_op_type(fist, ia32_AddrModeD);
3026
3027         assert(get_mode_size_bits(mode) <= 32);
3028         /* exception we can only store signed 32 bit integers, so for unsigned
3029            we store a 64bit (signed) integer and load the lower bits */
3030         if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3031                 set_ia32_ls_mode(fist, mode_Ls);
3032         } else {
3033                 set_ia32_ls_mode(fist, mode_Is);
3034         }
3035         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3036
3037         /* do a Load */
3038         load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3039
3040         set_irn_pinned(load, op_pin_state_floats);
3041         set_ia32_use_frame(load);
3042         set_ia32_op_type(load, ia32_AddrModeS);
3043         set_ia32_ls_mode(load, mode_Is);
3044         if(get_ia32_ls_mode(fist) == mode_Ls) {
3045                 ia32_attr_t *attr = get_ia32_attr(load);
3046                 attr->data.need_64bit_stackent = 1;
3047         } else {
3048                 ia32_attr_t *attr = get_ia32_attr(load);
3049                 attr->data.need_32bit_stackent = 1;
3050         }
3051         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3052
3053         return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3054 }
3055
3056 /**
3057  * Creates a x87 strict Conv by placing a Store and a Load
3058  */
3059 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3060 {
3061         ir_node  *block    = get_nodes_block(node);
3062         ir_graph *irg      = current_ir_graph;
3063         dbg_info *dbgi     = get_irn_dbg_info(node);
3064         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
3065         ir_node  *nomem    = new_NoMem();
3066         ir_node  *frame    = get_irg_frame(irg);
3067         ir_node  *store, *load;
3068         ir_node  *new_node;
3069
3070         store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3071                                  tgt_mode);
3072         set_ia32_use_frame(store);
3073         set_ia32_op_type(store, ia32_AddrModeD);
3074         SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3075
3076         load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3077                                 tgt_mode);
3078         set_ia32_use_frame(load);
3079         set_ia32_op_type(load, ia32_AddrModeS);
3080         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3081
3082         new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3083         return new_node;
3084 }
3085
3086 /**
3087  * Create a conversion from general purpose to x87 register
3088  */
3089 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3090         ir_node  *src_block = get_nodes_block(node);
3091         ir_node  *block     = be_transform_node(src_block);
3092         ir_graph *irg       = current_ir_graph;
3093         dbg_info *dbgi      = get_irn_dbg_info(node);
3094         ir_node  *op        = get_Conv_op(node);
3095         ir_node  *new_op    = NULL;
3096         ir_node  *noreg;
3097         ir_node  *nomem;
3098         ir_mode  *mode;
3099         ir_mode  *store_mode;
3100         ir_node  *fild;
3101         ir_node  *store;
3102         ir_node  *new_node;
3103         int       src_bits;
3104
3105         /* fild can use source AM if the operand is a signed 32bit integer */
3106         if (src_mode == mode_Is) {
3107                 ia32_address_mode_t am;
3108
3109                 match_arguments(&am, src_block, NULL, op, NULL,
3110                                 match_am | match_try_am);
3111                 if (am.op_type == ia32_AddrModeS) {
3112                         ia32_address_t *addr = &am.addr;
3113
3114                         fild     = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3115                                                      addr->index, addr->mem);
3116                         new_node = new_r_Proj(irg, block, fild, mode_vfp,
3117                                               pn_ia32_vfild_res);
3118
3119                         set_am_attributes(fild, &am);
3120                         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3121
3122                         fix_mem_proj(fild, &am);
3123
3124                         return new_node;
3125                 }
3126         }
3127         if(new_op == NULL) {
3128                 new_op = be_transform_node(op);
3129         }
3130
3131         noreg  = ia32_new_NoReg_gp(env_cg);
3132         nomem  = new_NoMem();
3133         mode   = get_irn_mode(op);
3134
3135         /* first convert to 32 bit signed if necessary */
3136         src_bits = get_mode_size_bits(src_mode);
3137         if (src_bits == 8) {
3138                 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3139                                                   new_op, src_mode);
3140                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3141                 mode = mode_Is;
3142         } else if (src_bits < 32) {
3143                 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3144                                               new_op, src_mode);
3145                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3146                 mode = mode_Is;
3147         }
3148
3149         assert(get_mode_size_bits(mode) == 32);
3150
3151         /* do a store */
3152         store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3153                                   new_op);
3154
3155         set_ia32_use_frame(store);
3156         set_ia32_op_type(store, ia32_AddrModeD);
3157         set_ia32_ls_mode(store, mode_Iu);
3158
3159         /* exception for 32bit unsigned, do a 64bit spill+load */
3160         if(!mode_is_signed(mode)) {
3161                 ir_node *in[2];
3162                 /* store a zero */
3163                 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3164
3165                 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3166                                                         get_irg_frame(irg), noreg, nomem,
3167                                                         zero_const);
3168
3169                 set_ia32_use_frame(zero_store);
3170                 set_ia32_op_type(zero_store, ia32_AddrModeD);
3171                 add_ia32_am_offs_int(zero_store, 4);
3172                 set_ia32_ls_mode(zero_store, mode_Iu);
3173
3174                 in[0] = zero_store;
3175                 in[1] = store;
3176
3177                 store      = new_rd_Sync(dbgi, irg, block, 2, in);
3178                 store_mode = mode_Ls;
3179         } else {
3180                 store_mode = mode_Is;
3181         }
3182
3183         /* do a fild */
3184         fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3185
3186         set_ia32_use_frame(fild);
3187         set_ia32_op_type(fild, ia32_AddrModeS);
3188         set_ia32_ls_mode(fild, store_mode);
3189
3190         new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3191
3192         return new_node;
3193 }
3194
3195 /**
3196  * Create a conversion from one integer mode into another one
3197  */
3198 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3199                                 dbg_info *dbgi, ir_node *block, ir_node *op,
3200                                 ir_node *node)
3201 {
3202         ir_graph *irg       = current_ir_graph;
3203         int       src_bits  = get_mode_size_bits(src_mode);
3204         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3205         ir_node  *new_block = be_transform_node(block);
3206         ir_node  *new_node;
3207         ir_mode  *smaller_mode;
3208         int       smaller_bits;
3209         ia32_address_mode_t  am;
3210         ia32_address_t      *addr = &am.addr;
3211
3212         (void) node;
3213         if (src_bits < tgt_bits) {
3214                 smaller_mode = src_mode;
3215                 smaller_bits = src_bits;
3216         } else {
3217                 smaller_mode = tgt_mode;
3218                 smaller_bits = tgt_bits;
3219         }
3220
3221 #ifdef DEBUG_libfirm
3222         if(is_Const(op)) {
3223                 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3224                            op);
3225         }
3226 #endif
3227
3228         match_arguments(&am, block, NULL, op, NULL,
3229                         match_8bit | match_16bit |
3230                         match_am | match_8bit_am | match_16bit_am);
3231         if (smaller_bits == 8) {
3232                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3233                                                     addr->index, addr->mem, am.new_op2,
3234                                                     smaller_mode);
3235         } else {
3236                 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3237                                                 addr->index, addr->mem, am.new_op2,
3238                                                 smaller_mode);
3239         }
3240         set_am_attributes(new_node, &am);
3241         /* match_arguments assume that out-mode = in-mode, this isn't true here
3242          * so fix it */
3243         set_ia32_ls_mode(new_node, smaller_mode);
3244         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3245         new_node = fix_mem_proj(new_node, &am);
3246         return new_node;
3247 }
3248
3249 /**
3250  * Transforms a Conv node.
3251  *
3252  * @return The created ia32 Conv node
3253  */
3254 static ir_node *gen_Conv(ir_node *node) {
3255         ir_node  *block     = get_nodes_block(node);
3256         ir_node  *new_block = be_transform_node(block);
3257         ir_node  *op        = get_Conv_op(node);
3258         ir_node  *new_op    = NULL;
3259         ir_graph *irg       = current_ir_graph;
3260         dbg_info *dbgi      = get_irn_dbg_info(node);
3261         ir_mode  *src_mode  = get_irn_mode(op);
3262         ir_mode  *tgt_mode  = get_irn_mode(node);
3263         int       src_bits  = get_mode_size_bits(src_mode);
3264         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3265         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
3266         ir_node  *nomem     = new_rd_NoMem(irg);
3267         ir_node  *res       = NULL;
3268
3269         if (src_mode == mode_b) {
3270                 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3271                 /* nothing to do, we already model bools as 0/1 ints */
3272                 return be_transform_node(op);
3273         }
3274
3275         if (src_mode == tgt_mode) {
3276                 if (get_Conv_strict(node)) {
3277                         if (ia32_cg_config.use_sse2) {
3278                                 /* when we are in SSE mode, we can kill all strict no-op conversion */
3279                                 return be_transform_node(op);
3280                         }
3281                 } else {
3282                         /* this should be optimized already, but who knows... */
3283                         DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3284                         DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3285                         return be_transform_node(op);
3286                 }
3287         }
3288
3289         if (mode_is_float(src_mode)) {
3290                 new_op = be_transform_node(op);
3291                 /* we convert from float ... */
3292                 if (mode_is_float(tgt_mode)) {
3293                         if(src_mode == mode_E && tgt_mode == mode_D
3294                                         && !get_Conv_strict(node)) {
3295                                 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3296                                 return new_op;
3297                         }
3298
3299                         /* ... to float */
3300                         if (ia32_cg_config.use_sse2) {
3301                                 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3302                                 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3303                                                              nomem, new_op);
3304                                 set_ia32_ls_mode(res, tgt_mode);
3305                         } else {
3306                                 if(get_Conv_strict(node)) {
3307                                         res = gen_x87_strict_conv(tgt_mode, new_op);
3308                                         SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3309                                         return res;
3310                                 }
3311                                 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3312                                 return new_op;
3313                         }
3314                 } else {
3315                         /* ... to int */
3316                         DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3317                         if (ia32_cg_config.use_sse2) {
3318                                 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3319                                                             nomem, new_op);
3320                                 set_ia32_ls_mode(res, src_mode);
3321                         } else {
3322                                 return gen_x87_fp_to_gp(node);
3323                         }
3324                 }
3325         } else {
3326                 /* we convert from int ... */
3327                 if (mode_is_float(tgt_mode)) {
3328                         /* ... to float */
3329                         DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3330                         if (ia32_cg_config.use_sse2) {
3331                                 new_op = be_transform_node(op);
3332                                 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3333                                                             nomem, new_op);
3334                                 set_ia32_ls_mode(res, tgt_mode);
3335                         } else {
3336                                 res = gen_x87_gp_to_fp(node, src_mode);
3337                                 if(get_Conv_strict(node)) {
3338                                         /* The strict-Conv is only necessary, if the int mode has more bits
3339                                          * than the float mantissa */
3340                                         size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3341                                         size_t float_mantissa;
3342                                         /* FIXME There is no way to get the mantissa size of a mode */
3343                                         switch (get_mode_size_bits(tgt_mode)) {
3344                                                 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3345                                                 case 64: float_mantissa = 52 + 1; break;
3346                                                 case 80: float_mantissa = 64 + 1; break;
3347                                                 default: float_mantissa = 0;      break;
3348                                         }
3349                                         if (float_mantissa < int_mantissa) {
3350                                                 res = gen_x87_strict_conv(tgt_mode, res);
3351                                                 SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3352                                         }
3353                                 }
3354                                 return res;
3355                         }
3356                 } else if(tgt_mode == mode_b) {
3357                         /* mode_b lowering already took care that we only have 0/1 values */
3358                         DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3359                             src_mode, tgt_mode));
3360                         return be_transform_node(op);
3361                 } else {
3362                         /* to int */
3363                         if (src_bits == tgt_bits) {
3364                                 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3365                                     src_mode, tgt_mode));
3366                                 return be_transform_node(op);
3367                         }
3368
3369                         res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3370                         return res;
3371                 }
3372         }
3373
3374         return res;
3375 }
3376
3377 static ir_node *create_immediate_or_transform(ir_node *node,
3378                                               char immediate_constraint_type)
3379 {
3380         ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3381         if (new_node == NULL) {
3382                 new_node = be_transform_node(node);
3383         }
3384         return new_node;
3385 }
3386
3387 /**
3388  * Transforms a FrameAddr into an ia32 Add.
3389  */
3390 static ir_node *gen_be_FrameAddr(ir_node *node) {
3391         ir_node  *block  = be_transform_node(get_nodes_block(node));
3392         ir_node  *op     = be_get_FrameAddr_frame(node);
3393         ir_node  *new_op = be_transform_node(op);
3394         ir_graph *irg    = current_ir_graph;
3395         dbg_info *dbgi   = get_irn_dbg_info(node);
3396         ir_node  *noreg  = ia32_new_NoReg_gp(env_cg);
3397         ir_node  *new_node;
3398
3399         new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
3400         set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
3401         set_ia32_use_frame(new_node);
3402
3403         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3404
3405         return new_node;
3406 }
3407
3408 /**
3409  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3410  */
3411 static ir_node *gen_be_Return(ir_node *node) {
3412         ir_graph  *irg     = current_ir_graph;
3413         ir_node   *ret_val = get_irn_n(node, be_pos_Return_val);
3414         ir_node   *ret_mem = get_irn_n(node, be_pos_Return_mem);
3415         ir_entity *ent     = get_irg_entity(irg);
3416         ir_type   *tp      = get_entity_type(ent);
3417         dbg_info  *dbgi;
3418         ir_node   *block;
3419         ir_type   *res_type;
3420         ir_mode   *mode;
3421         ir_node   *frame, *sse_store, *fld, *mproj, *barrier;
3422         ir_node   *new_barrier, *new_ret_val, *new_ret_mem;
3423         ir_node   *noreg;
3424         ir_node   **in;
3425         int       pn_ret_val, pn_ret_mem, arity, i;
3426
3427         assert(ret_val != NULL);
3428         if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3429                 return be_duplicate_node(node);
3430         }
3431
3432         res_type = get_method_res_type(tp, 0);
3433
3434         if (! is_Primitive_type(res_type)) {
3435                 return be_duplicate_node(node);
3436         }
3437
3438         mode = get_type_mode(res_type);
3439         if (! mode_is_float(mode)) {
3440                 return be_duplicate_node(node);
3441         }
3442
3443         assert(get_method_n_ress(tp) == 1);
3444
3445         pn_ret_val = get_Proj_proj(ret_val);
3446         pn_ret_mem = get_Proj_proj(ret_mem);
3447
3448         /* get the Barrier */
3449         barrier = get_Proj_pred(ret_val);
3450
3451         /* get result input of the Barrier */
3452         ret_val     = get_irn_n(barrier, pn_ret_val);
3453         new_ret_val = be_transform_node(ret_val);
3454
3455         /* get memory input of the Barrier */
3456         ret_mem     = get_irn_n(barrier, pn_ret_mem);
3457         new_ret_mem = be_transform_node(ret_mem);
3458
3459         frame = get_irg_frame(irg);
3460
3461         dbgi  = get_irn_dbg_info(barrier);
3462         block = be_transform_node(get_nodes_block(barrier));
3463
3464         noreg = ia32_new_NoReg_gp(env_cg);
3465
3466         /* store xmm0 onto stack */
3467         sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
3468                                              new_ret_mem, new_ret_val);
3469         set_ia32_ls_mode(sse_store, mode);
3470         set_ia32_op_type(sse_store, ia32_AddrModeD);
3471         set_ia32_use_frame(sse_store);
3472
3473         /* load into x87 register */
3474         fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
3475         set_ia32_op_type(fld, ia32_AddrModeS);
3476         set_ia32_use_frame(fld);
3477
3478         mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3479         fld   = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3480
3481         /* create a new barrier */
3482         arity = get_irn_arity(barrier);
3483         in = alloca(arity * sizeof(in[0]));
3484         for (i = 0; i < arity; ++i) {
3485                 ir_node *new_in;
3486
3487                 if (i == pn_ret_val) {
3488                         new_in = fld;
3489                 } else if (i == pn_ret_mem) {
3490                         new_in = mproj;
3491                 } else {
3492                         ir_node *in = get_irn_n(barrier, i);
3493                         new_in = be_transform_node(in);
3494                 }
3495                 in[i] = new_in;
3496         }
3497
3498         new_barrier = new_ir_node(dbgi, irg, block,
3499                                   get_irn_op(barrier), get_irn_mode(barrier),
3500                                   arity, in);
3501         copy_node_attr(barrier, new_barrier);
3502         be_duplicate_deps(barrier, new_barrier);
3503         be_set_transformed_node(barrier, new_barrier);
3504         mark_irn_visited(barrier);
3505
3506         /* transform normally */
3507         return be_duplicate_node(node);
3508 }
3509
3510 /**
3511  * Transform a be_AddSP into an ia32_SubSP.
3512  */
3513 static ir_node *gen_be_AddSP(ir_node *node)
3514 {
3515         ir_node  *sz = get_irn_n(node, be_pos_AddSP_size);
3516         ir_node  *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3517
3518         return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
3519 }
3520
3521 /**
3522  * Transform a be_SubSP into an ia32_AddSP
3523  */
3524 static ir_node *gen_be_SubSP(ir_node *node)
3525 {
3526         ir_node  *sz = get_irn_n(node, be_pos_SubSP_size);
3527         ir_node  *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3528
3529         return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
3530 }
3531
3532 /**
3533  * Change some phi modes
3534  */
3535 static ir_node *gen_Phi(ir_node *node) {
3536         ir_node  *block = be_transform_node(get_nodes_block(node));
3537         ir_graph *irg   = current_ir_graph;
3538         dbg_info *dbgi  = get_irn_dbg_info(node);
3539         ir_mode  *mode  = get_irn_mode(node);
3540         ir_node  *phi;
3541
3542         if(ia32_mode_needs_gp_reg(mode)) {
3543                 /* we shouldn't have any 64bit stuff around anymore */
3544                 assert(get_mode_size_bits(mode) <= 32);
3545                 /* all integer operations are on 32bit registers now */
3546                 mode = mode_Iu;
3547         } else if(mode_is_float(mode)) {
3548                 if (ia32_cg_config.use_sse2) {
3549                         mode = mode_xmm;
3550                 } else {
3551                         mode = mode_vfp;
3552                 }
3553         }
3554
3555         /* phi nodes allow loops, so we use the old arguments for now
3556          * and fix this later */
3557         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3558                           get_irn_in(node) + 1);
3559         copy_node_attr(node, phi);
3560         be_duplicate_deps(node, phi);
3561
3562         be_set_transformed_node(node, phi);
3563         be_enqueue_preds(node);
3564
3565         return phi;
3566 }
3567
3568 /**
3569  * Transform IJmp
3570  */
3571 static ir_node *gen_IJmp(ir_node *node)
3572 {
3573         ir_node  *block     = get_nodes_block(node);
3574         ir_node  *new_block = be_transform_node(block);
3575         dbg_info *dbgi      = get_irn_dbg_info(node);
3576         ir_node  *op        = get_IJmp_target(node);
3577         ir_node  *new_node;
3578         ia32_address_mode_t  am;
3579         ia32_address_t      *addr = &am.addr;
3580
3581         assert(get_irn_mode(op) == mode_P);
3582
3583         match_arguments(&am, block, NULL, op, NULL,
3584                         match_am | match_8bit_am | match_16bit_am |
3585                         match_immediate | match_8bit | match_16bit);
3586
3587         new_node = new_rd_ia32_IJmp(dbgi, current_ir_graph, new_block,
3588                                     addr->base, addr->index, addr->mem,
3589                                     am.new_op2);
3590         set_am_attributes(new_node, &am);
3591         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3592
3593         new_node = fix_mem_proj(new_node, &am);
3594
3595         return new_node;
3596 }
3597
3598 /**
3599  * Transform a Bound node.
3600  */
3601 static ir_node *gen_Bound(ir_node *node)
3602 {
3603         ir_node  *new_node;
3604         ir_node  *lower = get_Bound_lower(node);
3605         dbg_info *dbgi  = get_irn_dbg_info(node);
3606
3607         if (is_Const_0(lower)) {
3608                 /* typical case for Java */
3609                 ir_node  *sub, *res, *flags, *block;
3610                 ir_graph *irg  = current_ir_graph;
3611
3612                 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3613                         new_rd_ia32_Sub, match_mode_neutral     | match_am | match_immediate);
3614
3615                 block = get_nodes_block(res);
3616                 if (! is_Proj(res)) {
3617                         sub = res;
3618                         set_irn_mode(sub, mode_T);
3619                         res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3620                 } else {
3621                         sub = get_Proj_pred(res);
3622                 }
3623                 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3624                 new_node = new_rd_ia32_Jcc(dbgi, irg, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3625                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3626         } else {
3627                 panic("generic Bound not supported in ia32 Backend");
3628         }
3629         return new_node;
3630 }
3631
3632
3633 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3634                                      ir_node *mem);
3635
3636 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
3637                                       ir_node *val, ir_node *mem);
3638
3639 /**
3640  * Transforms a lowered Load into a "real" one.
3641  */
3642 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
3643 {
3644         ir_node  *block   = be_transform_node(get_nodes_block(node));
3645         ir_node  *ptr     = get_irn_n(node, 0);
3646         ir_node  *new_ptr = be_transform_node(ptr);
3647         ir_node  *mem     = get_irn_n(node, 1);
3648         ir_node  *new_mem = be_transform_node(mem);
3649         ir_graph *irg     = current_ir_graph;
3650         dbg_info *dbgi    = get_irn_dbg_info(node);
3651         ir_mode  *mode    = get_ia32_ls_mode(node);
3652         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
3653         ir_node  *new_op;
3654
3655         new_op  = func(dbgi, irg, block, new_ptr, noreg, new_mem);
3656
3657         set_ia32_op_type(new_op, ia32_AddrModeS);
3658         set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
3659         set_ia32_am_scale(new_op, get_ia32_am_scale(node));
3660         set_ia32_am_sc(new_op, get_ia32_am_sc(node));
3661         if (is_ia32_am_sc_sign(node))
3662                 set_ia32_am_sc_sign(new_op);
3663         set_ia32_ls_mode(new_op, mode);
3664         if (is_ia32_use_frame(node)) {
3665                 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3666                 set_ia32_use_frame(new_op);
3667         }
3668
3669         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3670
3671         return new_op;
3672 }
3673
3674 /**
3675  * Transforms a lowered Store into a "real" one.
3676  */
3677 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
3678 {
3679         ir_node  *block   = be_transform_node(get_nodes_block(node));
3680         ir_node  *ptr     = get_irn_n(node, 0);
3681         ir_node  *new_ptr = be_transform_node(ptr);
3682         ir_node  *val     = get_irn_n(node, 1);
3683         ir_node  *new_val = be_transform_node(val);
3684         ir_node  *mem     = get_irn_n(node, 2);
3685         ir_node  *new_mem = be_transform_node(mem);
3686         ir_graph *irg     = current_ir_graph;
3687         dbg_info *dbgi    = get_irn_dbg_info(node);
3688         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
3689         ir_mode  *mode    = get_ia32_ls_mode(node);
3690         ir_node  *new_op;
3691         long     am_offs;
3692
3693         new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
3694
3695         am_offs = get_ia32_am_offs_int(node);
3696         add_ia32_am_offs_int(new_op, am_offs);
3697
3698         set_ia32_op_type(new_op, ia32_AddrModeD);
3699         set_ia32_ls_mode(new_op, mode);
3700         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
3701         set_ia32_use_frame(new_op);
3702
3703         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3704
3705         return new_op;
3706 }
3707
3708 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3709 {
3710         ir_node *left  = get_irn_n(node, n_ia32_l_ShlDep_val);
3711         ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3712
3713         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
3714                                match_immediate | match_mode_neutral);
3715 }
3716
3717 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3718 {
3719         ir_node *left  = get_irn_n(node, n_ia32_l_ShrDep_val);
3720         ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3721         return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
3722                                match_immediate);
3723 }
3724
3725 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3726 {
3727         ir_node *left  = get_irn_n(node, n_ia32_l_SarDep_val);
3728         ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3729         return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
3730                                match_immediate);
3731 }
3732
3733 static ir_node *gen_ia32_l_Add(ir_node *node) {
3734         ir_node *left    = get_irn_n(node, n_ia32_l_Add_left);
3735         ir_node *right   = get_irn_n(node, n_ia32_l_Add_right);
3736         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
3737                         match_commutative | match_am | match_immediate |
3738                         match_mode_neutral);
3739
3740         if(is_Proj(lowered)) {
3741                 lowered = get_Proj_pred(lowered);
3742         } else {
3743                 assert(is_ia32_Add(lowered));
3744                 set_irn_mode(lowered, mode_T);
3745         }
3746
3747         return lowered;
3748 }
3749
3750 static ir_node *gen_ia32_l_Adc(ir_node *node)
3751 {
3752         return gen_binop_flags(node, new_rd_ia32_Adc,
3753                         match_commutative | match_am | match_immediate |
3754                         match_mode_neutral);
3755 }
3756
3757 /**
3758  * Transforms an ia32_l_vfild into a "real" ia32_vfild node
3759  *
3760  * @param node   The node to transform
3761  * @return the created ia32 vfild node
3762  */
3763 static ir_node *gen_ia32_l_vfild(ir_node *node) {
3764         return gen_lowered_Load(node, new_rd_ia32_vfild);
3765 }
3766
3767 /**
3768  * Transforms an ia32_l_Load into a "real" ia32_Load node
3769  *
3770  * @param node   The node to transform
3771  * @return the created ia32 Load node
3772  */
3773 static ir_node *gen_ia32_l_Load(ir_node *node) {
3774         return gen_lowered_Load(node, new_rd_ia32_Load);
3775 }
3776
3777 /**
3778  * Transforms an ia32_l_Store into a "real" ia32_Store node
3779  *
3780  * @param node   The node to transform
3781  * @return the created ia32 Store node
3782  */
3783 static ir_node *gen_ia32_l_Store(ir_node *node) {
3784         return gen_lowered_Store(node, new_rd_ia32_Store);
3785 }
3786
3787 /**
3788  * Transforms a l_vfist into a "real" vfist node.
3789  *
3790  * @param node   The node to transform
3791  * @return the created ia32 vfist node
3792  */
3793 static ir_node *gen_ia32_l_vfist(ir_node *node) {
3794         ir_node  *block      = be_transform_node(get_nodes_block(node));
3795         ir_node  *ptr        = get_irn_n(node, 0);
3796         ir_node  *new_ptr    = be_transform_node(ptr);
3797         ir_node  *val        = get_irn_n(node, 1);
3798         ir_node  *new_val    = be_transform_node(val);
3799         ir_node  *mem        = get_irn_n(node, 2);
3800         ir_node  *new_mem    = be_transform_node(mem);
3801         ir_graph *irg        = current_ir_graph;
3802         dbg_info *dbgi       = get_irn_dbg_info(node);
3803         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
3804         ir_mode  *mode       = get_ia32_ls_mode(node);
3805         ir_node  *memres, *fist;
3806         long     am_offs;
3807
3808         memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
3809         am_offs = get_ia32_am_offs_int(node);
3810         add_ia32_am_offs_int(fist, am_offs);
3811
3812         set_ia32_op_type(fist, ia32_AddrModeD);
3813         set_ia32_ls_mode(fist, mode);
3814         set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
3815         set_ia32_use_frame(fist);
3816
3817         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3818
3819         return memres;
3820 }
3821
3822 /**
3823  * Transforms a l_MulS into a "real" MulS node.
3824  *
3825  * @return the created ia32 Mul node
3826  */
3827 static ir_node *gen_ia32_l_Mul(ir_node *node) {
3828         ir_node *left  = get_binop_left(node);
3829         ir_node *right = get_binop_right(node);
3830
3831         return gen_binop(node, left, right, new_rd_ia32_Mul,
3832                          match_commutative | match_am | match_mode_neutral);
3833 }
3834
3835 /**
3836  * Transforms a l_IMulS into a "real" IMul1OPS node.
3837  *
3838  * @return the created ia32 IMul1OP node
3839  */
3840 static ir_node *gen_ia32_l_IMul(ir_node *node) {
3841         ir_node  *left  = get_binop_left(node);
3842         ir_node  *right = get_binop_right(node);
3843
3844         return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
3845                          match_commutative | match_am | match_mode_neutral);
3846 }
3847
3848 static ir_node *gen_ia32_l_Sub(ir_node *node) {
3849         ir_node *left    = get_irn_n(node, n_ia32_l_Sub_minuend);
3850         ir_node *right   = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3851         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
3852                         match_am | match_immediate | match_mode_neutral);
3853
3854         if(is_Proj(lowered)) {
3855                 lowered = get_Proj_pred(lowered);
3856         } else {
3857                 assert(is_ia32_Sub(lowered));
3858                 set_irn_mode(lowered, mode_T);
3859         }
3860
3861         return lowered;
3862 }
3863
3864 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
3865         return gen_binop_flags(node, new_rd_ia32_Sbb,
3866                         match_am | match_immediate | match_mode_neutral);
3867 }
3868
3869 /**
3870  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3871  * op1 - target to be shifted
3872  * op2 - contains bits to be shifted into target
3873  * op3 - shift count
3874  * Only op3 can be an immediate.
3875  */
3876 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3877                                          ir_node *low, ir_node *count)
3878 {
3879         ir_node  *block     = get_nodes_block(node);
3880         ir_node  *new_block = be_transform_node(block);
3881         ir_graph *irg       = current_ir_graph;
3882         dbg_info *dbgi      = get_irn_dbg_info(node);
3883         ir_node  *new_high  = be_transform_node(high);
3884         ir_node  *new_low   = be_transform_node(low);
3885         ir_node  *new_count;
3886         ir_node  *new_node;
3887
3888         /* the shift amount can be any mode that is bigger than 5 bits, since all
3889          * other bits are ignored anyway */
3890         while (is_Conv(count) && get_irn_n_edges(count) == 1) {
3891                 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3892                 count = get_Conv_op(count);
3893         }
3894         new_count = create_immediate_or_transform(count, 0);
3895
3896         if (is_ia32_l_ShlD(node)) {
3897                 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
3898                                             new_count);
3899         } else {
3900                 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
3901                                             new_count);
3902         }
3903         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3904
3905         return new_node;
3906 }
3907
3908 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3909 {
3910         ir_node *high  = get_irn_n(node, n_ia32_l_ShlD_val_high);
3911         ir_node *low   = get_irn_n(node, n_ia32_l_ShlD_val_low);
3912         ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3913         return gen_lowered_64bit_shifts(node, high, low, count);
3914 }
3915
3916 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3917 {
3918         ir_node *high  = get_irn_n(node, n_ia32_l_ShrD_val_high);
3919         ir_node *low   = get_irn_n(node, n_ia32_l_ShrD_val_low);
3920         ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3921         return gen_lowered_64bit_shifts(node, high, low, count);
3922 }
3923
3924 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
3925         ir_node  *src_block    = get_nodes_block(node);
3926         ir_node  *block        = be_transform_node(src_block);
3927         ir_graph *irg          = current_ir_graph;
3928         dbg_info *dbgi         = get_irn_dbg_info(node);
3929         ir_node  *frame        = get_irg_frame(irg);
3930         ir_node  *noreg        = ia32_new_NoReg_gp(env_cg);
3931         ir_node  *nomem        = new_NoMem();
3932         ir_node  *val_low      = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3933         ir_node  *val_high     = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3934         ir_node  *new_val_low  = be_transform_node(val_low);
3935         ir_node  *new_val_high = be_transform_node(val_high);
3936         ir_node  *in[2];
3937         ir_node  *sync;
3938         ir_node  *fild;
3939         ir_node  *store_low;
3940         ir_node  *store_high;
3941
3942         if(!mode_is_signed(get_irn_mode(val_high))) {
3943                 panic("unsigned long long -> float not supported yet (%+F)", node);
3944         }
3945
3946         /* do a store */
3947         store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3948                                       new_val_low);
3949         store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
3950                                        new_val_high);
3951         SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
3952         SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
3953
3954         set_ia32_use_frame(store_low);
3955         set_ia32_use_frame(store_high);
3956         set_ia32_op_type(store_low, ia32_AddrModeD);
3957         set_ia32_op_type(store_high, ia32_AddrModeD);
3958         set_ia32_ls_mode(store_low, mode_Iu);
3959         set_ia32_ls_mode(store_high, mode_Is);
3960         add_ia32_am_offs_int(store_high, 4);
3961
3962         in[0] = store_low;
3963         in[1] = store_high;
3964         sync  = new_rd_Sync(dbgi, irg, block, 2, in);
3965
3966         /* do a fild */
3967         fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
3968
3969         set_ia32_use_frame(fild);
3970         set_ia32_op_type(fild, ia32_AddrModeS);
3971         set_ia32_ls_mode(fild, mode_Ls);
3972
3973         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3974
3975         return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3976 }
3977
3978 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
3979         ir_node  *src_block  = get_nodes_block(node);
3980         ir_node  *block      = be_transform_node(src_block);
3981         ir_graph *irg        = current_ir_graph;
3982         dbg_info *dbgi       = get_irn_dbg_info(node);
3983         ir_node  *frame      = get_irg_frame(irg);
3984         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
3985         ir_node  *nomem      = new_NoMem();
3986         ir_node  *val        = get_irn_n(node, n_ia32_l_FloattoLL_val);
3987         ir_node  *new_val    = be_transform_node(val);
3988         ir_node  *fist, *mem;
3989
3990         mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3991         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
3992         set_ia32_use_frame(fist);
3993         set_ia32_op_type(fist, ia32_AddrModeD);
3994         set_ia32_ls_mode(fist, mode_Ls);
3995
3996         return mem;
3997 }
3998
3999 /**
4000  * the BAD transformer.
4001  */
4002 static ir_node *bad_transform(ir_node *node) {
4003         panic("No transform function for %+F available.\n", node);
4004         return NULL;
4005 }
4006
4007 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4008         ir_graph *irg      = current_ir_graph;
4009         ir_node  *block    = be_transform_node(get_nodes_block(node));
4010         ir_node  *pred     = get_Proj_pred(node);
4011         ir_node  *new_pred = be_transform_node(pred);
4012         ir_node  *frame    = get_irg_frame(irg);
4013         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
4014         dbg_info *dbgi     = get_irn_dbg_info(node);
4015         long      pn       = get_Proj_proj(node);
4016         ir_node  *load;
4017         ir_node  *proj;
4018         ia32_attr_t *attr;
4019
4020         load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4021         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4022         set_ia32_use_frame(load);
4023         set_ia32_op_type(load, ia32_AddrModeS);
4024         set_ia32_ls_mode(load, mode_Iu);
4025         /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4026          * 32 bit from it with this particular load */
4027         attr = get_ia32_attr(load);
4028         attr->data.need_64bit_stackent = 1;
4029
4030         if (pn == pn_ia32_l_FloattoLL_res_high) {
4031                 add_ia32_am_offs_int(load, 4);
4032         } else {
4033                 assert(pn == pn_ia32_l_FloattoLL_res_low);
4034         }
4035
4036         proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4037
4038         return proj;
4039 }
4040
4041 /**
4042  * Transform the Projs of an AddSP.
4043  */
4044 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4045         ir_node  *block    = be_transform_node(get_nodes_block(node));
4046         ir_node  *pred     = get_Proj_pred(node);
4047         ir_node  *new_pred = be_transform_node(pred);
4048         ir_graph *irg      = current_ir_graph;
4049         dbg_info *dbgi     = get_irn_dbg_info(node);
4050         long     proj      = get_Proj_proj(node);
4051
4052         if (proj == pn_be_AddSP_sp) {
4053                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4054                                            pn_ia32_SubSP_stack);
4055                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4056                 return res;
4057         } else if(proj == pn_be_AddSP_res) {
4058                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4059                                    pn_ia32_SubSP_addr);
4060         } else if (proj == pn_be_AddSP_M) {
4061                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4062         }
4063
4064         assert(0);
4065         return new_rd_Unknown(irg, get_irn_mode(node));
4066 }
4067
4068 /**
4069  * Transform the Projs of a SubSP.
4070  */
4071 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4072         ir_node  *block    = be_transform_node(get_nodes_block(node));
4073         ir_node  *pred     = get_Proj_pred(node);
4074         ir_node  *new_pred = be_transform_node(pred);
4075         ir_graph *irg      = current_ir_graph;
4076         dbg_info *dbgi     = get_irn_dbg_info(node);
4077         long     proj      = get_Proj_proj(node);
4078
4079         if (proj == pn_be_SubSP_sp) {
4080                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4081                                            pn_ia32_AddSP_stack);
4082                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4083                 return res;
4084         } else if (proj == pn_be_SubSP_M) {
4085                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4086         }
4087
4088         assert(0);
4089         return new_rd_Unknown(irg, get_irn_mode(node));
4090 }
4091
4092 /**
4093  * Transform and renumber the Projs from a Load.
4094  */
4095 static ir_node *gen_Proj_Load(ir_node *node) {
4096         ir_node  *new_pred;
4097         ir_node  *block    = be_transform_node(get_nodes_block(node));
4098         ir_node  *pred     = get_Proj_pred(node);
4099         ir_graph *irg      = current_ir_graph;
4100         dbg_info *dbgi     = get_irn_dbg_info(node);
4101         long     proj      = get_Proj_proj(node);
4102
4103         /* loads might be part of source address mode matches, so we don't
4104          * transform the ProjMs yet (with the exception of loads whose result is
4105          * not used)
4106          */
4107         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4108                 ir_node *res;
4109
4110                 /* this is needed, because sometimes we have loops that are only
4111                    reachable through the ProjM */
4112                 be_enqueue_preds(node);
4113                 /* do it in 2 steps, to silence firm verifier */
4114                 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4115                 set_Proj_proj(res, pn_ia32_mem);
4116                 return res;
4117         }
4118
4119         /* renumber the proj */
4120         new_pred = be_transform_node(pred);
4121         if (is_ia32_Load(new_pred)) {
4122                 switch (proj) {
4123                 case pn_Load_res:
4124                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4125                 case pn_Load_M:
4126                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4127                 case pn_Load_X_regular:
4128                         return new_rd_Jmp(dbgi, irg, block);
4129                 case pn_Load_X_except:
4130                         /* This Load might raise an exception. Mark it. */
4131                         set_ia32_exc_label(new_pred, 1);
4132                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4133                 default:
4134                         break;
4135                 }
4136         } else if (is_ia32_Conv_I2I(new_pred) ||
4137                    is_ia32_Conv_I2I8Bit(new_pred)) {
4138                 set_irn_mode(new_pred, mode_T);
4139                 if (proj == pn_Load_res) {
4140                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4141                 } else if (proj == pn_Load_M) {
4142                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4143                 }
4144         } else if (is_ia32_xLoad(new_pred)) {
4145                 switch (proj) {
4146                 case pn_Load_res:
4147                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4148                 case pn_Load_M:
4149                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4150                 case pn_Load_X_regular:
4151                         return new_rd_Jmp(dbgi, irg, block);
4152                 case pn_Load_X_except:
4153                         /* This Load might raise an exception. Mark it. */
4154                         set_ia32_exc_label(new_pred, 1);
4155                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4156                 default:
4157                         break;
4158                 }
4159         } else if (is_ia32_vfld(new_pred)) {
4160                 switch (proj) {
4161                 case pn_Load_res:
4162                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4163                 case pn_Load_M:
4164                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4165                 case pn_Load_X_regular:
4166                         return new_rd_Jmp(dbgi, irg, block);
4167                 case pn_Load_X_except:
4168                         /* This Load might raise an exception. Mark it. */
4169                         set_ia32_exc_label(new_pred, 1);
4170                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4171                 default:
4172                         break;
4173                 }
4174         } else {
4175                 /* can happen for ProJMs when source address mode happened for the
4176                    node */
4177
4178                 /* however it should not be the result proj, as that would mean the
4179                    load had multiple users and should not have been used for
4180                    SourceAM */
4181                 if (proj != pn_Load_M) {
4182                         panic("internal error: transformed node not a Load");
4183                 }
4184                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4185         }
4186
4187         assert(0);
4188         return new_rd_Unknown(irg, get_irn_mode(node));
4189 }
4190
4191 /**
4192  * Transform and renumber the Projs from a DivMod like instruction.
4193  */
4194 static ir_node *gen_Proj_DivMod(ir_node *node) {
4195         ir_node  *block    = be_transform_node(get_nodes_block(node));
4196         ir_node  *pred     = get_Proj_pred(node);
4197         ir_node  *new_pred = be_transform_node(pred);
4198         ir_graph *irg      = current_ir_graph;
4199         dbg_info *dbgi     = get_irn_dbg_info(node);
4200         ir_mode  *mode     = get_irn_mode(node);
4201         long     proj      = get_Proj_proj(node);
4202
4203         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4204
4205         switch (get_irn_opcode(pred)) {
4206         case iro_Div:
4207                 switch (proj) {
4208                 case pn_Div_M:
4209                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4210                 case pn_Div_res:
4211                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4212                 case pn_Div_X_regular:
4213                         return new_rd_Jmp(dbgi, irg, block);
4214                 case pn_Div_X_except:
4215                         set_ia32_exc_label(new_pred, 1);
4216                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4217                 default:
4218                         break;
4219                 }
4220                 break;
4221         case iro_Mod:
4222                 switch (proj) {
4223                 case pn_Mod_M:
4224                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4225                 case pn_Mod_res:
4226                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4227                 case pn_Mod_X_except:
4228                         set_ia32_exc_label(new_pred, 1);
4229                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4230                 default:
4231                         break;
4232                 }
4233                 break;
4234         case iro_DivMod:
4235                 switch (proj) {
4236                 case pn_DivMod_M:
4237                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4238                 case pn_DivMod_res_div:
4239                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4240                 case pn_DivMod_res_mod:
4241                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4242                 case pn_DivMod_X_regular:
4243                         return new_rd_Jmp(dbgi, irg, block);
4244                 case pn_DivMod_X_except:
4245                         set_ia32_exc_label(new_pred, 1);
4246                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4247                 default:
4248                         break;
4249                 }
4250                 break;
4251         default:
4252                 break;
4253         }
4254
4255         assert(0);
4256         return new_rd_Unknown(irg, mode);
4257 }
4258
4259 /**
4260  * Transform and renumber the Projs from a CopyB.
4261  */
4262 static ir_node *gen_Proj_CopyB(ir_node *node) {
4263         ir_node  *block    = be_transform_node(get_nodes_block(node));
4264         ir_node  *pred     = get_Proj_pred(node);
4265         ir_node  *new_pred = be_transform_node(pred);
4266         ir_graph *irg      = current_ir_graph;
4267         dbg_info *dbgi     = get_irn_dbg_info(node);
4268         ir_mode  *mode     = get_irn_mode(node);
4269         long     proj      = get_Proj_proj(node);
4270
4271         switch(proj) {
4272         case pn_CopyB_M_regular:
4273                 if (is_ia32_CopyB_i(new_pred)) {
4274                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4275                 } else if (is_ia32_CopyB(new_pred)) {
4276                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4277                 }
4278                 break;
4279         default:
4280                 break;
4281         }
4282
4283         assert(0);
4284         return new_rd_Unknown(irg, mode);
4285 }
4286
4287 /**
4288  * Transform and renumber the Projs from a Quot.
4289  */
4290 static ir_node *gen_Proj_Quot(ir_node *node) {
4291         ir_node  *block    = be_transform_node(get_nodes_block(node));
4292         ir_node  *pred     = get_Proj_pred(node);
4293         ir_node  *new_pred = be_transform_node(pred);
4294         ir_graph *irg      = current_ir_graph;
4295         dbg_info *dbgi     = get_irn_dbg_info(node);
4296         ir_mode  *mode     = get_irn_mode(node);
4297         long     proj      = get_Proj_proj(node);
4298
4299         switch(proj) {
4300         case pn_Quot_M:
4301                 if (is_ia32_xDiv(new_pred)) {
4302                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4303                 } else if (is_ia32_vfdiv(new_pred)) {
4304                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4305                 }
4306                 break;
4307         case pn_Quot_res:
4308                 if (is_ia32_xDiv(new_pred)) {
4309                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4310                 } else if (is_ia32_vfdiv(new_pred)) {
4311                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4312                 }
4313                 break;
4314         case pn_Quot_X_regular:
4315         case pn_Quot_X_except:
4316         default:
4317                 break;
4318         }
4319
4320         assert(0);
4321         return new_rd_Unknown(irg, mode);
4322 }
4323
4324 /**
4325  * Transform the Thread Local Storage Proj.
4326  */
4327 static ir_node *gen_Proj_tls(ir_node *node) {
4328         ir_node  *block = be_transform_node(get_nodes_block(node));
4329         ir_graph *irg   = current_ir_graph;
4330         dbg_info *dbgi  = NULL;
4331         ir_node  *res   = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
4332
4333         return res;
4334 }
4335
4336 static ir_node *gen_be_Call(ir_node *node) {
4337         ir_node *res = be_duplicate_node(node);
4338         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4339
4340         return res;
4341 }
4342
4343 static ir_node *gen_be_IncSP(ir_node *node) {
4344         ir_node *res = be_duplicate_node(node);
4345         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
4346
4347         return res;
4348 }
4349
4350 /**
4351  * Transform the Projs from a be_Call.
4352  */
4353 static ir_node *gen_Proj_be_Call(ir_node *node) {
4354         ir_node  *block       = be_transform_node(get_nodes_block(node));
4355         ir_node  *call        = get_Proj_pred(node);
4356         ir_node  *new_call    = be_transform_node(call);
4357         ir_graph *irg         = current_ir_graph;
4358         dbg_info *dbgi        = get_irn_dbg_info(node);
4359         ir_type  *method_type = be_Call_get_type(call);
4360         int       n_res       = get_method_n_ress(method_type);
4361         long      proj        = get_Proj_proj(node);
4362         ir_mode  *mode        = get_irn_mode(node);
4363         ir_node  *sse_load;
4364         const arch_register_class_t *cls;
4365
4366         /* The following is kinda tricky: If we're using SSE, then we have to
4367          * move the result value of the call in floating point registers to an
4368          * xmm register, we therefore construct a GetST0 -> xLoad sequence
4369          * after the call, we have to make sure to correctly make the
4370          * MemProj and the result Proj use these 2 nodes
4371          */
4372         if (proj == pn_be_Call_M_regular) {
4373                 // get new node for result, are we doing the sse load/store hack?
4374                 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4375                 ir_node *call_res_new;
4376                 ir_node *call_res_pred = NULL;
4377
4378                 if (call_res != NULL) {
4379                         call_res_new  = be_transform_node(call_res);
4380                         call_res_pred = get_Proj_pred(call_res_new);
4381                 }
4382
4383                 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
4384                         return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4385                                            pn_be_Call_M_regular);
4386                 } else {
4387                         assert(is_ia32_xLoad(call_res_pred));
4388                         return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4389                                            pn_ia32_xLoad_M);
4390                 }
4391         }
4392         if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4393                         && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4394                 ir_node *fstp;
4395                 ir_node *frame = get_irg_frame(irg);
4396                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4397                 //ir_node *p;
4398                 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4399                 ir_node *call_res;
4400
4401                 /* in case there is no memory output: create one to serialize the copy
4402                    FPU -> SSE */
4403                 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4404                                        pn_be_Call_M_regular);
4405                 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4406                                        pn_be_Call_first_res);
4407
4408                 /* store st(0) onto stack */
4409                 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
4410                                         call_res, mode);
4411                 set_ia32_op_type(fstp, ia32_AddrModeD);
4412                 set_ia32_use_frame(fstp);
4413
4414                 /* load into SSE register */
4415                 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
4416                                              mode);
4417                 set_ia32_op_type(sse_load, ia32_AddrModeS);
4418                 set_ia32_use_frame(sse_load);
4419
4420                 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4421                                        pn_ia32_xLoad_res);
4422
4423                 return sse_load;
4424         }
4425
4426         /* transform call modes */
4427         if (mode_is_data(mode)) {
4428                 cls  = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
4429                 mode = cls->mode;
4430         }
4431
4432         return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4433 }
4434
4435 /**
4436  * Transform the Projs from a Cmp.
4437  */
4438 static ir_node *gen_Proj_Cmp(ir_node *node)
4439 {
4440         /* this probably means not all mode_b nodes were lowered... */
4441         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4442               node);
4443 }
4444
4445 /**
4446  * Transform the Projs from a Bound.
4447  */
4448 static ir_node *gen_Proj_Bound(ir_node *node)
4449 {
4450         ir_node *new_node, *block;
4451         ir_node *pred = get_Proj_pred(node);
4452
4453         switch (get_Proj_proj(node)) {
4454         case pn_Bound_M:
4455                 return be_transform_node(get_Bound_mem(pred));
4456         case pn_Bound_X_regular:
4457                 new_node = be_transform_node(pred);
4458                 block    = get_nodes_block(new_node);
4459                 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4460         case pn_Bound_X_except:
4461                 new_node = be_transform_node(pred);
4462                 block    = get_nodes_block(new_node);
4463                 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4464         case pn_Bound_res:
4465                 return be_transform_node(get_Bound_index(pred));
4466         default:
4467                 panic("unsupported Proj from Bound");
4468         }
4469 }
4470
4471 static ir_node *gen_Proj_ASM(ir_node *node)
4472 {
4473         ir_node *pred;
4474         ir_node *new_pred;
4475         ir_node *block;
4476
4477         if (get_irn_mode(node) != mode_M)
4478                 return be_duplicate_node(node);
4479
4480         pred     = get_Proj_pred(node);
4481         new_pred = be_transform_node(pred);
4482         block    = get_nodes_block(new_pred);
4483         return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4484                         get_ia32_n_res(new_pred) + 1);
4485 }
4486
4487 /**
4488  * Transform and potentially renumber Proj nodes.
4489  */
4490 static ir_node *gen_Proj(ir_node *node) {
4491         ir_node *pred = get_Proj_pred(node);
4492         long    proj;
4493
4494         switch (get_irn_opcode(pred)) {
4495         case iro_Store:
4496                 proj = get_Proj_proj(node);
4497                 if (proj == pn_Store_M) {
4498                         return be_transform_node(pred);
4499                 } else {
4500                         assert(0);
4501                         return new_r_Bad(current_ir_graph);
4502                 }
4503         case iro_Load:
4504                 return gen_Proj_Load(node);
4505         case iro_ASM:
4506                 return gen_Proj_ASM(node);
4507         case iro_Div:
4508         case iro_Mod:
4509         case iro_DivMod:
4510                 return gen_Proj_DivMod(node);
4511         case iro_CopyB:
4512                 return gen_Proj_CopyB(node);
4513         case iro_Quot:
4514                 return gen_Proj_Quot(node);
4515         case beo_SubSP:
4516                 return gen_Proj_be_SubSP(node);
4517         case beo_AddSP:
4518                 return gen_Proj_be_AddSP(node);
4519         case beo_Call:
4520                 return gen_Proj_be_Call(node);
4521         case iro_Cmp:
4522                 return gen_Proj_Cmp(node);
4523         case iro_Bound:
4524                 return gen_Proj_Bound(node);
4525         case iro_Start:
4526                 proj = get_Proj_proj(node);
4527                 if (proj == pn_Start_X_initial_exec) {
4528                         ir_node *block = get_nodes_block(pred);
4529                         dbg_info *dbgi = get_irn_dbg_info(node);
4530                         ir_node *jump;
4531
4532                         /* we exchange the ProjX with a jump */
4533                         block = be_transform_node(block);
4534                         jump  = new_rd_Jmp(dbgi, current_ir_graph, block);
4535                         return jump;
4536                 }
4537                 if (node == be_get_old_anchor(anchor_tls)) {
4538                         return gen_Proj_tls(node);
4539                 }
4540                 break;
4541
4542         default:
4543                 if (is_ia32_l_FloattoLL(pred)) {
4544                         return gen_Proj_l_FloattoLL(node);
4545 #ifdef FIRM_EXT_GRS
4546                 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4547 #else
4548                 } else {
4549 #endif
4550                         ir_mode *mode = get_irn_mode(node);
4551                         if (ia32_mode_needs_gp_reg(mode)) {
4552                                 ir_node *new_pred = be_transform_node(pred);
4553                                 ir_node *block    = be_transform_node(get_nodes_block(node));
4554                                 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4555                                                                                            mode_Iu, get_Proj_proj(node));
4556 #ifdef DEBUG_libfirm
4557                                 new_proj->node_nr = node->node_nr;
4558 #endif
4559                                 return new_proj;
4560                         }
4561                 }
4562         }
4563         return be_duplicate_node(node);
4564 }
4565
4566 /**
4567  * Enters all transform functions into the generic pointer
4568  */
4569 static void register_transformers(void)
4570 {
4571         ir_op *op_Mulh;
4572
4573         /* first clear the generic function pointer for all ops */
4574         clear_irp_opcodes_generic_func();
4575
4576 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4577 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
4578
4579         GEN(Add);
4580         GEN(Sub);
4581         GEN(Mul);
4582         GEN(And);
4583         GEN(Or);
4584         GEN(Eor);
4585
4586         GEN(Shl);
4587         GEN(Shr);
4588         GEN(Shrs);
4589         GEN(Rotl);
4590
4591         GEN(Quot);
4592
4593         GEN(Div);
4594         GEN(Mod);
4595         GEN(DivMod);
4596
4597         GEN(Minus);
4598         GEN(Conv);
4599         GEN(Abs);
4600         GEN(Not);
4601
4602         GEN(Load);
4603         GEN(Store);
4604         GEN(Cond);
4605
4606         GEN(Cmp);
4607         GEN(ASM);
4608         GEN(CopyB);
4609         GEN(Mux);
4610         GEN(Proj);
4611         GEN(Phi);
4612         GEN(IJmp);
4613         GEN(Bound);
4614
4615         /* transform ops from intrinsic lowering */
4616         GEN(ia32_l_Add);
4617         GEN(ia32_l_Adc);
4618         GEN(ia32_l_Mul);
4619         GEN(ia32_l_IMul);
4620         GEN(ia32_l_ShlDep);
4621         GEN(ia32_l_ShrDep);
4622         GEN(ia32_l_SarDep);
4623         GEN(ia32_l_ShlD);
4624         GEN(ia32_l_ShrD);
4625         GEN(ia32_l_Sub);
4626         GEN(ia32_l_Sbb);
4627         GEN(ia32_l_vfild);
4628         GEN(ia32_l_Load);
4629         GEN(ia32_l_vfist);
4630         GEN(ia32_l_Store);
4631         GEN(ia32_l_LLtoFloat);
4632         GEN(ia32_l_FloattoLL);
4633
4634         GEN(Const);
4635         GEN(SymConst);
4636         GEN(Unknown);
4637
4638         /* we should never see these nodes */
4639         BAD(Raise);
4640         BAD(Sel);
4641         BAD(InstOf);
4642         BAD(Cast);
4643         BAD(Free);
4644         BAD(Tuple);
4645         BAD(Id);
4646         //BAD(Bad);
4647         BAD(Confirm);
4648         BAD(Filter);
4649         BAD(CallBegin);
4650         BAD(EndReg);
4651         BAD(EndExcept);
4652
4653         /* handle generic backend nodes */
4654         GEN(be_FrameAddr);
4655         GEN(be_Call);
4656         GEN(be_IncSP);
4657         GEN(be_Return);
4658         GEN(be_AddSP);
4659         GEN(be_SubSP);
4660         GEN(be_Copy);
4661
4662         op_Mulh = get_op_Mulh();
4663         if (op_Mulh)
4664                 GEN(Mulh);
4665
4666 #undef GEN
4667 #undef BAD
4668 }
4669
4670 /**
4671  * Pre-transform all unknown and noreg nodes.
4672  */
4673 static void ia32_pretransform_node(void *arch_cg) {
4674         ia32_code_gen_t *cg = arch_cg;
4675
4676         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
4677         cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4678         cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4679         cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
4680         cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
4681         cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
4682         get_fpcw();
4683 }
4684
4685 /**
4686  * Walker, checks if all ia32 nodes producing more than one result have
4687  * its Projs, otherwise creates new Projs and keep them using a be_Keep node.
4688  */
4689 static void add_missing_keep_walker(ir_node *node, void *data)
4690 {
4691         int              n_outs, i;
4692         unsigned         found_projs = 0;
4693         const ir_edge_t *edge;
4694         ir_mode         *mode = get_irn_mode(node);
4695         ir_node         *last_keep;
4696         (void) data;
4697         if(mode != mode_T)
4698                 return;
4699         if(!is_ia32_irn(node))
4700                 return;
4701
4702         n_outs = get_ia32_n_res(node);
4703         if(n_outs <= 0)
4704                 return;
4705         if(is_ia32_SwitchJmp(node))
4706                 return;
4707
4708         assert(n_outs < (int) sizeof(unsigned) * 8);
4709         foreach_out_edge(node, edge) {
4710                 ir_node *proj = get_edge_src_irn(edge);
4711                 int      pn   = get_Proj_proj(proj);
4712
4713                 if (get_irn_mode(proj) == mode_M)
4714                         continue;
4715
4716                 assert(pn < n_outs);
4717                 found_projs |= 1 << pn;
4718         }
4719
4720
4721         /* are keeps missing? */
4722         last_keep = NULL;
4723         for(i = 0; i < n_outs; ++i) {
4724                 ir_node                     *block;
4725                 ir_node                     *in[1];
4726                 const arch_register_req_t   *req;
4727                 const arch_register_class_t *cls;
4728
4729                 if(found_projs & (1 << i)) {
4730                         continue;
4731                 }
4732
4733                 req = get_ia32_out_req(node, i);
4734                 cls = req->cls;
4735                 if(cls == NULL) {
4736                         continue;
4737                 }
4738                 if(cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4739                         continue;
4740                 }
4741
4742                 block = get_nodes_block(node);
4743                 in[0] = new_r_Proj(current_ir_graph, block, node,
4744                                    arch_register_class_mode(cls), i);
4745                 if(last_keep != NULL) {
4746                         be_Keep_add_node(last_keep, cls, in[0]);
4747                 } else {
4748                         last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4749                         if(sched_is_scheduled(node)) {
4750                                 sched_add_after(node, last_keep);
4751                         }
4752                 }
4753         }
4754 }
4755
4756 /**
4757  * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4758  * and keeps them.
4759  */
4760 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4761 {
4762         ir_graph *irg = be_get_birg_irg(cg->birg);
4763         irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4764 }
4765
4766 /* do the transformation */
4767 void ia32_transform_graph(ia32_code_gen_t *cg) {
4768         int cse_last;
4769         ir_graph *irg = cg->irg;
4770
4771         register_transformers();
4772         env_cg       = cg;
4773         initial_fpcw = NULL;
4774
4775         BE_TIMER_PUSH(t_heights);
4776         heights      = heights_new(irg);
4777         BE_TIMER_POP(t_heights);
4778         ia32_calculate_non_address_mode_nodes(cg->birg);
4779
4780         /* the transform phase is not safe for CSE (yet) because several nodes get
4781          * attributes set after their creation */
4782         cse_last = get_opt_cse();
4783         set_opt_cse(0);
4784
4785         be_transform_graph(cg->birg, ia32_pretransform_node, cg);
4786
4787         set_opt_cse(cse_last);
4788
4789         ia32_free_non_address_mode_nodes();
4790         heights_free(heights);
4791         heights = NULL;
4792 }
4793
4794 void ia32_init_transform(void)
4795 {
4796         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
4797 }