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