no, we cannot skip all convs before vfst (but just float->float convs)
[libfirm] / ir / be / ia32 / ia32_transform.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       This file implements the IR transformation from firm into
23  *              ia32-Firm.
24  * @author      Christian Wuerdig, Matthias Braun
25  * @version     $Id$
26  */
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <limits.h>
32
33 #include "irargs_t.h"
34 #include "irnode_t.h"
35 #include "irgraph_t.h"
36 #include "irmode_t.h"
37 #include "iropt_t.h"
38 #include "irop_t.h"
39 #include "irprog_t.h"
40 #include "iredges_t.h"
41 #include "irgmod.h"
42 #include "irvrfy.h"
43 #include "ircons.h"
44 #include "irgwalk.h"
45 #include "irprintf.h"
46 #include "debug.h"
47 #include "irdom.h"
48 #include "archop.h"
49 #include "error.h"
50 #include "height.h"
51
52 #include "../benode_t.h"
53 #include "../besched.h"
54 #include "../beabi.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
58 #include "../be_t.h"
59
60 #include "bearch_ia32_t.h"
61 #include "ia32_nodes_attr.h"
62 #include "ia32_transform.h"
63 #include "ia32_new_nodes.h"
64 #include "ia32_map_regs.h"
65 #include "ia32_dbg_stat.h"
66 #include "ia32_optimize.h"
67 #include "ia32_util.h"
68 #include "ia32_address_mode.h"
69 #include "ia32_architecture.h"
70
71 #include "gen_ia32_regalloc_if.h"
72
73 #define SFP_SIGN   "0x80000000"
74 #define DFP_SIGN   "0x8000000000000000"
75 #define SFP_ABS    "0x7FFFFFFF"
76 #define DFP_ABS    "0x7FFFFFFFFFFFFFFF"
77 #define DFP_INTMAX "9223372036854775807"
78
79 #define TP_SFP_SIGN "ia32_sfp_sign"
80 #define TP_DFP_SIGN "ia32_dfp_sign"
81 #define TP_SFP_ABS  "ia32_sfp_abs"
82 #define TP_DFP_ABS  "ia32_dfp_abs"
83 #define TP_INT_MAX  "ia32_int_max"
84
85 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
86 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
87 #define ENT_SFP_ABS  "IA32_SFP_ABS"
88 #define ENT_DFP_ABS  "IA32_DFP_ABS"
89 #define ENT_INT_MAX  "IA32_INT_MAX"
90
91 #define mode_vfp        (ia32_reg_classes[CLASS_ia32_vfp].mode)
92 #define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)
93
94 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
95
96 /** hold the current code generator during transformation */
97 static ia32_code_gen_t *env_cg       = NULL;
98 static ir_node         *initial_fpcw = NULL;
99 static heights_t       *heights      = NULL;
100
101 extern ir_op *get_op_Mulh(void);
102
103 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
104         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
105         ir_node *op1, ir_node *op2);
106
107 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
108         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
109         ir_node *op1, ir_node *op2, ir_node *flags);
110
111 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
112         ir_node *block, ir_node *op1, ir_node *op2);
113
114 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
115         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
116         ir_node *op);
117
118 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
119         ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
120
121 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
122         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
123         ir_node *op1, ir_node *op2, ir_node *fpcw);
124
125 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
126         ir_node *block, ir_node *op);
127
128 static ir_node *try_create_Immediate(ir_node *node,
129                                      char immediate_constraint_type);
130
131 static ir_node *create_immediate_or_transform(ir_node *node,
132                                               char immediate_constraint_type);
133
134 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
135                                 dbg_info *dbgi, ir_node *block,
136                                 ir_node *op, ir_node *orig_node);
137
138 /**
139  * Return true if a mode can be stored in the GP register set
140  */
141 static INLINE int mode_needs_gp_reg(ir_mode *mode) {
142         if(mode == mode_fpcw)
143                 return 0;
144         if(get_mode_size_bits(mode) > 32)
145                 return 0;
146         return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b;
147 }
148
149 /**
150  * creates a unique ident by adding a number to a tag
151  *
152  * @param tag   the tag string, must contain a %d if a number
153  *              should be added
154  */
155 static ident *unique_id(const char *tag)
156 {
157         static unsigned id = 0;
158         char str[256];
159
160         snprintf(str, sizeof(str), tag, ++id);
161         return new_id_from_str(str);
162 }
163
164 /**
165  * Get a primitive type for a mode.
166  */
167 static ir_type *get_prim_type(pmap *types, ir_mode *mode)
168 {
169         pmap_entry *e = pmap_find(types, mode);
170         ir_type *res;
171
172         if (! e) {
173                 char buf[64];
174                 snprintf(buf, sizeof(buf), "prim_type_%s", get_mode_name(mode));
175                 res = new_type_primitive(new_id_from_str(buf), mode);
176                 set_type_alignment_bytes(res, 16);
177                 pmap_insert(types, mode, res);
178         }
179         else
180                 res = e->value;
181         return res;
182 }
183
184 /**
185  * Creates an immediate.
186  *
187  * @param symconst       if set, create a SymConst immediate
188  * @param symconst_sign  sign for the symconst
189  * @param val            integer value for the immediate
190  */
191 static ir_node *create_Immediate(ir_entity *symconst, int symconst_sign, long val)
192 {
193         ir_graph *irg         = current_ir_graph;
194         ir_node  *start_block = get_irg_start_block(irg);
195         ir_node  *immediate   = new_rd_ia32_Immediate(NULL, irg, start_block,
196                                                       symconst, symconst_sign, val);
197         arch_set_irn_register(env_cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]);
198
199         return immediate;
200 }
201
202 /**
203  * Get an atomic entity that is initialized with a tarval forming
204  * a given constant.
205  *
206  * @param cnst             the node representing the constant
207  */
208 static ir_entity *create_float_const_entity(ir_node *cnst)
209 {
210         ia32_isa_t *isa = env_cg->isa;
211         tarval *key     = get_Const_tarval(cnst);
212         pmap_entry *e   = pmap_find(isa->tv_ent, key);
213         ir_entity *res;
214         ir_graph *rem;
215
216         if (e == NULL) {
217                 tarval  *tv   = key;
218                 ir_mode *mode = get_tarval_mode(tv);
219                 ir_type *tp;
220
221                 if (! ia32_cg_config.use_sse2) {
222                         /* try to reduce the mode to produce smaller sized entities */
223                         if (mode != mode_F) {
224                                 if (tarval_ieee754_can_conv_lossless(tv, mode_F)) {
225                                         mode = mode_F;
226                                         tv = tarval_convert_to(tv, mode);
227                                 } else if (mode != mode_D) {
228                                         if (tarval_ieee754_can_conv_lossless(tv, mode_D)) {
229                                                 mode = mode_D;
230                                                 tv = tarval_convert_to(tv, mode);
231                                         }
232                                 }
233                         }
234                 }
235
236                 if (mode == get_irn_mode(cnst)) {
237                         /* mode was not changed */
238                         tp = get_Const_type(cnst);
239                         if (tp == firm_unknown_type)
240                                 tp = get_prim_type(isa->types, mode);
241                 } else
242                         tp = get_prim_type(isa->types, mode);
243
244                 res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);
245
246                 set_entity_ld_ident(res, get_entity_ident(res));
247                 set_entity_visibility(res, visibility_local);
248                 set_entity_variability(res, variability_constant);
249                 set_entity_allocation(res, allocation_static);
250
251                  /* we create a new entity here: It's initialization must resist on the
252                     const code irg */
253                 rem = current_ir_graph;
254                 current_ir_graph = get_const_code_irg();
255                 set_atomic_ent_value(res, new_Const_type(tv, tp));
256                 current_ir_graph = rem;
257
258                 pmap_insert(isa->tv_ent, key, res);
259         } else {
260                 res = e->value;
261         }
262
263         return res;
264 }
265
266 static int is_Const_0(ir_node *node) {
267         return is_Const(node) && is_Const_null(node);
268 }
269
270 static int is_Const_1(ir_node *node) {
271         return is_Const(node) && is_Const_one(node);
272 }
273
274 static int is_Const_Minus_1(ir_node *node) {
275         return is_Const(node) && is_Const_all_one(node);
276 }
277
278 /**
279  * returns true if constant can be created with a simple float command
280  */
281 static int is_simple_x87_Const(ir_node *node)
282 {
283         tarval *tv = get_Const_tarval(node);
284         if (tarval_is_null(tv) || tarval_is_one(tv))
285                 return 1;
286
287         /* TODO: match all the other float constants */
288         return 0;
289 }
290
291 /**
292  * returns true if constant can be created with a simple float command
293  */
294 static int is_simple_sse_Const(ir_node *node)
295 {
296         tarval  *tv   = get_Const_tarval(node);
297         ir_mode *mode = get_tarval_mode(tv);
298
299         if (mode == mode_F)
300                 return 1;
301
302         if (tarval_is_null(tv) || tarval_is_one(tv))
303                 return 1;
304
305         if (mode == mode_D) {
306                 unsigned val = get_tarval_sub_bits(tv, 0) |
307                         (get_tarval_sub_bits(tv, 1) << 8) |
308                         (get_tarval_sub_bits(tv, 2) << 16) |
309                         (get_tarval_sub_bits(tv, 3) << 24);
310                 if (val == 0)
311                         /* lower 32bit are zero, really a 32bit constant */
312                         return 1;
313         }
314
315         /* TODO: match all the other float constants */
316         return 0;
317 }
318
319 /**
320  * Transforms a Const.
321  */
322 static ir_node *gen_Const(ir_node *node) {
323         ir_graph        *irg   = current_ir_graph;
324         ir_node         *old_block = get_nodes_block(node);
325         ir_node         *block = be_transform_node(old_block);
326         dbg_info        *dbgi  = get_irn_dbg_info(node);
327         ir_mode         *mode  = get_irn_mode(node);
328
329         assert(is_Const(node));
330
331         if (mode_is_float(mode)) {
332                 ir_node   *res   = NULL;
333                 ir_node   *noreg = ia32_new_NoReg_gp(env_cg);
334                 ir_node   *nomem = new_NoMem();
335                 ir_node   *load;
336                 ir_entity *floatent;
337
338                 if (ia32_cg_config.use_sse2) {
339                         tarval *tv = get_Const_tarval(node);
340                         if (tarval_is_null(tv)) {
341                                 load = new_rd_ia32_xZero(dbgi, irg, block);
342                                 set_ia32_ls_mode(load, mode);
343                                 res  = load;
344                         } else if (tarval_is_one(tv)) {
345                                 int     cnst  = mode == mode_F ? 26 : 55;
346                                 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
347                                 ir_node *imm2 = create_Immediate(NULL, 0, 2);
348                                 ir_node *pslld, *psrld;
349
350                                 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
351                                 set_ia32_ls_mode(load, mode);
352                                 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
353                                 set_ia32_ls_mode(pslld, mode);
354                                 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
355                                 set_ia32_ls_mode(psrld, mode);
356                                 res = psrld;
357                         } else if (mode == mode_F) {
358                                 /* we can place any 32bit constant by using a movd gp, sse */
359                                 unsigned val = get_tarval_sub_bits(tv, 0) |
360                                                (get_tarval_sub_bits(tv, 1) << 8) |
361                                                (get_tarval_sub_bits(tv, 2) << 16) |
362                                                (get_tarval_sub_bits(tv, 3) << 24);
363                                 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
364                                 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
365                                 set_ia32_ls_mode(load, mode);
366                                 res = load;
367                         } else {
368                                 if (mode == mode_D) {
369                                         unsigned val = get_tarval_sub_bits(tv, 0) |
370                                                 (get_tarval_sub_bits(tv, 1) << 8) |
371                                                 (get_tarval_sub_bits(tv, 2) << 16) |
372                                                 (get_tarval_sub_bits(tv, 3) << 24);
373                                         if (val == 0) {
374                                                 ir_node *imm32 = create_Immediate(NULL, 0, 32);
375                                                 ir_node *cnst, *psllq;
376
377                                                 /* fine, lower 32bit are zero, produce 32bit value */
378                                                 val = get_tarval_sub_bits(tv, 4) |
379                                                         (get_tarval_sub_bits(tv, 5) << 8) |
380                                                         (get_tarval_sub_bits(tv, 6) << 16) |
381                                                         (get_tarval_sub_bits(tv, 7) << 24);
382                                                 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
383                                                 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
384                                                 set_ia32_ls_mode(load, mode);
385                                                 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
386                                                 set_ia32_ls_mode(psllq, mode);
387                                                 res = psllq;
388                                                 goto end;
389                                         }
390                                 }
391                                 floatent = create_float_const_entity(node);
392
393                                 load     = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
394                                                              mode);
395                                 set_ia32_op_type(load, ia32_AddrModeS);
396                                 set_ia32_am_sc(load, floatent);
397                                 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
398                                 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
399                         }
400                 } else {
401                         if (is_Const_null(node)) {
402                                 load = new_rd_ia32_vfldz(dbgi, irg, block);
403                                 res  = load;
404                                 set_ia32_ls_mode(load, mode);
405                         } else if (is_Const_one(node)) {
406                                 load = new_rd_ia32_vfld1(dbgi, irg, block);
407                                 res  = load;
408                                 set_ia32_ls_mode(load, mode);
409                         } else {
410                                 floatent = create_float_const_entity(node);
411
412                                 load     = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
413                                 set_ia32_op_type(load, ia32_AddrModeS);
414                                 set_ia32_am_sc(load, floatent);
415                                 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
416                                 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
417                                 /* take the mode from the entity */
418                                 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
419                         }
420                 }
421 end:
422                 /* Const Nodes before the initial IncSP are a bad idea, because
423                  * they could be spilled and we have no SP ready at that point yet.
424                  * So add a dependency to the initial frame pointer calculation to
425                  * avoid that situation.
426                  */
427                 if (get_irg_start_block(irg) == block) {
428                         add_irn_dep(load, get_irg_frame(irg));
429                 }
430
431                 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
432                 return res;
433         } else { /* non-float mode */
434                 ir_node *cnst;
435                 tarval  *tv = get_Const_tarval(node);
436                 long     val;
437
438                 tv = tarval_convert_to(tv, mode_Iu);
439
440                 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
441                     tv == NULL) {
442                         panic("couldn't convert constant tarval (%+F)", node);
443                 }
444                 val = get_tarval_long(tv);
445
446                 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
447                 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
448
449                 /* see above */
450                 if (get_irg_start_block(irg) == block) {
451                         add_irn_dep(cnst, get_irg_frame(irg));
452                 }
453
454                 return cnst;
455         }
456 }
457
458 /**
459  * Transforms a SymConst.
460  */
461 static ir_node *gen_SymConst(ir_node *node) {
462         ir_graph *irg   = current_ir_graph;
463         ir_node  *old_block = get_nodes_block(node);
464         ir_node  *block = be_transform_node(old_block);
465         dbg_info *dbgi  = get_irn_dbg_info(node);
466         ir_mode  *mode  = get_irn_mode(node);
467         ir_node  *cnst;
468
469         if (mode_is_float(mode)) {
470                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
471                 ir_node *nomem = new_NoMem();
472
473                 if (ia32_cg_config.use_sse2)
474                         cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
475                 else
476                         cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
477                 set_ia32_am_sc(cnst, get_SymConst_entity(node));
478                 set_ia32_use_frame(cnst);
479         } else {
480                 ir_entity *entity;
481
482                 if(get_SymConst_kind(node) != symconst_addr_ent) {
483                         panic("backend only support symconst_addr_ent (at %+F)", node);
484                 }
485                 entity = get_SymConst_entity(node);
486                 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
487         }
488
489         /* Const Nodes before the initial IncSP are a bad idea, because
490          * they could be spilled and we have no SP ready at that point yet
491          */
492         if (get_irg_start_block(irg) == block) {
493                 add_irn_dep(cnst, get_irg_frame(irg));
494         }
495
496         SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
497
498         return cnst;
499 }
500
501 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
502 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
503         static const struct {
504                 const char *tp_name;
505                 const char *ent_name;
506                 const char *cnst_str;
507                 char mode;
508                 char align;
509         } names [ia32_known_const_max] = {
510                 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN,   0, 16 },       /* ia32_SSIGN */
511                 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN,   1, 16 },       /* ia32_DSIGN */
512                 { TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS,    0, 16 },       /* ia32_SABS */
513                 { TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS,    1, 16 },       /* ia32_DABS */
514                 { TP_INT_MAX,  ENT_INT_MAX,  DFP_INTMAX, 2, 4 }         /* ia32_INTMAX */
515         };
516         static ir_entity *ent_cache[ia32_known_const_max];
517
518         const char    *tp_name, *ent_name, *cnst_str;
519         ir_type       *tp;
520         ir_node       *cnst;
521         ir_graph      *rem;
522         ir_entity     *ent;
523         tarval        *tv;
524         ir_mode       *mode;
525
526         ent_name = names[kct].ent_name;
527         if (! ent_cache[kct]) {
528                 tp_name  = names[kct].tp_name;
529                 cnst_str = names[kct].cnst_str;
530
531                 switch (names[kct].mode) {
532                 case 0:  mode = mode_Iu; break;
533                 case 1:  mode = mode_Lu; break;
534                 default: mode = mode_F; break;
535                 }
536                 tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
537                 tp  = new_type_primitive(new_id_from_str(tp_name), mode);
538                 /* set the specified alignment */
539                 set_type_alignment_bytes(tp, names[kct].align);
540
541                 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
542
543                 set_entity_ld_ident(ent, get_entity_ident(ent));
544                 set_entity_visibility(ent, visibility_local);
545                 set_entity_variability(ent, variability_constant);
546                 set_entity_allocation(ent, allocation_static);
547
548                 /* we create a new entity here: It's initialization must resist on the
549                     const code irg */
550                 rem = current_ir_graph;
551                 current_ir_graph = get_const_code_irg();
552                 cnst = new_Const(mode, tv);
553                 current_ir_graph = rem;
554
555                 set_atomic_ent_value(ent, cnst);
556
557                 /* cache the entry */
558                 ent_cache[kct] = ent;
559         }
560
561         return ent_cache[kct];
562 }
563
564 #ifndef NDEBUG
565 /**
566  * Prints the old node name on cg obst and returns a pointer to it.
567  */
568 const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
569         ia32_isa_t *isa = (ia32_isa_t*) cg->arch_env;
570
571         lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
572         obstack_1grow(isa->name_obst, 0);
573         return obstack_finish(isa->name_obst);
574 }
575 #endif /* NDEBUG */
576
577 /**
578  * return true if the node is a Proj(Load) and could be used in source address
579  * mode for another node. Will return only true if the @p other node is not
580  * dependent on the memory of the Load (for binary operations use the other
581  * input here, for unary operations use NULL).
582  */
583 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
584                                         ir_node *other, ir_node *other2, match_flags_t flags)
585 {
586         ir_node *load;
587         long     pn;
588
589         /* float constants are always available */
590         if (is_Const(node)) {
591                 ir_mode *mode = get_irn_mode(node);
592                 if (mode_is_float(mode)) {
593                         if (ia32_cg_config.use_sse2) {
594                                 if (is_simple_sse_Const(node))
595                                         return 0;
596                         } else {
597                                 if (is_simple_x87_Const(node))
598                                         return 0;
599                         }
600                         if (get_irn_n_edges(node) > 1)
601                                 return 0;
602                         return 1;
603                 }
604         }
605
606         if (!is_Proj(node))
607                 return 0;
608         load = get_Proj_pred(node);
609         pn   = get_Proj_proj(node);
610         if (!is_Load(load) || pn != pn_Load_res)
611                 return 0;
612         if (get_nodes_block(load) != block)
613                 return 0;
614         /* we only use address mode if we're the only user of the load */
615         if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
616                 return 0;
617         /* in some edge cases with address mode we might reach the load normally
618          * and through some AM sequence, if it is already materialized then we
619          * can't create an AM node from it */
620         if (be_is_transformed(node))
621                 return 0;
622
623         /* don't do AM if other node inputs depend on the load (via mem-proj) */
624         if (other != NULL && get_nodes_block(other) == block &&
625             heights_reachable_in_block(heights, other, load))
626                 return 0;
627         if (other2 != NULL && get_nodes_block(other2) == block &&
628             heights_reachable_in_block(heights, other2, load))
629                 return 0;
630
631         return 1;
632 }
633
634 typedef struct ia32_address_mode_t ia32_address_mode_t;
635 struct ia32_address_mode_t {
636         ia32_address_t  addr;
637         ir_mode        *ls_mode;
638         ir_node        *mem_proj;
639         ia32_op_type_t  op_type;
640         ir_node        *new_op1;
641         ir_node        *new_op2;
642         op_pin_state    pinned;
643         unsigned        commutative  : 1;
644         unsigned        ins_permuted : 1;
645 };
646
647 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
648 {
649         ir_node *noreg_gp;
650
651         /* construct load address */
652         memset(addr, 0, sizeof(addr[0]));
653         ia32_create_address_mode(addr, ptr, /*force=*/0);
654
655         noreg_gp    = ia32_new_NoReg_gp(env_cg);
656         addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_gp;
657         addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
658         addr->mem   = be_transform_node(mem);
659 }
660
661 static void build_address(ia32_address_mode_t *am, ir_node *node)
662 {
663         ir_node        *noreg_gp = ia32_new_NoReg_gp(env_cg);
664         ia32_address_t *addr     = &am->addr;
665         ir_node        *load;
666         ir_node        *ptr;
667         ir_node        *mem;
668         ir_node        *new_mem;
669
670         if (is_Const(node)) {
671                 ir_entity *entity  = create_float_const_entity(node);
672                 addr->base         = noreg_gp;
673                 addr->index        = noreg_gp;
674                 addr->mem          = new_NoMem();
675                 addr->symconst_ent = entity;
676                 addr->use_frame    = 1;
677                 am->ls_mode        = get_type_mode(get_entity_type(entity));
678                 am->pinned         = op_pin_state_floats;
679                 return;
680         }
681
682         load         = get_Proj_pred(node);
683         ptr          = get_Load_ptr(load);
684         mem          = get_Load_mem(load);
685         new_mem      = be_transform_node(mem);
686         am->pinned   = get_irn_pinned(load);
687         am->ls_mode  = get_Load_mode(load);
688         am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
689
690         /* construct load address */
691         ia32_create_address_mode(addr, ptr, /*force=*/0);
692
693         addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_gp;
694         addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
695         addr->mem   = new_mem;
696 }
697
698 static void set_address(ir_node *node, const ia32_address_t *addr)
699 {
700         set_ia32_am_scale(node, addr->scale);
701         set_ia32_am_sc(node, addr->symconst_ent);
702         set_ia32_am_offs_int(node, addr->offset);
703         if(addr->symconst_sign)
704                 set_ia32_am_sc_sign(node);
705         if(addr->use_frame)
706                 set_ia32_use_frame(node);
707         set_ia32_frame_ent(node, addr->frame_entity);
708 }
709
710 /**
711  * Apply attributes of a given address mode to a node.
712  */
713 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
714 {
715         set_address(node, &am->addr);
716
717         set_ia32_op_type(node, am->op_type);
718         set_ia32_ls_mode(node, am->ls_mode);
719         if (am->pinned == op_pin_state_pinned) {
720                 set_irn_pinned(node, am->pinned);
721         }
722         if (am->commutative)
723                 set_ia32_commutative(node);
724 }
725
726 /**
727  * Check, if a given node is a Down-Conv, ie. a integer Conv
728  * from a mode with a mode with more bits to a mode with lesser bits.
729  * Moreover, we return only true if the node has not more than 1 user.
730  *
731  * @param node   the node
732  * @return non-zero if node is a Down-Conv
733  */
734 static int is_downconv(const ir_node *node)
735 {
736         ir_mode *src_mode;
737         ir_mode *dest_mode;
738
739         if(!is_Conv(node))
740                 return 0;
741
742         /* we only want to skip the conv when we're the only user
743          * (not optimal but for now...)
744          */
745         if(get_irn_n_edges(node) > 1)
746                 return 0;
747
748         src_mode  = get_irn_mode(get_Conv_op(node));
749         dest_mode = get_irn_mode(node);
750         return mode_needs_gp_reg(src_mode)
751                 && mode_needs_gp_reg(dest_mode)
752                 && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode);
753 }
754
755 /* Skip all Down-Conv's on a given node and return the resulting node. */
756 ir_node *ia32_skip_downconv(ir_node *node) {
757         while (is_downconv(node))
758                 node = get_Conv_op(node);
759
760         return node;
761 }
762
763 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
764 {
765         ir_mode  *mode = get_irn_mode(node);
766         ir_node  *block;
767         ir_mode  *tgt_mode;
768         dbg_info *dbgi;
769
770         if(mode_is_signed(mode)) {
771                 tgt_mode = mode_Is;
772         } else {
773                 tgt_mode = mode_Iu;
774         }
775         block = get_nodes_block(node);
776         dbgi  = get_irn_dbg_info(node);
777
778         return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
779 }
780
781 /**
782  * matches operands of a node into ia32 addressing/operand modes. This covers
783  * usage of source address mode, immediates, operations with non 32-bit modes,
784  * ...
785  * The resulting data is filled into the @p am struct. block is the block
786  * of the node whose arguments are matched. op1, op2 are the first and second
787  * input that are matched (op1 may be NULL). other_op is another unrelated
788  * input that is not matched! but which is needed sometimes to check if AM
789  * for op1/op2 is legal.
790  * @p flags describes the supported modes of the operation in detail.
791  */
792 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
793                             ir_node *op1, ir_node *op2, ir_node *other_op,
794                             match_flags_t flags)
795 {
796         ia32_address_t *addr      = &am->addr;
797         ir_mode        *mode      = get_irn_mode(op2);
798         int             mode_bits = get_mode_size_bits(mode);
799         ir_node        *noreg_gp, *new_op1, *new_op2;
800         int             use_am;
801         unsigned        commutative;
802         int             use_am_and_immediates;
803         int             use_immediate;
804
805         memset(am, 0, sizeof(am[0]));
806
807         commutative           = (flags & match_commutative) != 0;
808         use_am_and_immediates = (flags & match_am_and_immediates) != 0;
809         use_am                = (flags & match_am) != 0;
810         use_immediate         = (flags & match_immediate) != 0;
811         assert(!use_am_and_immediates || use_immediate);
812
813         assert(op2 != NULL);
814         assert(!commutative || op1 != NULL);
815         assert(use_am || !(flags & match_8bit_am));
816         assert(use_am || !(flags & match_16bit_am));
817
818         if (mode_bits == 8) {
819                 if (!(flags & match_8bit_am))
820                         use_am = 0;
821                 /* we don't automatically add upconvs yet */
822                 assert((flags & match_mode_neutral) || (flags & match_8bit));
823         } else if (mode_bits == 16) {
824                 if (!(flags & match_16bit_am))
825                         use_am = 0;
826                 /* we don't automatically add upconvs yet */
827                 assert((flags & match_mode_neutral) || (flags & match_16bit));
828         }
829
830         /* we can simply skip downconvs for mode neutral nodes: the upper bits
831          * can be random for these operations */
832         if (flags & match_mode_neutral) {
833                 op2 = ia32_skip_downconv(op2);
834                 if (op1 != NULL) {
835                         op1 = ia32_skip_downconv(op1);
836                 }
837         }
838
839         /* match immediates. firm nodes are normalized: constants are always on the
840          * op2 input */
841         new_op2 = NULL;
842         if (!(flags & match_try_am) && use_immediate) {
843                 new_op2 = try_create_Immediate(op2, 0);
844         }
845
846         noreg_gp = ia32_new_NoReg_gp(env_cg);
847         if (new_op2 == NULL &&
848             use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
849                 build_address(am, op2);
850                 new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
851                 if (mode_is_float(mode)) {
852                         new_op2 = ia32_new_NoReg_vfp(env_cg);
853                 } else {
854                         new_op2 = noreg_gp;
855                 }
856                 am->op_type = ia32_AddrModeS;
857         } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
858                        use_am &&
859                        ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
860                 ir_node *noreg;
861                 build_address(am, op1);
862
863                 if (mode_is_float(mode)) {
864                         noreg = ia32_new_NoReg_vfp(env_cg);
865                 } else {
866                         noreg = noreg_gp;
867                 }
868
869                 if (new_op2 != NULL) {
870                         new_op1 = noreg;
871                 } else {
872                         new_op1 = be_transform_node(op2);
873                         new_op2 = noreg;
874                         am->ins_permuted = 1;
875                 }
876                 am->op_type = ia32_AddrModeS;
877         } else {
878                 if (flags & match_try_am) {
879                         am->new_op1 = NULL;
880                         am->new_op2 = NULL;
881                         am->op_type = ia32_Normal;
882                         return;
883                 }
884
885                 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
886                 if (new_op2 == NULL)
887                         new_op2 = be_transform_node(op2);
888                 am->op_type = ia32_Normal;
889                 am->ls_mode = get_irn_mode(op2);
890                 if (flags & match_mode_neutral)
891                         am->ls_mode = mode_Iu;
892         }
893         if (addr->base == NULL)
894                 addr->base = noreg_gp;
895         if (addr->index == NULL)
896                 addr->index = noreg_gp;
897         if (addr->mem == NULL)
898                 addr->mem = new_NoMem();
899
900         am->new_op1     = new_op1;
901         am->new_op2     = new_op2;
902         am->commutative = commutative;
903 }
904
905 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
906 {
907         ir_mode  *mode;
908         ir_node  *load;
909
910         if (am->mem_proj == NULL)
911                 return node;
912
913         /* we have to create a mode_T so the old MemProj can attach to us */
914         mode = get_irn_mode(node);
915         load = get_Proj_pred(am->mem_proj);
916
917         mark_irn_visited(load);
918         be_set_transformed_node(load, node);
919
920         if (mode != mode_T) {
921                 set_irn_mode(node, mode_T);
922                 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
923         } else {
924                 return node;
925         }
926 }
927
928 /**
929  * Construct a standard binary operation, set AM and immediate if required.
930  *
931  * @param node  The original node for which the binop is created
932  * @param op1   The first operand
933  * @param op2   The second operand
934  * @param func  The node constructor function
935  * @return The constructed ia32 node.
936  */
937 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
938                           construct_binop_func *func, match_flags_t flags)
939 {
940         dbg_info            *dbgi;
941         ir_node             *block, *new_block, *new_node;
942         ia32_address_mode_t  am;
943         ia32_address_t      *addr = &am.addr;
944
945         block = get_nodes_block(node);
946         match_arguments(&am, block, op1, op2, NULL, flags);
947
948         dbgi      = get_irn_dbg_info(node);
949         new_block = be_transform_node(block);
950         new_node  = func(dbgi, current_ir_graph, new_block,
951                          addr->base, addr->index, addr->mem,
952                          am.new_op1, am.new_op2);
953         set_am_attributes(new_node, &am);
954         /* we can't use source address mode anymore when using immediates */
955         if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
956                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
957         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
958
959         new_node = fix_mem_proj(new_node, &am);
960
961         return new_node;
962 }
963
964 enum {
965         n_ia32_l_binop_left,
966         n_ia32_l_binop_right,
967         n_ia32_l_binop_eflags
968 };
969 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Adc_left,       n_Adc_left)
970 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Adc_right,      n_Adc_right)
971 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags,     n_Adc_eflags)
972 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Sbb_minuend,    n_Sbb_minuend)
973 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
974 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags,     n_Sbb_eflags)
975
976 /**
977  * Construct a binary operation which also consumes the eflags.
978  *
979  * @param node  The node to transform
980  * @param func  The node constructor function
981  * @param flags The match flags
982  * @return      The constructor ia32 node
983  */
984 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
985                                 match_flags_t flags)
986 {
987         ir_node             *src_block  = get_nodes_block(node);
988         ir_node             *op1        = get_irn_n(node, n_ia32_l_binop_left);
989         ir_node             *op2        = get_irn_n(node, n_ia32_l_binop_right);
990         dbg_info            *dbgi;
991         ir_node             *block, *new_node, *eflags, *new_eflags;
992         ia32_address_mode_t  am;
993         ia32_address_t      *addr       = &am.addr;
994
995         match_arguments(&am, src_block, op1, op2, NULL, flags);
996
997         dbgi       = get_irn_dbg_info(node);
998         block      = be_transform_node(src_block);
999         eflags     = get_irn_n(node, n_ia32_l_binop_eflags);
1000         new_eflags = be_transform_node(eflags);
1001         new_node   = func(dbgi, current_ir_graph, block, addr->base, addr->index,
1002                         addr->mem, am.new_op1, am.new_op2, new_eflags);
1003         set_am_attributes(new_node, &am);
1004         /* we can't use source address mode anymore when using immediates */
1005         if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1006                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1007         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1008
1009         new_node = fix_mem_proj(new_node, &am);
1010
1011         return new_node;
1012 }
1013
1014 static ir_node *get_fpcw(void)
1015 {
1016         ir_node *fpcw;
1017         if (initial_fpcw != NULL)
1018                 return initial_fpcw;
1019
1020         fpcw         = be_abi_get_ignore_irn(env_cg->birg->abi,
1021                                              &ia32_fp_cw_regs[REG_FPCW]);
1022         initial_fpcw = be_transform_node(fpcw);
1023
1024         return initial_fpcw;
1025 }
1026
1027 /**
1028  * Construct a standard binary operation, set AM and immediate if required.
1029  *
1030  * @param op1   The first operand
1031  * @param op2   The second operand
1032  * @param func  The node constructor function
1033  * @return The constructed ia32 node.
1034  */
1035 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1036                                     construct_binop_float_func *func,
1037                                     match_flags_t flags)
1038 {
1039         ir_mode             *mode  = get_irn_mode(node);
1040         dbg_info            *dbgi;
1041         ir_node             *block, *new_block, *new_node;
1042         ia32_address_mode_t  am;
1043         ia32_address_t      *addr = &am.addr;
1044
1045         /* cannot use address mode with long double on x87 */
1046         if (get_mode_size_bits(mode) > 64)
1047                 flags &= ~match_am;
1048
1049         block = get_nodes_block(node);
1050         match_arguments(&am, block, op1, op2, NULL, flags);
1051
1052         dbgi      = get_irn_dbg_info(node);
1053         new_block = be_transform_node(block);
1054         new_node  = func(dbgi, current_ir_graph, new_block,
1055                          addr->base, addr->index, addr->mem,
1056                          am.new_op1, am.new_op2, get_fpcw());
1057         set_am_attributes(new_node, &am);
1058
1059         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1060
1061         new_node = fix_mem_proj(new_node, &am);
1062
1063         return new_node;
1064 }
1065
1066 /**
1067  * Construct a shift/rotate binary operation, sets AM and immediate if required.
1068  *
1069  * @param op1   The first operand
1070  * @param op2   The second operand
1071  * @param func  The node constructor function
1072  * @return The constructed ia32 node.
1073  */
1074 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1075                                 construct_shift_func *func,
1076                                 match_flags_t flags)
1077 {
1078         dbg_info *dbgi;
1079         ir_node  *block, *new_block, *new_op1, *new_op2, *new_node;
1080
1081         assert(! mode_is_float(get_irn_mode(node)));
1082         assert(flags & match_immediate);
1083         assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1084
1085         if (flags & match_mode_neutral) {
1086                 op1     = ia32_skip_downconv(op1);
1087                 new_op1 = be_transform_node(op1);
1088         } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1089                 new_op1 = create_upconv(op1, node);
1090         } else {
1091                 new_op1 = be_transform_node(op1);
1092         }
1093
1094         /* the shift amount can be any mode that is bigger than 5 bits, since all
1095          * other bits are ignored anyway */
1096         while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
1097                 op2 = get_Conv_op(op2);
1098                 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
1099         }
1100         new_op2 = create_immediate_or_transform(op2, 0);
1101
1102         dbgi      = get_irn_dbg_info(node);
1103         block     = get_nodes_block(node);
1104         new_block = be_transform_node(block);
1105         new_node  = func(dbgi, current_ir_graph, new_block, new_op1, new_op2);
1106         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1107
1108         /* lowered shift instruction may have a dependency operand, handle it here */
1109         if (get_irn_arity(node) == 3) {
1110                 /* we have a dependency */
1111                 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
1112                 add_irn_dep(new_node, new_dep);
1113         }
1114
1115         return new_node;
1116 }
1117
1118
1119 /**
1120  * Construct a standard unary operation, set AM and immediate if required.
1121  *
1122  * @param op    The operand
1123  * @param func  The node constructor function
1124  * @return The constructed ia32 node.
1125  */
1126 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
1127                          match_flags_t flags)
1128 {
1129         dbg_info *dbgi;
1130         ir_node  *block, *new_block, *new_op, *new_node;
1131
1132         assert(flags == 0 || flags == match_mode_neutral);
1133         if (flags & match_mode_neutral) {
1134                 op = ia32_skip_downconv(op);
1135         }
1136
1137         new_op    = be_transform_node(op);
1138         dbgi      = get_irn_dbg_info(node);
1139         block     = get_nodes_block(node);
1140         new_block = be_transform_node(block);
1141         new_node  = func(dbgi, current_ir_graph, new_block, new_op);
1142
1143         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1144
1145         return new_node;
1146 }
1147
1148 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1149                                         ia32_address_t *addr)
1150 {
1151         ir_node *base, *index, *res;
1152
1153         base = addr->base;
1154         if (base == NULL) {
1155                 base = ia32_new_NoReg_gp(env_cg);
1156         } else {
1157                 base = be_transform_node(base);
1158         }
1159
1160         index = addr->index;
1161         if (index == NULL) {
1162                 index = ia32_new_NoReg_gp(env_cg);
1163         } else {
1164                 index = be_transform_node(index);
1165         }
1166
1167         res = new_rd_ia32_Lea(dbgi, current_ir_graph, block, base, index);
1168         set_address(res, addr);
1169
1170         return res;
1171 }
1172
1173 /**
1174  * Returns non-zero if a given address mode has a symbolic or
1175  * numerical offset != 0.
1176  */
1177 static int am_has_immediates(const ia32_address_t *addr)
1178 {
1179         return addr->offset != 0 || addr->symconst_ent != NULL
1180                 || addr->frame_entity || addr->use_frame;
1181 }
1182
1183 /**
1184  * Creates an ia32 Add.
1185  *
1186  * @return the created ia32 Add node
1187  */
1188 static ir_node *gen_Add(ir_node *node) {
1189         ir_mode  *mode = get_irn_mode(node);
1190         ir_node  *op1  = get_Add_left(node);
1191         ir_node  *op2  = get_Add_right(node);
1192         dbg_info *dbgi;
1193         ir_node  *block, *new_block, *new_node, *add_immediate_op;
1194         ia32_address_t       addr;
1195         ia32_address_mode_t  am;
1196
1197         if (mode_is_float(mode)) {
1198                 if (ia32_cg_config.use_sse2)
1199                         return gen_binop(node, op1, op2, new_rd_ia32_xAdd,
1200                                          match_commutative | match_am);
1201                 else
1202                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd,
1203                                                    match_commutative | match_am);
1204         }
1205
1206         ia32_mark_non_am(node);
1207
1208         op2 = ia32_skip_downconv(op2);
1209         op1 = ia32_skip_downconv(op1);
1210
1211         /**
1212          * Rules for an Add:
1213          *   0. Immediate Trees (example Add(Symconst, Const) -> Const)
1214          *   1. Add with immediate -> Lea
1215          *   2. Add with possible source address mode -> Add
1216          *   3. Otherwise -> Lea
1217          */
1218         memset(&addr, 0, sizeof(addr));
1219         ia32_create_address_mode(&addr, node, /*force=*/1);
1220         add_immediate_op = NULL;
1221
1222         dbgi      = get_irn_dbg_info(node);
1223         block     = get_nodes_block(node);
1224         new_block = be_transform_node(block);
1225
1226         /* a constant? */
1227         if(addr.base == NULL && addr.index == NULL) {
1228                 ir_graph *irg = current_ir_graph;
1229                 new_node = new_rd_ia32_Const(dbgi, irg, new_block, addr.symconst_ent,
1230                                              addr.symconst_sign, addr.offset);
1231                 add_irn_dep(new_node, get_irg_frame(irg));
1232                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1233                 return new_node;
1234         }
1235         /* add with immediate? */
1236         if(addr.index == NULL) {
1237                 add_immediate_op = addr.base;
1238         } else if(addr.base == NULL && addr.scale == 0) {
1239                 add_immediate_op = addr.index;
1240         }
1241
1242         if(add_immediate_op != NULL) {
1243                 if(!am_has_immediates(&addr)) {
1244 #ifdef DEBUG_libfirm
1245                         ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1246                                            node);
1247 #endif
1248                         return be_transform_node(add_immediate_op);
1249                 }
1250
1251                 new_node = create_lea_from_address(dbgi, new_block, &addr);
1252                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1253                 return new_node;
1254         }
1255
1256         /* test if we can use source address mode */
1257         match_arguments(&am, block, op1, op2, NULL, match_commutative
1258                         | match_mode_neutral | match_am | match_immediate | match_try_am);
1259
1260         /* construct an Add with source address mode */
1261         if (am.op_type == ia32_AddrModeS) {
1262                 ir_graph *irg = current_ir_graph;
1263                 ia32_address_t *am_addr = &am.addr;
1264                 new_node = new_rd_ia32_Add(dbgi, irg, new_block, am_addr->base,
1265                                          am_addr->index, am_addr->mem, am.new_op1,
1266                                          am.new_op2);
1267                 set_am_attributes(new_node, &am);
1268                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1269
1270                 new_node = fix_mem_proj(new_node, &am);
1271
1272                 return new_node;
1273         }
1274
1275         /* otherwise construct a lea */
1276         new_node = create_lea_from_address(dbgi, new_block, &addr);
1277         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1278         return new_node;
1279 }
1280
1281 /**
1282  * Creates an ia32 Mul.
1283  *
1284  * @return the created ia32 Mul node
1285  */
1286 static ir_node *gen_Mul(ir_node *node) {
1287         ir_node *op1  = get_Mul_left(node);
1288         ir_node *op2  = get_Mul_right(node);
1289         ir_mode *mode = get_irn_mode(node);
1290
1291         if (mode_is_float(mode)) {
1292                 if (ia32_cg_config.use_sse2)
1293                         return gen_binop(node, op1, op2, new_rd_ia32_xMul,
1294                                          match_commutative | match_am);
1295                 else
1296                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul,
1297                                                    match_commutative | match_am);
1298         }
1299         return gen_binop(node, op1, op2, new_rd_ia32_IMul,
1300                          match_commutative | match_am | match_mode_neutral |
1301                          match_immediate | match_am_and_immediates);
1302 }
1303
1304 /**
1305  * Creates an ia32 Mulh.
1306  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1307  * this result while Mul returns the lower 32 bit.
1308  *
1309  * @return the created ia32 Mulh node
1310  */
1311 static ir_node *gen_Mulh(ir_node *node)
1312 {
1313         ir_node  *block     = get_nodes_block(node);
1314         ir_node  *new_block = be_transform_node(block);
1315         ir_graph *irg       = current_ir_graph;
1316         dbg_info *dbgi      = get_irn_dbg_info(node);
1317         ir_mode  *mode      = get_irn_mode(node);
1318         ir_node  *op1       = get_Mulh_left(node);
1319         ir_node  *op2       = get_Mulh_right(node);
1320         ir_node  *proj_res_high;
1321         ir_node  *new_node;
1322         ia32_address_mode_t  am;
1323         ia32_address_t      *addr = &am.addr;
1324
1325         assert(!mode_is_float(mode) && "Mulh with float not supported");
1326         assert(get_mode_size_bits(mode) == 32);
1327
1328         match_arguments(&am, block, op1, op2, NULL, match_commutative | match_am);
1329
1330         if (mode_is_signed(mode)) {
1331                 new_node = new_rd_ia32_IMul1OP(dbgi, irg, new_block, addr->base,
1332                                                addr->index, addr->mem, am.new_op1,
1333                                                am.new_op2);
1334         } else {
1335                 new_node = new_rd_ia32_Mul(dbgi, irg, new_block, addr->base,
1336                                            addr->index, addr->mem, am.new_op1,
1337                                            am.new_op2);
1338         }
1339
1340         set_am_attributes(new_node, &am);
1341         /* we can't use source address mode anymore when using immediates */
1342         if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1343                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1344         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1345
1346         assert(get_irn_mode(new_node) == mode_T);
1347
1348         fix_mem_proj(new_node, &am);
1349
1350         assert(pn_ia32_IMul1OP_res_high == pn_ia32_Mul_res_high);
1351         proj_res_high = new_rd_Proj(dbgi, irg, block, new_node,
1352                                mode_Iu, pn_ia32_IMul1OP_res_high);
1353
1354         return proj_res_high;
1355 }
1356
1357
1358
1359 /**
1360  * Creates an ia32 And.
1361  *
1362  * @return The created ia32 And node
1363  */
1364 static ir_node *gen_And(ir_node *node) {
1365         ir_node *op1 = get_And_left(node);
1366         ir_node *op2 = get_And_right(node);
1367         assert(! mode_is_float(get_irn_mode(node)));
1368
1369         /* is it a zero extension? */
1370         if (is_Const(op2)) {
1371                 tarval   *tv    = get_Const_tarval(op2);
1372                 long      v     = get_tarval_long(tv);
1373
1374                 if (v == 0xFF || v == 0xFFFF) {
1375                         dbg_info *dbgi   = get_irn_dbg_info(node);
1376                         ir_node  *block  = get_nodes_block(node);
1377                         ir_mode  *src_mode;
1378                         ir_node  *res;
1379
1380                         if(v == 0xFF) {
1381                                 src_mode = mode_Bu;
1382                         } else {
1383                                 assert(v == 0xFFFF);
1384                                 src_mode = mode_Hu;
1385                         }
1386                         res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1387
1388                         return res;
1389                 }
1390         }
1391         return gen_binop(node, op1, op2, new_rd_ia32_And,
1392                          match_commutative | match_mode_neutral | match_am
1393                                          | match_immediate);
1394 }
1395
1396
1397
1398 /**
1399  * Creates an ia32 Or.
1400  *
1401  * @return The created ia32 Or node
1402  */
1403 static ir_node *gen_Or(ir_node *node) {
1404         ir_node *op1 = get_Or_left(node);
1405         ir_node *op2 = get_Or_right(node);
1406
1407         assert (! mode_is_float(get_irn_mode(node)));
1408         return gen_binop(node, op1, op2, new_rd_ia32_Or, match_commutative
1409                         | match_mode_neutral | match_am | match_immediate);
1410 }
1411
1412
1413
1414 /**
1415  * Creates an ia32 Eor.
1416  *
1417  * @return The created ia32 Eor node
1418  */
1419 static ir_node *gen_Eor(ir_node *node) {
1420         ir_node *op1 = get_Eor_left(node);
1421         ir_node *op2 = get_Eor_right(node);
1422
1423         assert(! mode_is_float(get_irn_mode(node)));
1424         return gen_binop(node, op1, op2, new_rd_ia32_Xor, match_commutative
1425                         | match_mode_neutral | match_am | match_immediate);
1426 }
1427
1428
1429 /**
1430  * Creates an ia32 Sub.
1431  *
1432  * @return The created ia32 Sub node
1433  */
1434 static ir_node *gen_Sub(ir_node *node) {
1435         ir_node  *op1  = get_Sub_left(node);
1436         ir_node  *op2  = get_Sub_right(node);
1437         ir_mode  *mode = get_irn_mode(node);
1438
1439         if (mode_is_float(mode)) {
1440                 if (ia32_cg_config.use_sse2)
1441                         return gen_binop(node, op1, op2, new_rd_ia32_xSub, match_am);
1442                 else
1443                         return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfsub,
1444                                                    match_am);
1445         }
1446
1447         if (is_Const(op2)) {
1448                 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1449                            node);
1450         }
1451
1452         return gen_binop(node, op1, op2, new_rd_ia32_Sub, match_mode_neutral
1453                         | match_am | match_immediate);
1454 }
1455
1456 /**
1457  * Generates an ia32 DivMod with additional infrastructure for the
1458  * register allocator if needed.
1459  */
1460 static ir_node *create_Div(ir_node *node)
1461 {
1462         ir_graph *irg       = current_ir_graph;
1463         dbg_info *dbgi      = get_irn_dbg_info(node);
1464         ir_node  *block     = get_nodes_block(node);
1465         ir_node  *new_block = be_transform_node(block);
1466         ir_node  *mem;
1467         ir_node  *new_mem;
1468         ir_node  *op1;
1469         ir_node  *op2;
1470         ir_node  *new_node;
1471         ir_mode  *mode;
1472         ir_node  *sign_extension;
1473         ia32_address_mode_t  am;
1474         ia32_address_t      *addr = &am.addr;
1475
1476         /* the upper bits have random contents for smaller modes */
1477         switch (get_irn_opcode(node)) {
1478         case iro_Div:
1479                 op1     = get_Div_left(node);
1480                 op2     = get_Div_right(node);
1481                 mem     = get_Div_mem(node);
1482                 mode    = get_Div_resmode(node);
1483                 break;
1484         case iro_Mod:
1485                 op1     = get_Mod_left(node);
1486                 op2     = get_Mod_right(node);
1487                 mem     = get_Mod_mem(node);
1488                 mode    = get_Mod_resmode(node);
1489                 break;
1490         case iro_DivMod:
1491                 op1     = get_DivMod_left(node);
1492                 op2     = get_DivMod_right(node);
1493                 mem     = get_DivMod_mem(node);
1494                 mode    = get_DivMod_resmode(node);
1495                 break;
1496         default:
1497                 panic("invalid divmod node %+F", node);
1498         }
1499
1500         match_arguments(&am, block, op1, op2, NULL, match_am);
1501
1502         /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1503            is the memory of the consumed address. We can have only the second op as address
1504            in Div nodes, so check only op2. */
1505         if(!is_NoMem(mem) && skip_Proj(mem) != skip_Proj(op2)) {
1506                 new_mem = be_transform_node(mem);
1507                 if(!is_NoMem(addr->mem)) {
1508                         ir_node *in[2];
1509                         in[0] = new_mem;
1510                         in[1] = addr->mem;
1511                         new_mem = new_rd_Sync(dbgi, irg, new_block, 2, in);
1512                 }
1513         } else {
1514                 new_mem = addr->mem;
1515         }
1516
1517         if (mode_is_signed(mode)) {
1518                 ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1519                 add_irn_dep(produceval, get_irg_frame(irg));
1520                 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1,
1521                                                   produceval);
1522
1523                 new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base,
1524                                             addr->index, new_mem, am.new_op2,
1525                                             am.new_op1, sign_extension);
1526         } else {
1527                 sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0);
1528                 add_irn_dep(sign_extension, get_irg_frame(irg));
1529
1530                 new_node = new_rd_ia32_Div(dbgi, irg, new_block, addr->base,
1531                                            addr->index, new_mem, am.new_op2,
1532                                            am.new_op1, sign_extension);
1533         }
1534
1535         set_irn_pinned(new_node, get_irn_pinned(node));
1536
1537         set_am_attributes(new_node, &am);
1538         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1539
1540         new_node = fix_mem_proj(new_node, &am);
1541
1542         return new_node;
1543 }
1544
1545
1546 static ir_node *gen_Mod(ir_node *node) {
1547         return create_Div(node);
1548 }
1549
1550 static ir_node *gen_Div(ir_node *node) {
1551         return create_Div(node);
1552 }
1553
1554 static ir_node *gen_DivMod(ir_node *node) {
1555         return create_Div(node);
1556 }
1557
1558
1559
1560 /**
1561  * Creates an ia32 floating Div.
1562  *
1563  * @return The created ia32 xDiv node
1564  */
1565 static ir_node *gen_Quot(ir_node *node)
1566 {
1567         ir_node *op1 = get_Quot_left(node);
1568         ir_node *op2 = get_Quot_right(node);
1569
1570         if (ia32_cg_config.use_sse2) {
1571                 return gen_binop(node, op1, op2, new_rd_ia32_xDiv, match_am);
1572         } else {
1573                 return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfdiv, match_am);
1574         }
1575 }
1576
1577
1578 /**
1579  * Creates an ia32 Shl.
1580  *
1581  * @return The created ia32 Shl node
1582  */
1583 static ir_node *gen_Shl(ir_node *node) {
1584         ir_node *left  = get_Shl_left(node);
1585         ir_node *right = get_Shl_right(node);
1586
1587         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
1588                                match_mode_neutral | match_immediate);
1589 }
1590
1591 /**
1592  * Creates an ia32 Shr.
1593  *
1594  * @return The created ia32 Shr node
1595  */
1596 static ir_node *gen_Shr(ir_node *node) {
1597         ir_node *left  = get_Shr_left(node);
1598         ir_node *right = get_Shr_right(node);
1599
1600         return gen_shift_binop(node, left, right, new_rd_ia32_Shr, match_immediate);
1601 }
1602
1603
1604
1605 /**
1606  * Creates an ia32 Sar.
1607  *
1608  * @return The created ia32 Shrs node
1609  */
1610 static ir_node *gen_Shrs(ir_node *node) {
1611         ir_node *left  = get_Shrs_left(node);
1612         ir_node *right = get_Shrs_right(node);
1613         ir_mode *mode  = get_irn_mode(node);
1614
1615         if(is_Const(right) && mode == mode_Is) {
1616                 tarval *tv = get_Const_tarval(right);
1617                 long val = get_tarval_long(tv);
1618                 if(val == 31) {
1619                         /* this is a sign extension */
1620                         ir_graph *irg    = current_ir_graph;
1621                         dbg_info *dbgi   = get_irn_dbg_info(node);
1622                         ir_node  *block  = be_transform_node(get_nodes_block(node));
1623                         ir_node  *op     = left;
1624                         ir_node  *new_op = be_transform_node(op);
1625                         ir_node  *pval   = new_rd_ia32_ProduceVal(dbgi, irg, block);
1626                         add_irn_dep(pval, get_irg_frame(irg));
1627
1628                         return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval);
1629                 }
1630         }
1631
1632         /* 8 or 16 bit sign extension? */
1633         if(is_Const(right) && is_Shl(left) && mode == mode_Is) {
1634                 ir_node *shl_left  = get_Shl_left(left);
1635                 ir_node *shl_right = get_Shl_right(left);
1636                 if(is_Const(shl_right)) {
1637                         tarval *tv1 = get_Const_tarval(right);
1638                         tarval *tv2 = get_Const_tarval(shl_right);
1639                         if(tv1 == tv2 && tarval_is_long(tv1)) {
1640                                 long val = get_tarval_long(tv1);
1641                                 if(val == 16 || val == 24) {
1642                                         dbg_info *dbgi   = get_irn_dbg_info(node);
1643                                         ir_node  *block  = get_nodes_block(node);
1644                                         ir_mode  *src_mode;
1645                                         ir_node  *res;
1646
1647                                         if(val == 24) {
1648                                                 src_mode = mode_Bs;
1649                                         } else {
1650                                                 assert(val == 16);
1651                                                 src_mode = mode_Hs;
1652                                         }
1653                                         res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1654                                                               shl_left, node);
1655
1656                                         return res;
1657                                 }
1658                         }
1659                 }
1660         }
1661
1662         return gen_shift_binop(node, left, right, new_rd_ia32_Sar, match_immediate);
1663 }
1664
1665
1666
1667 /**
1668  * Creates an ia32 RotL.
1669  *
1670  * @param op1   The first operator
1671  * @param op2   The second operator
1672  * @return The created ia32 RotL node
1673  */
1674 static ir_node *gen_RotL(ir_node *node, ir_node *op1, ir_node *op2) {
1675         return gen_shift_binop(node, op1, op2, new_rd_ia32_Rol, match_immediate);
1676 }
1677
1678
1679
1680 /**
1681  * Creates an ia32 RotR.
1682  * NOTE: There is no RotR with immediate because this would always be a RotL
1683  *       "imm-mode_size_bits" which can be pre-calculated.
1684  *
1685  * @param op1   The first operator
1686  * @param op2   The second operator
1687  * @return The created ia32 RotR node
1688  */
1689 static ir_node *gen_RotR(ir_node *node, ir_node *op1, ir_node *op2) {
1690         return gen_shift_binop(node, op1, op2, new_rd_ia32_Ror, match_immediate);
1691 }
1692
1693
1694
1695 /**
1696  * Creates an ia32 RotR or RotL (depending on the found pattern).
1697  *
1698  * @return The created ia32 RotL or RotR node
1699  */
1700 static ir_node *gen_Rot(ir_node *node) {
1701         ir_node *rotate = NULL;
1702         ir_node *op1    = get_Rot_left(node);
1703         ir_node *op2    = get_Rot_right(node);
1704
1705         /* Firm has only Rot (which is a RotL), so we are looking for a right (op2)
1706                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1707                  that means we can create a RotR instead of an Add and a RotL */
1708
1709         if (get_irn_op(op2) == op_Add) {
1710                 ir_node *add = op2;
1711                 ir_node *left = get_Add_left(add);
1712                 ir_node *right = get_Add_right(add);
1713                 if (is_Const(right)) {
1714                         tarval  *tv   = get_Const_tarval(right);
1715                         ir_mode *mode = get_irn_mode(node);
1716                         long     bits = get_mode_size_bits(mode);
1717
1718                         if (get_irn_op(left) == op_Minus &&
1719                                         tarval_is_long(tv)       &&
1720                                         get_tarval_long(tv) == bits &&
1721                                         bits                == 32)
1722                         {
1723                                 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1724                                 rotate = gen_RotR(node, op1, get_Minus_op(left));
1725                         }
1726                 }
1727         }
1728
1729         if (rotate == NULL) {
1730                 rotate = gen_RotL(node, op1, op2);
1731         }
1732
1733         return rotate;
1734 }
1735
1736
1737
1738 /**
1739  * Transforms a Minus node.
1740  *
1741  * @return The created ia32 Minus node
1742  */
1743 static ir_node *gen_Minus(ir_node *node)
1744 {
1745         ir_node   *op    = get_Minus_op(node);
1746         ir_node   *block = be_transform_node(get_nodes_block(node));
1747         ir_graph  *irg   = current_ir_graph;
1748         dbg_info  *dbgi  = get_irn_dbg_info(node);
1749         ir_mode   *mode  = get_irn_mode(node);
1750         ir_entity *ent;
1751         ir_node   *new_node;
1752         int        size;
1753
1754         if (mode_is_float(mode)) {
1755                 ir_node *new_op = be_transform_node(op);
1756                 if (ia32_cg_config.use_sse2) {
1757                         /* TODO: non-optimal... if we have many xXors, then we should
1758                          * rather create a load for the const and use that instead of
1759                          * several AM nodes... */
1760                         ir_node *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1761                         ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1762                         ir_node *nomem     = new_rd_NoMem(irg);
1763
1764                         new_node = new_rd_ia32_xXor(dbgi, irg, block, noreg_gp, noreg_gp,
1765                                                     nomem, new_op, noreg_xmm);
1766
1767                         size = get_mode_size_bits(mode);
1768                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1769
1770                         set_ia32_am_sc(new_node, ent);
1771                         set_ia32_op_type(new_node, ia32_AddrModeS);
1772                         set_ia32_ls_mode(new_node, mode);
1773                 } else {
1774                         new_node = new_rd_ia32_vfchs(dbgi, irg, block, new_op);
1775                 }
1776         } else {
1777                 new_node = gen_unop(node, op, new_rd_ia32_Neg, match_mode_neutral);
1778         }
1779
1780         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1781
1782         return new_node;
1783 }
1784
1785 /**
1786  * Transforms a Not node.
1787  *
1788  * @return The created ia32 Not node
1789  */
1790 static ir_node *gen_Not(ir_node *node) {
1791         ir_node *op   = get_Not_op(node);
1792
1793         assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1794         assert (! mode_is_float(get_irn_mode(node)));
1795
1796         return gen_unop(node, op, new_rd_ia32_Not, match_mode_neutral);
1797 }
1798
1799
1800
1801 /**
1802  * Transforms an Abs node.
1803  *
1804  * @return The created ia32 Abs node
1805  */
1806 static ir_node *gen_Abs(ir_node *node)
1807 {
1808         ir_node   *block     = get_nodes_block(node);
1809         ir_node   *new_block = be_transform_node(block);
1810         ir_node   *op        = get_Abs_op(node);
1811         ir_graph  *irg       = current_ir_graph;
1812         dbg_info  *dbgi      = get_irn_dbg_info(node);
1813         ir_mode   *mode      = get_irn_mode(node);
1814         ir_node   *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1815         ir_node   *nomem     = new_NoMem();
1816         ir_node   *new_op;
1817         ir_node   *new_node;
1818         int        size;
1819         ir_entity *ent;
1820
1821         if (mode_is_float(mode)) {
1822                 new_op = be_transform_node(op);
1823
1824                 if (ia32_cg_config.use_sse2) {
1825                         ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1826                         new_node = new_rd_ia32_xAnd(dbgi,irg, new_block, noreg_gp, noreg_gp,
1827                                                     nomem, new_op, noreg_fp);
1828
1829                         size = get_mode_size_bits(mode);
1830                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1831
1832                         set_ia32_am_sc(new_node, ent);
1833
1834                         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1835
1836                         set_ia32_op_type(new_node, ia32_AddrModeS);
1837                         set_ia32_ls_mode(new_node, mode);
1838                 } else {
1839                         new_node = new_rd_ia32_vfabs(dbgi, irg, new_block, new_op);
1840                         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1841                 }
1842         } else {
1843                 ir_node *xor, *pval, *sign_extension;
1844
1845                 if (get_mode_size_bits(mode) == 32) {
1846                         new_op = be_transform_node(op);
1847                 } else {
1848                         new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1849                 }
1850
1851                 pval           = new_rd_ia32_ProduceVal(dbgi, irg, new_block);
1852                 sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block,
1853                                                            new_op, pval);
1854
1855                 add_irn_dep(pval, get_irg_frame(irg));
1856                 SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node));
1857
1858                 xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp,
1859                                       nomem, new_op, sign_extension);
1860                 SET_IA32_ORIG_NODE(xor, ia32_get_old_node_name(env_cg, node));
1861
1862                 new_node = new_rd_ia32_Sub(dbgi, irg, new_block, noreg_gp, noreg_gp,
1863                                            nomem, xor, sign_extension);
1864                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1865         }
1866
1867         return new_node;
1868 }
1869
1870 /**
1871  * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1872  */
1873 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n) {
1874         dbg_info *dbgi      = get_irn_dbg_info(cmp);
1875         ir_node  *block     = get_nodes_block(cmp);
1876         ir_node  *new_block = be_transform_node(block);
1877         ir_node  *op1       = be_transform_node(x);
1878         ir_node  *op2       = be_transform_node(n);
1879
1880         return new_rd_ia32_Bt(dbgi, current_ir_graph, new_block, op1, op2);
1881 }
1882
1883 /**
1884  * Transform a node returning a "flag" result.
1885  *
1886  * @param node     the node to transform
1887  * @param pnc_out  the compare mode to use
1888  */
1889 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1890 {
1891         ir_node  *flags;
1892         ir_node  *new_op;
1893         ir_node  *noreg;
1894         ir_node  *nomem;
1895         ir_node  *new_block;
1896         dbg_info *dbgi;
1897
1898         /* we have a Cmp as input */
1899         if (is_Proj(node)) {
1900                 ir_node *pred = get_Proj_pred(node);
1901                 if (is_Cmp(pred)) {
1902                         pn_Cmp pnc = get_Proj_proj(node);
1903                         if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1904                                 ir_node *l = get_Cmp_left(pred);
1905                                 ir_node *r = get_Cmp_right(pred);
1906                                 if (is_And(l)) {
1907                                         ir_node *la = get_And_left(l);
1908                                         ir_node *ra = get_And_right(l);
1909                                         if (is_Shl(la)) {
1910                                                 ir_node *c = get_Shl_left(la);
1911                                                 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1912                                                         /* (1 << n) & ra) */
1913                                                         ir_node *n = get_Shl_right(la);
1914                                                         flags    = gen_bt(pred, ra, n);
1915                                                         /* we must generate a Jc/Jnc jump */
1916                                                         pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1917                                                         if (r == la)
1918                                                                 pnc ^= pn_Cmp_Leg;
1919                                                         *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1920                                                         return flags;
1921                                                 }
1922                                         }
1923                                         if (is_Shl(ra)) {
1924                                                 ir_node *c = get_Shl_left(ra);
1925                                                 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1926                                                         /* la & (1 << n)) */
1927                                                         ir_node *n = get_Shl_right(ra);
1928                                                         flags    = gen_bt(pred, la, n);
1929                                                         /* we must generate a Jc/Jnc jump */
1930                                                         pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1931                                                         if (r == ra)
1932                                                                 pnc ^= pn_Cmp_Leg;
1933                                                         *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1934                                                         return flags;
1935                                                 }
1936                                         }
1937                                 }
1938                         }
1939                         flags    = be_transform_node(pred);
1940                         *pnc_out = pnc;
1941                         return flags;
1942                 }
1943         }
1944
1945         /* a mode_b value, we have to compare it against 0 */
1946         dbgi      = get_irn_dbg_info(node);
1947         new_block = be_transform_node(get_nodes_block(node));
1948         new_op    = be_transform_node(node);
1949         noreg     = ia32_new_NoReg_gp(env_cg);
1950         nomem     = new_NoMem();
1951         flags     = new_rd_ia32_Test(dbgi, current_ir_graph, new_block, noreg, noreg, nomem,
1952                                      new_op, new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1953         *pnc_out  = pn_Cmp_Lg;
1954         return flags;
1955 }
1956
1957 /**
1958  * Transforms a Load.
1959  *
1960  * @return the created ia32 Load node
1961  */
1962 static ir_node *gen_Load(ir_node *node) {
1963         ir_node  *old_block = get_nodes_block(node);
1964         ir_node  *block   = be_transform_node(old_block);
1965         ir_node  *ptr     = get_Load_ptr(node);
1966         ir_node  *mem     = get_Load_mem(node);
1967         ir_node  *new_mem = be_transform_node(mem);
1968         ir_node  *base;
1969         ir_node  *index;
1970         ir_graph *irg     = current_ir_graph;
1971         dbg_info *dbgi    = get_irn_dbg_info(node);
1972         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
1973         ir_mode  *mode    = get_Load_mode(node);
1974         ir_mode  *res_mode;
1975         ir_node  *new_node;
1976         ia32_address_t addr;
1977
1978         /* construct load address */
1979         memset(&addr, 0, sizeof(addr));
1980         ia32_create_address_mode(&addr, ptr, /*force=*/0);
1981         base  = addr.base;
1982         index = addr.index;
1983
1984         if(base == NULL) {
1985                 base = noreg;
1986         } else {
1987                 base = be_transform_node(base);
1988         }
1989
1990         if(index == NULL) {
1991                 index = noreg;
1992         } else {
1993                 index = be_transform_node(index);
1994         }
1995
1996         if (mode_is_float(mode)) {
1997                 if (ia32_cg_config.use_sse2) {
1998                         new_node = new_rd_ia32_xLoad(dbgi, irg, block, base, index, new_mem,
1999                                                      mode);
2000                         res_mode = mode_xmm;
2001                 } else {
2002                         new_node = new_rd_ia32_vfld(dbgi, irg, block, base, index, new_mem,
2003                                                     mode);
2004                         res_mode = mode_vfp;
2005                 }
2006         } else {
2007                 assert(mode != mode_b);
2008
2009                 /* create a conv node with address mode for smaller modes */
2010                 if(get_mode_size_bits(mode) < 32) {
2011                         new_node = new_rd_ia32_Conv_I2I(dbgi, irg, block, base, index,
2012                                                         new_mem, noreg, mode);
2013                 } else {
2014                         new_node = new_rd_ia32_Load(dbgi, irg, block, base, index, new_mem);
2015                 }
2016                 res_mode = mode_Iu;
2017         }
2018
2019         set_irn_pinned(new_node, get_irn_pinned(node));
2020         set_ia32_op_type(new_node, ia32_AddrModeS);
2021         set_ia32_ls_mode(new_node, mode);
2022         set_address(new_node, &addr);
2023
2024         if(get_irn_pinned(node) == op_pin_state_floats) {
2025                 add_ia32_flags(new_node, arch_irn_flags_rematerializable);
2026         }
2027
2028         /* make sure we are scheduled behind the initial IncSP/Barrier
2029          * to avoid spills being placed before it
2030          */
2031         if (block == get_irg_start_block(irg)) {
2032                 add_irn_dep(new_node, get_irg_frame(irg));
2033         }
2034
2035         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2036
2037         return new_node;
2038 }
2039
2040 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
2041                        ir_node *ptr, ir_node *other)
2042 {
2043         ir_node *load;
2044
2045         if(!is_Proj(node))
2046                 return 0;
2047
2048         /* we only use address mode if we're the only user of the load */
2049         if(get_irn_n_edges(node) > 1)
2050                 return 0;
2051
2052         load = get_Proj_pred(node);
2053         if(!is_Load(load))
2054                 return 0;
2055         if(get_nodes_block(load) != block)
2056                 return 0;
2057
2058         /* Store should be attached to the load */
2059         if(!is_Proj(mem) || get_Proj_pred(mem) != load)
2060                 return 0;
2061         /* store should have the same pointer as the load */
2062         if(get_Load_ptr(load) != ptr)
2063                 return 0;
2064
2065         /* don't do AM if other node inputs depend on the load (via mem-proj) */
2066         if(other != NULL && get_nodes_block(other) == block
2067                         && heights_reachable_in_block(heights, other, load))
2068                 return 0;
2069
2070         return 1;
2071 }
2072
2073 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
2074                               ir_node *mem, ir_node *ptr, ir_mode *mode,
2075                               construct_binop_dest_func *func,
2076                               construct_binop_dest_func *func8bit,
2077                                                           match_flags_t flags)
2078 {
2079         ir_node  *src_block = get_nodes_block(node);
2080         ir_node  *block;
2081         ir_node  *noreg_gp  = ia32_new_NoReg_gp(env_cg);
2082         ir_graph *irg      = current_ir_graph;
2083         dbg_info *dbgi;
2084         ir_node  *new_node;
2085         ir_node  *new_op;
2086         int       commutative;
2087         ia32_address_mode_t  am;
2088         ia32_address_t      *addr = &am.addr;
2089         memset(&am, 0, sizeof(am));
2090
2091         assert(flags & match_dest_am);
2092         assert(flags & match_immediate); /* there is no destam node without... */
2093         commutative = (flags & match_commutative) != 0;
2094
2095         if(use_dest_am(src_block, op1, mem, ptr, op2)) {
2096                 build_address(&am, op1);
2097                 new_op = create_immediate_or_transform(op2, 0);
2098         } else if(commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
2099                 build_address(&am, op2);
2100                 new_op = create_immediate_or_transform(op1, 0);
2101         } else {
2102                 return NULL;
2103         }
2104
2105         if(addr->base == NULL)
2106                 addr->base = noreg_gp;
2107         if(addr->index == NULL)
2108                 addr->index = noreg_gp;
2109         if(addr->mem == NULL)
2110                 addr->mem = new_NoMem();
2111
2112         dbgi  = get_irn_dbg_info(node);
2113         block = be_transform_node(src_block);
2114         if(get_mode_size_bits(mode) == 8) {
2115                 new_node = func8bit(dbgi, irg, block, addr->base, addr->index,
2116                                     addr->mem, new_op);
2117         } else {
2118                 new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
2119                                 new_op);
2120         }
2121         set_address(new_node, addr);
2122         set_ia32_op_type(new_node, ia32_AddrModeD);
2123         set_ia32_ls_mode(new_node, mode);
2124         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2125
2126         return new_node;
2127 }
2128
2129 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2130                              ir_node *ptr, ir_mode *mode,
2131                              construct_unop_dest_func *func)
2132 {
2133         ir_graph *irg      = current_ir_graph;
2134         ir_node *src_block = get_nodes_block(node);
2135         ir_node *block;
2136         dbg_info *dbgi;
2137         ir_node *new_node;
2138         ia32_address_mode_t  am;
2139         ia32_address_t *addr = &am.addr;
2140         memset(&am, 0, sizeof(am));
2141
2142         if(!use_dest_am(src_block, op, mem, ptr, NULL))
2143                 return NULL;
2144
2145         build_address(&am, op);
2146
2147         dbgi     = get_irn_dbg_info(node);
2148         block    = be_transform_node(src_block);
2149         new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem);
2150         set_address(new_node, addr);
2151         set_ia32_op_type(new_node, ia32_AddrModeD);
2152         set_ia32_ls_mode(new_node, mode);
2153         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2154
2155         return new_node;
2156 }
2157
2158 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) {
2159         ir_mode  *mode        = get_irn_mode(node);
2160         ir_node  *psi_true    = get_Psi_val(node, 0);
2161         ir_node  *psi_default = get_Psi_default(node);
2162         ir_graph *irg;
2163         ir_node  *cond;
2164         ir_node  *new_mem;
2165         dbg_info *dbgi;
2166         ir_node  *block;
2167         ir_node  *new_block;
2168         ir_node  *flags;
2169         ir_node  *new_node;
2170         int       negated;
2171         pn_Cmp    pnc;
2172         ia32_address_t addr;
2173
2174         if(get_mode_size_bits(mode) != 8)
2175                 return NULL;
2176
2177         if(is_Const_1(psi_true) && is_Const_0(psi_default)) {
2178                 negated = 0;
2179         } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) {
2180                 negated = 1;
2181         } else {
2182                 return NULL;
2183         }
2184
2185         build_address_ptr(&addr, ptr, mem);
2186
2187         irg       = current_ir_graph;
2188         dbgi      = get_irn_dbg_info(node);
2189         block     = get_nodes_block(node);
2190         new_block = be_transform_node(block);
2191         cond      = get_Psi_cond(node, 0);
2192         flags     = get_flags_node(cond, &pnc);
2193         new_mem   = be_transform_node(mem);
2194         new_node  = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base,
2195                                        addr.index, addr.mem, flags, pnc, negated);
2196         set_address(new_node, &addr);
2197         set_ia32_op_type(new_node, ia32_AddrModeD);
2198         set_ia32_ls_mode(new_node, mode);
2199         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2200
2201         return new_node;
2202 }
2203
2204 static ir_node *try_create_dest_am(ir_node *node) {
2205         ir_node  *val  = get_Store_value(node);
2206         ir_node  *mem  = get_Store_mem(node);
2207         ir_node  *ptr  = get_Store_ptr(node);
2208         ir_mode  *mode = get_irn_mode(val);
2209         unsigned  bits = get_mode_size_bits(mode);
2210         ir_node  *op1;
2211         ir_node  *op2;
2212         ir_node  *new_node;
2213
2214         /* handle only GP modes for now... */
2215         if(!mode_needs_gp_reg(mode))
2216                 return NULL;
2217
2218         while(1) {
2219                 /* store must be the only user of the val node */
2220                 if(get_irn_n_edges(val) > 1)
2221                         return NULL;
2222                 /* skip pointless convs */
2223                 if(is_Conv(val)) {
2224                         ir_node *conv_op   = get_Conv_op(val);
2225                         ir_mode *pred_mode = get_irn_mode(conv_op);
2226                         if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2227                                 val = conv_op;
2228                                 continue;
2229                         }
2230                 }
2231                 break;
2232         }
2233
2234         /* value must be in the same block */
2235         if(get_nodes_block(node) != get_nodes_block(val))
2236                 return NULL;
2237
2238         switch(get_irn_opcode(val)) {
2239         case iro_Add:
2240                 op1      = get_Add_left(val);
2241                 op2      = get_Add_right(val);
2242                 if(is_Const_1(op2)) {
2243                         new_node = dest_am_unop(val, op1, mem, ptr, mode,
2244                                                 new_rd_ia32_IncMem);
2245                         break;
2246                 } else if(is_Const_Minus_1(op2)) {
2247                         new_node = dest_am_unop(val, op1, mem, ptr, mode,
2248                                                 new_rd_ia32_DecMem);
2249                         break;
2250                 }
2251                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2252                                          new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
2253                                          match_dest_am | match_commutative |
2254                                          match_immediate);
2255                 break;
2256         case iro_Sub:
2257                 op1      = get_Sub_left(val);
2258                 op2      = get_Sub_right(val);
2259                 if(is_Const(op2)) {
2260                         ir_fprintf(stderr, "Optimisation warning: not-normalize sub ,C"
2261                                    "found\n");
2262                 }
2263                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2264                                          new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
2265                                          match_dest_am | match_immediate |
2266                                          match_immediate);
2267                 break;
2268         case iro_And:
2269                 op1      = get_And_left(val);
2270                 op2      = get_And_right(val);
2271                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2272                                          new_rd_ia32_AndMem, new_rd_ia32_AndMem8Bit,
2273                                          match_dest_am | match_commutative |
2274                                          match_immediate);
2275                 break;
2276         case iro_Or:
2277                 op1      = get_Or_left(val);
2278                 op2      = get_Or_right(val);
2279                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2280                                          new_rd_ia32_OrMem, new_rd_ia32_OrMem8Bit,
2281                                          match_dest_am | match_commutative |
2282                                          match_immediate);
2283                 break;
2284         case iro_Eor:
2285                 op1      = get_Eor_left(val);
2286                 op2      = get_Eor_right(val);
2287                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2288                                          new_rd_ia32_XorMem, new_rd_ia32_XorMem8Bit,
2289                                          match_dest_am | match_commutative |
2290                                          match_immediate);
2291                 break;
2292         case iro_Shl:
2293                 op1      = get_Shl_left(val);
2294                 op2      = get_Shl_right(val);
2295                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2296                                          new_rd_ia32_ShlMem, new_rd_ia32_ShlMem,
2297                                          match_dest_am | match_immediate);
2298                 break;
2299         case iro_Shr:
2300                 op1      = get_Shr_left(val);
2301                 op2      = get_Shr_right(val);
2302                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2303                                          new_rd_ia32_ShrMem, new_rd_ia32_ShrMem,
2304                                          match_dest_am | match_immediate);
2305                 break;
2306         case iro_Shrs:
2307                 op1      = get_Shrs_left(val);
2308                 op2      = get_Shrs_right(val);
2309                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2310                                          new_rd_ia32_SarMem, new_rd_ia32_SarMem,
2311                                          match_dest_am | match_immediate);
2312                 break;
2313         case iro_Rot:
2314                 op1      = get_Rot_left(val);
2315                 op2      = get_Rot_right(val);
2316                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2317                                          new_rd_ia32_RolMem, new_rd_ia32_RolMem,
2318                                          match_dest_am | match_immediate);
2319                 break;
2320         /* TODO: match ROR patterns... */
2321         case iro_Psi:
2322                 new_node = try_create_SetMem(val, ptr, mem);
2323                 break;
2324         case iro_Minus:
2325                 op1      = get_Minus_op(val);
2326                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem);
2327                 break;
2328         case iro_Not:
2329                 /* should be lowered already */
2330                 assert(mode != mode_b);
2331                 op1      = get_Not_op(val);
2332                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NotMem);
2333                 break;
2334         default:
2335                 return NULL;
2336         }
2337
2338         if(new_node != NULL) {
2339                 if(get_irn_pinned(new_node) != op_pin_state_pinned &&
2340                                 get_irn_pinned(node) == op_pin_state_pinned) {
2341                         set_irn_pinned(new_node, op_pin_state_pinned);
2342                 }
2343         }
2344
2345         return new_node;
2346 }
2347
2348 static int is_float_to_int32_conv(const ir_node *node)
2349 {
2350         ir_mode  *mode = get_irn_mode(node);
2351         ir_node  *conv_op;
2352         ir_mode  *conv_mode;
2353
2354         if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode))
2355                 return 0;
2356
2357         if(!is_Conv(node))
2358                 return 0;
2359         conv_op   = get_Conv_op(node);
2360         conv_mode = get_irn_mode(conv_op);
2361
2362         if(!mode_is_float(conv_mode))
2363                 return 0;
2364
2365         return 1;
2366 }
2367
2368 /**
2369  * Transform a Store(floatConst).
2370  *
2371  * @return the created ia32 Store node
2372  */
2373 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns) {
2374         ir_mode  *mode      = get_irn_mode(cns);
2375         int      size       = get_mode_size_bits(mode);
2376         tarval   *tv        = get_Const_tarval(cns);
2377         ir_node  *block     = get_nodes_block(node);
2378         ir_node  *new_block = be_transform_node(block);
2379         ir_node  *ptr       = get_Store_ptr(node);
2380         ir_node  *mem       = get_Store_mem(node);
2381         ir_graph *irg       = current_ir_graph;
2382         dbg_info *dbgi      = get_irn_dbg_info(node);
2383         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2384         int      ofs        = 4;
2385         ir_node  *new_node;
2386         ia32_address_t addr;
2387
2388         unsigned val = get_tarval_sub_bits(tv, 0) |
2389                 (get_tarval_sub_bits(tv, 1) << 8) |
2390                 (get_tarval_sub_bits(tv, 2) << 16) |
2391                 (get_tarval_sub_bits(tv, 3) << 24);
2392         ir_node *imm = create_Immediate(NULL, 0, val);
2393
2394         /* construct store address */
2395         memset(&addr, 0, sizeof(addr));
2396         ia32_create_address_mode(&addr, ptr, /*force=*/0);
2397
2398         if (addr.base == NULL) {
2399                 addr.base = noreg;
2400         } else {
2401                 addr.base = be_transform_node(addr.base);
2402         }
2403
2404         if (addr.index == NULL) {
2405                 addr.index = noreg;
2406         } else {
2407                 addr.index = be_transform_node(addr.index);
2408         }
2409         addr.mem = be_transform_node(mem);
2410
2411         new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2412                 addr.index, addr.mem, imm);
2413
2414         set_irn_pinned(new_node, get_irn_pinned(node));
2415         set_ia32_op_type(new_node, ia32_AddrModeD);
2416         set_ia32_ls_mode(new_node, mode_Iu);
2417
2418         set_address(new_node, &addr);
2419
2420         /** add more stores if needed */
2421         while (size > 32) {
2422                 unsigned val = get_tarval_sub_bits(tv, ofs) |
2423                         (get_tarval_sub_bits(tv, ofs + 1) << 8) |
2424                         (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2425                         (get_tarval_sub_bits(tv, ofs + 3) << 24);
2426                 ir_node *imm = create_Immediate(NULL, 0, val);
2427
2428                 addr.offset += 4;
2429                 addr.mem = new_node;
2430
2431                 new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2432                         addr.index, addr.mem, imm);
2433
2434                 set_irn_pinned(new_node, get_irn_pinned(node));
2435                 set_ia32_op_type(new_node, ia32_AddrModeD);
2436                 set_ia32_ls_mode(new_node, mode_Iu);
2437
2438                 set_address(new_node, &addr);
2439                 size -= 32;
2440                 ofs  += 4;
2441         }
2442
2443         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2444         return new_node;
2445 }
2446
2447 /**
2448  * Generate a vfist or vfisttp instruction.
2449  */
2450 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2451                           ir_node *mem,  ir_node *val, ir_node **fist)
2452 {
2453         ir_node *new_node;
2454
2455         if (ia32_cg_config.use_fisttp) {
2456                 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2457                 if other users exists */
2458                 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2459                 ir_node *vfisttp = new_rd_ia32_vfisttp(dbgi, irg, block, base, index, mem, val);
2460                 ir_node *value   = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2461                 be_new_Keep(reg_class, irg, block, 1, &value);
2462
2463                 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2464                 *fist    = vfisttp;
2465         } else {
2466                 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2467
2468                 /* do a fist */
2469                 new_node = new_rd_ia32_vfist(dbgi, irg, block, base, index, mem, val, trunc_mode);
2470                 *fist    = new_node;
2471         }
2472         return new_node;
2473 }
2474 /**
2475  * Transforms a normal Store.
2476  *
2477  * @return the created ia32 Store node
2478  */
2479 static ir_node *gen_normal_Store(ir_node *node)
2480 {
2481         ir_node  *val       = get_Store_value(node);
2482         ir_mode  *mode      = get_irn_mode(val);
2483         ir_node  *block     = get_nodes_block(node);
2484         ir_node  *new_block = be_transform_node(block);
2485         ir_node  *ptr       = get_Store_ptr(node);
2486         ir_node  *mem       = get_Store_mem(node);
2487         ir_graph *irg       = current_ir_graph;
2488         dbg_info *dbgi      = get_irn_dbg_info(node);
2489         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2490         ir_node  *new_val, *new_node, *store;
2491         ia32_address_t addr;
2492
2493         /* check for destination address mode */
2494         new_node = try_create_dest_am(node);
2495         if (new_node != NULL)
2496                 return new_node;
2497
2498         /* construct store address */
2499         memset(&addr, 0, sizeof(addr));
2500         ia32_create_address_mode(&addr, ptr, /*force=*/0);
2501
2502         if (addr.base == NULL) {
2503                 addr.base = noreg;
2504         } else {
2505                 addr.base = be_transform_node(addr.base);
2506         }
2507
2508         if (addr.index == NULL) {
2509                 addr.index = noreg;
2510         } else {
2511                 addr.index = be_transform_node(addr.index);
2512         }
2513         addr.mem = be_transform_node(mem);
2514
2515         if (mode_is_float(mode)) {
2516                 if (ia32_cg_config.use_sse2) {
2517                         /* Convs (and strict-Convs) before stores are unnecessary if the mode
2518                            is the same. */
2519                         while (is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2520                                 val = get_Conv_op(val);
2521                         }
2522                         new_val = be_transform_node(val);
2523                         new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2524                                                       addr.index, addr.mem, new_val);
2525                 } else {
2526                         /* We can skip ALL float Convs (and strict-Convs) before stores. */
2527                         while (is_Conv(val) &&
2528                                         mode_is_float(get_irn_mode(get_Conv_op(val)))) {
2529                                 val = get_Conv_op(val);
2530                         }
2531                         new_val = be_transform_node(val);
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         ir_graph *irg       = current_ir_graph;
4321         dbg_info *dbgi      = get_irn_dbg_info(node);
4322         ir_node  *op        = get_IJmp_target(node);
4323         ir_node  *new_node;
4324         ia32_address_mode_t  am;
4325         ia32_address_t      *addr = &am.addr;
4326
4327         assert(get_irn_mode(op) == mode_P);
4328
4329         match_arguments(&am, block, NULL, op, NULL,
4330                         match_am | match_8bit_am | match_16bit_am |
4331                         match_immediate | match_8bit | match_16bit);
4332
4333         new_node = new_rd_ia32_IJmp(dbgi, irg, new_block, addr->base, addr->index,
4334                                     addr->mem, 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 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4344                                      ir_node *mem);
4345
4346 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4347                                       ir_node *val, ir_node *mem);
4348
4349 /**
4350  * Transforms a lowered Load into a "real" one.
4351  */
4352 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4353 {
4354         ir_node  *block   = be_transform_node(get_nodes_block(node));
4355         ir_node  *ptr     = get_irn_n(node, 0);
4356         ir_node  *new_ptr = be_transform_node(ptr);
4357         ir_node  *mem     = get_irn_n(node, 1);
4358         ir_node  *new_mem = be_transform_node(mem);
4359         ir_graph *irg     = current_ir_graph;
4360         dbg_info *dbgi    = get_irn_dbg_info(node);
4361         ir_mode  *mode    = get_ia32_ls_mode(node);
4362         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
4363         ir_node  *new_op;
4364
4365         new_op  = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4366
4367         set_ia32_op_type(new_op, ia32_AddrModeS);
4368         set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4369         set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4370         set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4371         if (is_ia32_am_sc_sign(node))
4372                 set_ia32_am_sc_sign(new_op);
4373         set_ia32_ls_mode(new_op, mode);
4374         if (is_ia32_use_frame(node)) {
4375                 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4376                 set_ia32_use_frame(new_op);
4377         }
4378
4379         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4380
4381         return new_op;
4382 }
4383
4384 /**
4385  * Transforms a lowered Store into a "real" one.
4386  */
4387 static ir_node *gen_lowered_Store(ir_node *node, construct_store_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  *val     = get_irn_n(node, 1);
4393         ir_node  *new_val = be_transform_node(val);
4394         ir_node  *mem     = get_irn_n(node, 2);
4395         ir_node  *new_mem = be_transform_node(mem);
4396         ir_graph *irg     = current_ir_graph;
4397         dbg_info *dbgi    = get_irn_dbg_info(node);
4398         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
4399         ir_mode  *mode    = get_ia32_ls_mode(node);
4400         ir_node  *new_op;
4401         long     am_offs;
4402
4403         new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4404
4405         am_offs = get_ia32_am_offs_int(node);
4406         add_ia32_am_offs_int(new_op, am_offs);
4407
4408         set_ia32_op_type(new_op, ia32_AddrModeD);
4409         set_ia32_ls_mode(new_op, mode);
4410         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4411         set_ia32_use_frame(new_op);
4412
4413         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4414
4415         return new_op;
4416 }
4417
4418 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4419 {
4420         ir_node *left  = get_irn_n(node, n_ia32_l_ShlDep_val);
4421         ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4422
4423         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4424                                match_immediate | match_mode_neutral);
4425 }
4426
4427 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4428 {
4429         ir_node *left  = get_irn_n(node, n_ia32_l_ShrDep_val);
4430         ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4431         return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4432                                match_immediate);
4433 }
4434
4435 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4436 {
4437         ir_node *left  = get_irn_n(node, n_ia32_l_SarDep_val);
4438         ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4439         return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4440                                match_immediate);
4441 }
4442
4443 static ir_node *gen_ia32_l_Add(ir_node *node) {
4444         ir_node *left    = get_irn_n(node, n_ia32_l_Add_left);
4445         ir_node *right   = get_irn_n(node, n_ia32_l_Add_right);
4446         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4447                         match_commutative | match_am | match_immediate |
4448                         match_mode_neutral);
4449
4450         if(is_Proj(lowered)) {
4451                 lowered = get_Proj_pred(lowered);
4452         } else {
4453                 assert(is_ia32_Add(lowered));
4454                 set_irn_mode(lowered, mode_T);
4455         }
4456
4457         return lowered;
4458 }
4459
4460 static ir_node *gen_ia32_l_Adc(ir_node *node)
4461 {
4462         return gen_binop_flags(node, new_rd_ia32_Adc,
4463                         match_commutative | match_am | match_immediate |
4464                         match_mode_neutral);
4465 }
4466
4467 /**
4468  * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4469  *
4470  * @param node   The node to transform
4471  * @return the created ia32 vfild node
4472  */
4473 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4474         return gen_lowered_Load(node, new_rd_ia32_vfild);
4475 }
4476
4477 /**
4478  * Transforms an ia32_l_Load into a "real" ia32_Load node
4479  *
4480  * @param node   The node to transform
4481  * @return the created ia32 Load node
4482  */
4483 static ir_node *gen_ia32_l_Load(ir_node *node) {
4484         return gen_lowered_Load(node, new_rd_ia32_Load);
4485 }
4486
4487 /**
4488  * Transforms an ia32_l_Store into a "real" ia32_Store node
4489  *
4490  * @param node   The node to transform
4491  * @return the created ia32 Store node
4492  */
4493 static ir_node *gen_ia32_l_Store(ir_node *node) {
4494         return gen_lowered_Store(node, new_rd_ia32_Store);
4495 }
4496
4497 /**
4498  * Transforms a l_vfist into a "real" vfist node.
4499  *
4500  * @param node   The node to transform
4501  * @return the created ia32 vfist node
4502  */
4503 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4504         ir_node  *block      = be_transform_node(get_nodes_block(node));
4505         ir_node  *ptr        = get_irn_n(node, 0);
4506         ir_node  *new_ptr    = be_transform_node(ptr);
4507         ir_node  *val        = get_irn_n(node, 1);
4508         ir_node  *new_val    = be_transform_node(val);
4509         ir_node  *mem        = get_irn_n(node, 2);
4510         ir_node  *new_mem    = be_transform_node(mem);
4511         ir_graph *irg        = current_ir_graph;
4512         dbg_info *dbgi       = get_irn_dbg_info(node);
4513         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
4514         ir_mode  *mode       = get_ia32_ls_mode(node);
4515         ir_node  *memres, *fist;
4516         long     am_offs;
4517
4518         memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
4519         am_offs = get_ia32_am_offs_int(node);
4520         add_ia32_am_offs_int(fist, am_offs);
4521
4522         set_ia32_op_type(fist, ia32_AddrModeD);
4523         set_ia32_ls_mode(fist, mode);
4524         set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
4525         set_ia32_use_frame(fist);
4526
4527         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4528
4529         return memres;
4530 }
4531
4532 /**
4533  * Transforms a l_MulS into a "real" MulS node.
4534  *
4535  * @return the created ia32 Mul node
4536  */
4537 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4538         ir_node *left  = get_binop_left(node);
4539         ir_node *right = get_binop_right(node);
4540
4541         return gen_binop(node, left, right, new_rd_ia32_Mul,
4542                          match_commutative | match_am | match_mode_neutral);
4543 }
4544
4545 /**
4546  * Transforms a l_IMulS into a "real" IMul1OPS node.
4547  *
4548  * @return the created ia32 IMul1OP node
4549  */
4550 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4551         ir_node  *left  = get_binop_left(node);
4552         ir_node  *right = get_binop_right(node);
4553
4554         return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4555                          match_commutative | match_am | match_mode_neutral);
4556 }
4557
4558 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4559         ir_node *left    = get_irn_n(node, n_ia32_l_Sub_minuend);
4560         ir_node *right   = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4561         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4562                         match_am | match_immediate | match_mode_neutral);
4563
4564         if(is_Proj(lowered)) {
4565                 lowered = get_Proj_pred(lowered);
4566         } else {
4567                 assert(is_ia32_Sub(lowered));
4568                 set_irn_mode(lowered, mode_T);
4569         }
4570
4571         return lowered;
4572 }
4573
4574 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4575         return gen_binop_flags(node, new_rd_ia32_Sbb,
4576                         match_am | match_immediate | match_mode_neutral);
4577 }
4578
4579 /**
4580  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4581  * op1 - target to be shifted
4582  * op2 - contains bits to be shifted into target
4583  * op3 - shift count
4584  * Only op3 can be an immediate.
4585  */
4586 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4587                                          ir_node *low, ir_node *count)
4588 {
4589         ir_node  *block     = get_nodes_block(node);
4590         ir_node  *new_block = be_transform_node(block);
4591         ir_graph *irg       = current_ir_graph;
4592         dbg_info *dbgi      = get_irn_dbg_info(node);
4593         ir_node  *new_high  = be_transform_node(high);
4594         ir_node  *new_low   = be_transform_node(low);
4595         ir_node  *new_count;
4596         ir_node  *new_node;
4597
4598         /* the shift amount can be any mode that is bigger than 5 bits, since all
4599          * other bits are ignored anyway */
4600         while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4601                 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4602                 count = get_Conv_op(count);
4603         }
4604         new_count = create_immediate_or_transform(count, 0);
4605
4606         if (is_ia32_l_ShlD(node)) {
4607                 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4608                                             new_count);
4609         } else {
4610                 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4611                                             new_count);
4612         }
4613         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4614
4615         return new_node;
4616 }
4617
4618 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4619 {
4620         ir_node *high  = get_irn_n(node, n_ia32_l_ShlD_val_high);
4621         ir_node *low   = get_irn_n(node, n_ia32_l_ShlD_val_low);
4622         ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4623         return gen_lowered_64bit_shifts(node, high, low, count);
4624 }
4625
4626 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4627 {
4628         ir_node *high  = get_irn_n(node, n_ia32_l_ShrD_val_high);
4629         ir_node *low   = get_irn_n(node, n_ia32_l_ShrD_val_low);
4630         ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4631         return gen_lowered_64bit_shifts(node, high, low, count);
4632 }
4633
4634 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4635         ir_node  *src_block    = get_nodes_block(node);
4636         ir_node  *block        = be_transform_node(src_block);
4637         ir_graph *irg          = current_ir_graph;
4638         dbg_info *dbgi         = get_irn_dbg_info(node);
4639         ir_node  *frame        = get_irg_frame(irg);
4640         ir_node  *noreg        = ia32_new_NoReg_gp(env_cg);
4641         ir_node  *nomem        = new_NoMem();
4642         ir_node  *val_low      = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4643         ir_node  *val_high     = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4644         ir_node  *new_val_low  = be_transform_node(val_low);
4645         ir_node  *new_val_high = be_transform_node(val_high);
4646         ir_node  *in[2];
4647         ir_node  *sync;
4648         ir_node  *fild;
4649         ir_node  *store_low;
4650         ir_node  *store_high;
4651
4652         if(!mode_is_signed(get_irn_mode(val_high))) {
4653                 panic("unsigned long long -> float not supported yet (%+F)", node);
4654         }
4655
4656         /* do a store */
4657         store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4658                                       new_val_low);
4659         store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4660                                        new_val_high);
4661         SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4662         SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4663
4664         set_ia32_use_frame(store_low);
4665         set_ia32_use_frame(store_high);
4666         set_ia32_op_type(store_low, ia32_AddrModeD);
4667         set_ia32_op_type(store_high, ia32_AddrModeD);
4668         set_ia32_ls_mode(store_low, mode_Iu);
4669         set_ia32_ls_mode(store_high, mode_Is);
4670         add_ia32_am_offs_int(store_high, 4);
4671
4672         in[0] = store_low;
4673         in[1] = store_high;
4674         sync  = new_rd_Sync(dbgi, irg, block, 2, in);
4675
4676         /* do a fild */
4677         fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4678
4679         set_ia32_use_frame(fild);
4680         set_ia32_op_type(fild, ia32_AddrModeS);
4681         set_ia32_ls_mode(fild, mode_Ls);
4682
4683         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4684
4685         return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4686 }
4687
4688 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4689         ir_node  *src_block  = get_nodes_block(node);
4690         ir_node  *block      = be_transform_node(src_block);
4691         ir_graph *irg        = current_ir_graph;
4692         dbg_info *dbgi       = get_irn_dbg_info(node);
4693         ir_node  *frame      = get_irg_frame(irg);
4694         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
4695         ir_node  *nomem      = new_NoMem();
4696         ir_node  *val        = get_irn_n(node, n_ia32_l_FloattoLL_val);
4697         ir_node  *new_val    = be_transform_node(val);
4698         ir_node  *fist, *mem;
4699
4700         mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4701         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4702         set_ia32_use_frame(fist);
4703         set_ia32_op_type(fist, ia32_AddrModeD);
4704         set_ia32_ls_mode(fist, mode_Ls);
4705
4706         return mem;
4707 }
4708
4709 /**
4710  * the BAD transformer.
4711  */
4712 static ir_node *bad_transform(ir_node *node) {
4713         panic("No transform function for %+F available.\n", node);
4714         return NULL;
4715 }
4716
4717 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4718         ir_graph *irg      = current_ir_graph;
4719         ir_node  *block    = be_transform_node(get_nodes_block(node));
4720         ir_node  *pred     = get_Proj_pred(node);
4721         ir_node  *new_pred = be_transform_node(pred);
4722         ir_node  *frame    = get_irg_frame(irg);
4723         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
4724         dbg_info *dbgi     = get_irn_dbg_info(node);
4725         long      pn       = get_Proj_proj(node);
4726         ir_node  *load;
4727         ir_node  *proj;
4728         ia32_attr_t *attr;
4729
4730         load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4731         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4732         set_ia32_use_frame(load);
4733         set_ia32_op_type(load, ia32_AddrModeS);
4734         set_ia32_ls_mode(load, mode_Iu);
4735         /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4736          * 32 bit from it with this particular load */
4737         attr = get_ia32_attr(load);
4738         attr->data.need_64bit_stackent = 1;
4739
4740         if (pn == pn_ia32_l_FloattoLL_res_high) {
4741                 add_ia32_am_offs_int(load, 4);
4742         } else {
4743                 assert(pn == pn_ia32_l_FloattoLL_res_low);
4744         }
4745
4746         proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4747
4748         return proj;
4749 }
4750
4751 /**
4752  * Transform the Projs of an AddSP.
4753  */
4754 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4755         ir_node  *block    = be_transform_node(get_nodes_block(node));
4756         ir_node  *pred     = get_Proj_pred(node);
4757         ir_node  *new_pred = be_transform_node(pred);
4758         ir_graph *irg      = current_ir_graph;
4759         dbg_info *dbgi     = get_irn_dbg_info(node);
4760         long     proj      = get_Proj_proj(node);
4761
4762         if (proj == pn_be_AddSP_sp) {
4763                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4764                                            pn_ia32_SubSP_stack);
4765                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4766                 return res;
4767         } else if(proj == pn_be_AddSP_res) {
4768                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4769                                    pn_ia32_SubSP_addr);
4770         } else if (proj == pn_be_AddSP_M) {
4771                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4772         }
4773
4774         assert(0);
4775         return new_rd_Unknown(irg, get_irn_mode(node));
4776 }
4777
4778 /**
4779  * Transform the Projs of a SubSP.
4780  */
4781 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4782         ir_node  *block    = be_transform_node(get_nodes_block(node));
4783         ir_node  *pred     = get_Proj_pred(node);
4784         ir_node  *new_pred = be_transform_node(pred);
4785         ir_graph *irg      = current_ir_graph;
4786         dbg_info *dbgi     = get_irn_dbg_info(node);
4787         long     proj      = get_Proj_proj(node);
4788
4789         if (proj == pn_be_SubSP_sp) {
4790                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4791                                            pn_ia32_AddSP_stack);
4792                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4793                 return res;
4794         } else if (proj == pn_be_SubSP_M) {
4795                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4796         }
4797
4798         assert(0);
4799         return new_rd_Unknown(irg, get_irn_mode(node));
4800 }
4801
4802 /**
4803  * Transform and renumber the Projs from a Load.
4804  */
4805 static ir_node *gen_Proj_Load(ir_node *node) {
4806         ir_node  *new_pred;
4807         ir_node  *block    = be_transform_node(get_nodes_block(node));
4808         ir_node  *pred     = get_Proj_pred(node);
4809         ir_graph *irg      = current_ir_graph;
4810         dbg_info *dbgi     = get_irn_dbg_info(node);
4811         long     proj      = get_Proj_proj(node);
4812
4813         /* loads might be part of source address mode matches, so we don't
4814          * transform the ProjMs yet (with the exception of loads whose result is
4815          * not used)
4816          */
4817         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4818                 ir_node *res;
4819
4820                 /* this is needed, because sometimes we have loops that are only
4821                    reachable through the ProjM */
4822                 be_enqueue_preds(node);
4823                 /* do it in 2 steps, to silence firm verifier */
4824                 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4825                 set_Proj_proj(res, pn_ia32_mem);
4826                 return res;
4827         }
4828
4829         /* renumber the proj */
4830         new_pred = be_transform_node(pred);
4831         if (is_ia32_Load(new_pred)) {
4832                 switch (proj) {
4833                 case pn_Load_res:
4834                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4835                 case pn_Load_M:
4836                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4837                 case pn_Load_X_regular:
4838                         return new_rd_Jmp(dbgi, irg, block);
4839                 case pn_Load_X_except:
4840                         /* This Load might raise an exception. Mark it. */
4841                         set_ia32_exc_label(new_pred, 1);
4842                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4843                 default:
4844                         break;
4845                 }
4846         } else if (is_ia32_Conv_I2I(new_pred) ||
4847                    is_ia32_Conv_I2I8Bit(new_pred)) {
4848                 set_irn_mode(new_pred, mode_T);
4849                 if (proj == pn_Load_res) {
4850                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4851                 } else if (proj == pn_Load_M) {
4852                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4853                 }
4854         } else if (is_ia32_xLoad(new_pred)) {
4855                 switch (proj) {
4856                 case pn_Load_res:
4857                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4858                 case pn_Load_M:
4859                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4860                 case pn_Load_X_regular:
4861                         return new_rd_Jmp(dbgi, irg, block);
4862                 case pn_Load_X_except:
4863                         /* This Load might raise an exception. Mark it. */
4864                         set_ia32_exc_label(new_pred, 1);
4865                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4866                 default:
4867                         break;
4868                 }
4869         } else if (is_ia32_vfld(new_pred)) {
4870                 switch (proj) {
4871                 case pn_Load_res:
4872                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4873                 case pn_Load_M:
4874                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4875                 case pn_Load_X_regular:
4876                         return new_rd_Jmp(dbgi, irg, block);
4877                 case pn_Load_X_except:
4878                         /* This Load might raise an exception. Mark it. */
4879                         set_ia32_exc_label(new_pred, 1);
4880                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4881                 default:
4882                         break;
4883                 }
4884         } else {
4885                 /* can happen for ProJMs when source address mode happened for the
4886                    node */
4887
4888                 /* however it should not be the result proj, as that would mean the
4889                    load had multiple users and should not have been used for
4890                    SourceAM */
4891                 if (proj != pn_Load_M) {
4892                         panic("internal error: transformed node not a Load");
4893                 }
4894                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4895         }
4896
4897         assert(0);
4898         return new_rd_Unknown(irg, get_irn_mode(node));
4899 }
4900
4901 /**
4902  * Transform and renumber the Projs from a DivMod like instruction.
4903  */
4904 static ir_node *gen_Proj_DivMod(ir_node *node) {
4905         ir_node  *block    = be_transform_node(get_nodes_block(node));
4906         ir_node  *pred     = get_Proj_pred(node);
4907         ir_node  *new_pred = be_transform_node(pred);
4908         ir_graph *irg      = current_ir_graph;
4909         dbg_info *dbgi     = get_irn_dbg_info(node);
4910         ir_mode  *mode     = get_irn_mode(node);
4911         long     proj      = get_Proj_proj(node);
4912
4913         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4914
4915         switch (get_irn_opcode(pred)) {
4916         case iro_Div:
4917                 switch (proj) {
4918                 case pn_Div_M:
4919                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4920                 case pn_Div_res:
4921                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4922                 case pn_Div_X_regular:
4923                         return new_rd_Jmp(dbgi, irg, block);
4924                 case pn_Div_X_except:
4925                         set_ia32_exc_label(new_pred, 1);
4926                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4927                 default:
4928                         break;
4929                 }
4930                 break;
4931         case iro_Mod:
4932                 switch (proj) {
4933                 case pn_Mod_M:
4934                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4935                 case pn_Mod_res:
4936                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4937                 case pn_Mod_X_except:
4938                         set_ia32_exc_label(new_pred, 1);
4939                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4940                 default:
4941                         break;
4942                 }
4943                 break;
4944         case iro_DivMod:
4945                 switch (proj) {
4946                 case pn_DivMod_M:
4947                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4948                 case pn_DivMod_res_div:
4949                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4950                 case pn_DivMod_res_mod:
4951                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4952                 case pn_DivMod_X_regular:
4953                         return new_rd_Jmp(dbgi, irg, block);
4954                 case pn_DivMod_X_except:
4955                         set_ia32_exc_label(new_pred, 1);
4956                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4957                 default:
4958                         break;
4959                 }
4960                 break;
4961         default:
4962                 break;
4963         }
4964
4965         assert(0);
4966         return new_rd_Unknown(irg, mode);
4967 }
4968
4969 /**
4970  * Transform and renumber the Projs from a CopyB.
4971  */
4972 static ir_node *gen_Proj_CopyB(ir_node *node) {
4973         ir_node  *block    = be_transform_node(get_nodes_block(node));
4974         ir_node  *pred     = get_Proj_pred(node);
4975         ir_node  *new_pred = be_transform_node(pred);
4976         ir_graph *irg      = current_ir_graph;
4977         dbg_info *dbgi     = get_irn_dbg_info(node);
4978         ir_mode  *mode     = get_irn_mode(node);
4979         long     proj      = get_Proj_proj(node);
4980
4981         switch(proj) {
4982         case pn_CopyB_M_regular:
4983                 if (is_ia32_CopyB_i(new_pred)) {
4984                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4985                 } else if (is_ia32_CopyB(new_pred)) {
4986                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4987                 }
4988                 break;
4989         default:
4990                 break;
4991         }
4992
4993         assert(0);
4994         return new_rd_Unknown(irg, mode);
4995 }
4996
4997 /**
4998  * Transform and renumber the Projs from a Quot.
4999  */
5000 static ir_node *gen_Proj_Quot(ir_node *node) {
5001         ir_node  *block    = be_transform_node(get_nodes_block(node));
5002         ir_node  *pred     = get_Proj_pred(node);
5003         ir_node  *new_pred = be_transform_node(pred);
5004         ir_graph *irg      = current_ir_graph;
5005         dbg_info *dbgi     = get_irn_dbg_info(node);
5006         ir_mode  *mode     = get_irn_mode(node);
5007         long     proj      = get_Proj_proj(node);
5008
5009         switch(proj) {
5010         case pn_Quot_M:
5011                 if (is_ia32_xDiv(new_pred)) {
5012                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
5013                 } else if (is_ia32_vfdiv(new_pred)) {
5014                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
5015                 }
5016                 break;
5017         case pn_Quot_res:
5018                 if (is_ia32_xDiv(new_pred)) {
5019                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
5020                 } else if (is_ia32_vfdiv(new_pred)) {
5021                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
5022                 }
5023                 break;
5024         case pn_Quot_X_regular:
5025         case pn_Quot_X_except:
5026         default:
5027                 break;
5028         }
5029
5030         assert(0);
5031         return new_rd_Unknown(irg, mode);
5032 }
5033
5034 /**
5035  * Transform the Thread Local Storage Proj.
5036  */
5037 static ir_node *gen_Proj_tls(ir_node *node) {
5038         ir_node  *block = be_transform_node(get_nodes_block(node));
5039         ir_graph *irg   = current_ir_graph;
5040         dbg_info *dbgi  = NULL;
5041         ir_node  *res   = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
5042
5043         return res;
5044 }
5045
5046 static ir_node *gen_be_Call(ir_node *node) {
5047         ir_node *res = be_duplicate_node(node);
5048         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5049
5050         return res;
5051 }
5052
5053 static ir_node *gen_be_IncSP(ir_node *node) {
5054         ir_node *res = be_duplicate_node(node);
5055         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5056
5057         return res;
5058 }
5059
5060 /**
5061  * Transform the Projs from a be_Call.
5062  */
5063 static ir_node *gen_Proj_be_Call(ir_node *node) {
5064         ir_node  *block       = be_transform_node(get_nodes_block(node));
5065         ir_node  *call        = get_Proj_pred(node);
5066         ir_node  *new_call    = be_transform_node(call);
5067         ir_graph *irg         = current_ir_graph;
5068         dbg_info *dbgi        = get_irn_dbg_info(node);
5069         ir_type  *method_type = be_Call_get_type(call);
5070         int       n_res       = get_method_n_ress(method_type);
5071         long      proj        = get_Proj_proj(node);
5072         ir_mode  *mode        = get_irn_mode(node);
5073         ir_node  *sse_load;
5074         const arch_register_class_t *cls;
5075
5076         /* The following is kinda tricky: If we're using SSE, then we have to
5077          * move the result value of the call in floating point registers to an
5078          * xmm register, we therefore construct a GetST0 -> xLoad sequence
5079          * after the call, we have to make sure to correctly make the
5080          * MemProj and the result Proj use these 2 nodes
5081          */
5082         if (proj == pn_be_Call_M_regular) {
5083                 // get new node for result, are we doing the sse load/store hack?
5084                 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5085                 ir_node *call_res_new;
5086                 ir_node *call_res_pred = NULL;
5087
5088                 if (call_res != NULL) {
5089                         call_res_new  = be_transform_node(call_res);
5090                         call_res_pred = get_Proj_pred(call_res_new);
5091                 }
5092
5093                 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
5094                         return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5095                                            pn_be_Call_M_regular);
5096                 } else {
5097                         assert(is_ia32_xLoad(call_res_pred));
5098                         return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5099                                            pn_ia32_xLoad_M);
5100                 }
5101         }
5102         if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5103                         && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5104                 ir_node *fstp;
5105                 ir_node *frame = get_irg_frame(irg);
5106                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
5107                 //ir_node *p;
5108                 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5109                 ir_node *call_res;
5110
5111                 /* in case there is no memory output: create one to serialize the copy
5112                    FPU -> SSE */
5113                 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5114                                        pn_be_Call_M_regular);
5115                 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5116                                        pn_be_Call_first_res);
5117
5118                 /* store st(0) onto stack */
5119                 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
5120                                         call_res, mode);
5121                 set_ia32_op_type(fstp, ia32_AddrModeD);
5122                 set_ia32_use_frame(fstp);
5123
5124                 /* load into SSE register */
5125                 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5126                                              mode);
5127                 set_ia32_op_type(sse_load, ia32_AddrModeS);
5128                 set_ia32_use_frame(sse_load);
5129
5130                 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5131                                        pn_ia32_xLoad_res);
5132
5133                 return sse_load;
5134         }
5135
5136         /* transform call modes */
5137         if (mode_is_data(mode)) {
5138                 cls  = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5139                 mode = cls->mode;
5140         }
5141
5142         return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5143 }
5144
5145 /**
5146  * Transform the Projs from a Cmp.
5147  */
5148 static ir_node *gen_Proj_Cmp(ir_node *node)
5149 {
5150         /* this probably means not all mode_b nodes were lowered... */
5151         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5152               node);
5153 }
5154
5155 /**
5156  * Transform and potentially renumber Proj nodes.
5157  */
5158 static ir_node *gen_Proj(ir_node *node) {
5159         ir_node  *pred = get_Proj_pred(node);
5160         if (is_Store(pred)) {
5161                 long proj = get_Proj_proj(node);
5162                 if (proj == pn_Store_M) {
5163                         return be_transform_node(pred);
5164                 } else {
5165                         assert(0);
5166                         return new_r_Bad(current_ir_graph);
5167                 }
5168         } else if (is_Load(pred)) {
5169                 return gen_Proj_Load(node);
5170         } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
5171                 return gen_Proj_DivMod(node);
5172         } else if (is_CopyB(pred)) {
5173                 return gen_Proj_CopyB(node);
5174         } else if (is_Quot(pred)) {
5175                 return gen_Proj_Quot(node);
5176         } else if (be_is_SubSP(pred)) {
5177                 return gen_Proj_be_SubSP(node);
5178         } else if (be_is_AddSP(pred)) {
5179                 return gen_Proj_be_AddSP(node);
5180         } else if (be_is_Call(pred)) {
5181                 return gen_Proj_be_Call(node);
5182         } else if (is_Cmp(pred)) {
5183                 return gen_Proj_Cmp(node);
5184         } else if (get_irn_op(pred) == op_Start) {
5185                 long proj = get_Proj_proj(node);
5186                 if (proj == pn_Start_X_initial_exec) {
5187                         ir_node *block = get_nodes_block(pred);
5188                         dbg_info *dbgi = get_irn_dbg_info(node);
5189                         ir_node *jump;
5190
5191                         /* we exchange the ProjX with a jump */
5192                         block = be_transform_node(block);
5193                         jump  = new_rd_Jmp(dbgi, current_ir_graph, block);
5194                         return jump;
5195                 }
5196                 if (node == be_get_old_anchor(anchor_tls)) {
5197                         return gen_Proj_tls(node);
5198                 }
5199         } else if (is_ia32_l_FloattoLL(pred)) {
5200                 return gen_Proj_l_FloattoLL(node);
5201 #ifdef FIRM_EXT_GRS
5202         } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5203 #else
5204         } else {
5205 #endif
5206                 ir_mode *mode = get_irn_mode(node);
5207                 if (mode_needs_gp_reg(mode)) {
5208                         ir_node *new_pred = be_transform_node(pred);
5209                         ir_node *block    = be_transform_node(get_nodes_block(node));
5210                         ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5211                                                        mode_Iu, get_Proj_proj(node));
5212 #ifdef DEBUG_libfirm
5213                         new_proj->node_nr = node->node_nr;
5214 #endif
5215                         return new_proj;
5216                 }
5217         }
5218
5219         return be_duplicate_node(node);
5220 }
5221
5222 /**
5223  * Enters all transform functions into the generic pointer
5224  */
5225 static void register_transformers(void)
5226 {
5227         ir_op *op_Mulh;
5228
5229         /* first clear the generic function pointer for all ops */
5230         clear_irp_opcodes_generic_func();
5231
5232 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5233 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
5234
5235         GEN(Add);
5236         GEN(Sub);
5237         GEN(Mul);
5238         GEN(And);
5239         GEN(Or);
5240         GEN(Eor);
5241
5242         GEN(Shl);
5243         GEN(Shr);
5244         GEN(Shrs);
5245         GEN(Rot);
5246
5247         GEN(Quot);
5248
5249         GEN(Div);
5250         GEN(Mod);
5251         GEN(DivMod);
5252
5253         GEN(Minus);
5254         GEN(Conv);
5255         GEN(Abs);
5256         GEN(Not);
5257
5258         GEN(Load);
5259         GEN(Store);
5260         GEN(Cond);
5261
5262         GEN(Cmp);
5263         GEN(ASM);
5264         GEN(CopyB);
5265         BAD(Mux);
5266         GEN(Psi);
5267         GEN(Proj);
5268         GEN(Phi);
5269         GEN(IJmp);
5270
5271         /* transform ops from intrinsic lowering */
5272         GEN(ia32_l_Add);
5273         GEN(ia32_l_Adc);
5274         GEN(ia32_l_Mul);
5275         GEN(ia32_l_IMul);
5276         GEN(ia32_l_ShlDep);
5277         GEN(ia32_l_ShrDep);
5278         GEN(ia32_l_SarDep);
5279         GEN(ia32_l_ShlD);
5280         GEN(ia32_l_ShrD);
5281         GEN(ia32_l_Sub);
5282         GEN(ia32_l_Sbb);
5283         GEN(ia32_l_vfild);
5284         GEN(ia32_l_Load);
5285         GEN(ia32_l_vfist);
5286         GEN(ia32_l_Store);
5287         GEN(ia32_l_LLtoFloat);
5288         GEN(ia32_l_FloattoLL);
5289
5290         GEN(Const);
5291         GEN(SymConst);
5292         GEN(Unknown);
5293
5294         /* we should never see these nodes */
5295         BAD(Raise);
5296         BAD(Sel);
5297         BAD(InstOf);
5298         BAD(Cast);
5299         BAD(Free);
5300         BAD(Tuple);
5301         BAD(Id);
5302         //BAD(Bad);
5303         BAD(Confirm);
5304         BAD(Filter);
5305         BAD(CallBegin);
5306         BAD(EndReg);
5307         BAD(EndExcept);
5308
5309         /* handle generic backend nodes */
5310         GEN(be_FrameAddr);
5311         GEN(be_Call);
5312         GEN(be_IncSP);
5313         GEN(be_Return);
5314         GEN(be_AddSP);
5315         GEN(be_SubSP);
5316         GEN(be_Copy);
5317
5318         op_Mulh = get_op_Mulh();
5319         if (op_Mulh)
5320                 GEN(Mulh);
5321
5322 #undef GEN
5323 #undef BAD
5324 }
5325
5326 /**
5327  * Pre-transform all unknown and noreg nodes.
5328  */
5329 static void ia32_pretransform_node(void *arch_cg) {
5330         ia32_code_gen_t *cg = arch_cg;
5331
5332         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
5333         cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5334         cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5335         cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
5336         cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
5337         cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
5338         get_fpcw();
5339 }
5340
5341 /**
5342  * Walker, checks if all ia32 nodes producing more than one result have
5343  * its Projs, other wise creates new projs and keep them using a be_Keep node.
5344  */
5345 static void add_missing_keep_walker(ir_node *node, void *data)
5346 {
5347         int              n_outs, i;
5348         unsigned         found_projs = 0;
5349         const ir_edge_t *edge;
5350         ir_mode         *mode = get_irn_mode(node);
5351         ir_node         *last_keep;
5352         (void) data;
5353         if(mode != mode_T)
5354                 return;
5355         if(!is_ia32_irn(node))
5356                 return;
5357
5358         n_outs = get_ia32_n_res(node);
5359         if(n_outs <= 0)
5360                 return;
5361         if(is_ia32_SwitchJmp(node))
5362                 return;
5363
5364         assert(n_outs < (int) sizeof(unsigned) * 8);
5365         foreach_out_edge(node, edge) {
5366                 ir_node *proj = get_edge_src_irn(edge);
5367                 int      pn   = get_Proj_proj(proj);
5368
5369                 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
5370                 found_projs |= 1 << pn;
5371         }
5372
5373
5374         /* are keeps missing? */
5375         last_keep = NULL;
5376         for(i = 0; i < n_outs; ++i) {
5377                 ir_node                     *block;
5378                 ir_node                     *in[1];
5379                 const arch_register_req_t   *req;
5380                 const arch_register_class_t *class;
5381
5382                 if(found_projs & (1 << i)) {
5383                         continue;
5384                 }
5385
5386                 req   = get_ia32_out_req(node, i);
5387                 class = req->cls;
5388                 if(class == NULL) {
5389                         continue;
5390                 }
5391                 if(class == &ia32_reg_classes[CLASS_ia32_flags]) {
5392                         continue;
5393                 }
5394
5395                 block = get_nodes_block(node);
5396                 in[0] = new_r_Proj(current_ir_graph, block, node,
5397                                    arch_register_class_mode(class), i);
5398                 if(last_keep != NULL) {
5399                         be_Keep_add_node(last_keep, class, in[0]);
5400                 } else {
5401                         last_keep = be_new_Keep(class, current_ir_graph, block, 1, in);
5402                         if(sched_is_scheduled(node)) {
5403                                 sched_add_after(node, last_keep);
5404                         }
5405                 }
5406         }
5407 }
5408
5409 /**
5410  * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5411  * and keeps them.
5412  */
5413 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5414 {
5415         ir_graph *irg = be_get_birg_irg(cg->birg);
5416         irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5417 }
5418
5419 /* do the transformation */
5420 void ia32_transform_graph(ia32_code_gen_t *cg) {
5421         int cse_last;
5422         ir_graph *irg = cg->irg;
5423
5424         register_transformers();
5425         env_cg       = cg;
5426         initial_fpcw = NULL;
5427
5428 BE_TIMER_PUSH(t_heights);
5429         heights      = heights_new(irg);
5430 BE_TIMER_POP(t_heights);
5431         ia32_calculate_non_address_mode_nodes(cg->birg);
5432
5433         /* the transform phase is not safe for CSE (yet) because several nodes get
5434          * attributes set after their creation */
5435         cse_last = get_opt_cse();
5436         set_opt_cse(0);
5437
5438         be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5439
5440         set_opt_cse(cse_last);
5441
5442         ia32_free_non_address_mode_nodes();
5443         heights_free(heights);
5444         heights = NULL;
5445 }
5446
5447 void ia32_init_transform(void)
5448 {
5449         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
5450 }