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