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