- add a flag to allow 2 users when matching address mode: needed for Psi nodes
[libfirm] / ir / be / ia32 / ia32_transform.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       This file implements the IR transformation from firm into
23  *              ia32-Firm.
24  * @author      Christian Wuerdig, Matthias Braun
25  * @version     $Id$
26  */
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <limits.h>
32
33 #include "irargs_t.h"
34 #include "irnode_t.h"
35 #include "irgraph_t.h"
36 #include "irmode_t.h"
37 #include "iropt_t.h"
38 #include "irop_t.h"
39 #include "irprog_t.h"
40 #include "iredges_t.h"
41 #include "irgmod.h"
42 #include "irvrfy.h"
43 #include "ircons.h"
44 #include "irgwalk.h"
45 #include "irprintf.h"
46 #include "debug.h"
47 #include "irdom.h"
48 #include "archop.h"
49 #include "error.h"
50 #include "height.h"
51
52 #include "../benode_t.h"
53 #include "../besched.h"
54 #include "../beabi.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
58 #include "../be_t.h"
59
60 #include "bearch_ia32_t.h"
61 #include "ia32_nodes_attr.h"
62 #include "ia32_transform.h"
63 #include "ia32_new_nodes.h"
64 #include "ia32_map_regs.h"
65 #include "ia32_dbg_stat.h"
66 #include "ia32_optimize.h"
67 #include "ia32_util.h"
68 #include "ia32_address_mode.h"
69 #include "ia32_architecture.h"
70
71 #include "gen_ia32_regalloc_if.h"
72
73 #define SFP_SIGN   "0x80000000"
74 #define DFP_SIGN   "0x8000000000000000"
75 #define SFP_ABS    "0x7FFFFFFF"
76 #define DFP_ABS    "0x7FFFFFFFFFFFFFFF"
77 #define DFP_INTMAX "9223372036854775807"
78
79 #define TP_SFP_SIGN "ia32_sfp_sign"
80 #define TP_DFP_SIGN "ia32_dfp_sign"
81 #define TP_SFP_ABS  "ia32_sfp_abs"
82 #define TP_DFP_ABS  "ia32_dfp_abs"
83 #define TP_INT_MAX  "ia32_int_max"
84
85 #define ENT_SFP_SIGN "IA32_SFP_SIGN"
86 #define ENT_DFP_SIGN "IA32_DFP_SIGN"
87 #define ENT_SFP_ABS  "IA32_SFP_ABS"
88 #define ENT_DFP_ABS  "IA32_DFP_ABS"
89 #define ENT_INT_MAX  "IA32_INT_MAX"
90
91 #define mode_vfp        (ia32_reg_classes[CLASS_ia32_vfp].mode)
92 #define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)
93
94 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
95
96 /** hold the current code generator during transformation */
97 static ia32_code_gen_t *env_cg       = NULL;
98 static ir_node         *initial_fpcw = NULL;
99 static heights_t       *heights      = NULL;
100
101 extern ir_op *get_op_Mulh(void);
102
103 typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
104         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
105         ir_node *op1, ir_node *op2);
106
107 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_graph *irg,
108         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
109         ir_node *op1, ir_node *op2, ir_node *flags);
110
111 typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
112         ir_node *block, ir_node *op1, ir_node *op2);
113
114 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
115         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
116         ir_node *op);
117
118 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
119         ir_node *block, ir_node *base, ir_node *index, ir_node *mem);
120
121 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
122         ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
123         ir_node *op1, ir_node *op2, ir_node *fpcw);
124
125 typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
126         ir_node *block, ir_node *op);
127
128 static ir_node *try_create_Immediate(ir_node *node,
129                                      char immediate_constraint_type);
130
131 static ir_node *create_immediate_or_transform(ir_node *node,
132                                               char immediate_constraint_type);
133
134 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
135                                 dbg_info *dbgi, ir_node *block,
136                                 ir_node *op, ir_node *orig_node);
137
138 /**
139  * Return true if a mode can be stored in the GP register set
140  */
141 static INLINE int mode_needs_gp_reg(ir_mode *mode) {
142         if(mode == mode_fpcw)
143                 return 0;
144         if(get_mode_size_bits(mode) > 32)
145                 return 0;
146         return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b;
147 }
148
149 /**
150  * creates a unique ident by adding a number to a tag
151  *
152  * @param tag   the tag string, must contain a %d if a number
153  *              should be added
154  */
155 static ident *unique_id(const char *tag)
156 {
157         static unsigned id = 0;
158         char str[256];
159
160         snprintf(str, sizeof(str), tag, ++id);
161         return new_id_from_str(str);
162 }
163
164 /**
165  * Get a primitive type for a mode.
166  */
167 static ir_type *get_prim_type(pmap *types, ir_mode *mode)
168 {
169         pmap_entry *e = pmap_find(types, mode);
170         ir_type *res;
171
172         if (! e) {
173                 char buf[64];
174                 snprintf(buf, sizeof(buf), "prim_type_%s", get_mode_name(mode));
175                 res = new_type_primitive(new_id_from_str(buf), mode);
176                 set_type_alignment_bytes(res, 16);
177                 pmap_insert(types, mode, res);
178         }
179         else
180                 res = e->value;
181         return res;
182 }
183
184 /**
185  * Creates an immediate.
186  *
187  * @param symconst       if set, create a SymConst immediate
188  * @param symconst_sign  sign for the symconst
189  * @param val            integer value for the immediate
190  */
191 static ir_node *create_Immediate(ir_entity *symconst, int symconst_sign, long val)
192 {
193         ir_graph *irg         = current_ir_graph;
194         ir_node  *start_block = get_irg_start_block(irg);
195         ir_node  *immediate   = new_rd_ia32_Immediate(NULL, irg, start_block,
196                                                       symconst, symconst_sign, val);
197         arch_set_irn_register(env_cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]);
198
199         return immediate;
200 }
201
202 /**
203  * Get an atomic entity that is initialized with a tarval forming
204  * a given constant.
205  *
206  * @param cnst             the node representing the constant
207  */
208 static ir_entity *create_float_const_entity(ir_node *cnst)
209 {
210         ia32_isa_t *isa = env_cg->isa;
211         tarval *key     = get_Const_tarval(cnst);
212         pmap_entry *e   = pmap_find(isa->tv_ent, key);
213         ir_entity *res;
214         ir_graph *rem;
215
216         if (e == NULL) {
217                 tarval  *tv   = key;
218                 ir_mode *mode = get_tarval_mode(tv);
219                 ir_type *tp;
220
221                 if (! ia32_cg_config.use_sse2) {
222                         /* try to reduce the mode to produce smaller sized entities */
223                         if (mode != mode_F) {
224                                 if (tarval_ieee754_can_conv_lossless(tv, mode_F)) {
225                                         mode = mode_F;
226                                         tv = tarval_convert_to(tv, mode);
227                                 } else if (mode != mode_D) {
228                                         if (tarval_ieee754_can_conv_lossless(tv, mode_D)) {
229                                                 mode = mode_D;
230                                                 tv = tarval_convert_to(tv, mode);
231                                         }
232                                 }
233                         }
234                 }
235
236                 if (mode == get_irn_mode(cnst)) {
237                         /* mode was not changed */
238                         tp = get_Const_type(cnst);
239                         if (tp == firm_unknown_type)
240                                 tp = get_prim_type(isa->types, mode);
241                 } else
242                         tp = get_prim_type(isa->types, mode);
243
244                 res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);
245
246                 set_entity_ld_ident(res, get_entity_ident(res));
247                 set_entity_visibility(res, visibility_local);
248                 set_entity_variability(res, variability_constant);
249                 set_entity_allocation(res, allocation_static);
250
251                  /* we create a new entity here: It's initialization must resist on the
252                     const code irg */
253                 rem = current_ir_graph;
254                 current_ir_graph = get_const_code_irg();
255                 set_atomic_ent_value(res, new_Const_type(tv, tp));
256                 current_ir_graph = rem;
257
258                 pmap_insert(isa->tv_ent, key, res);
259         } else {
260                 res = e->value;
261         }
262
263         return res;
264 }
265
266 static int is_Const_0(ir_node *node) {
267         return is_Const(node) && is_Const_null(node);
268 }
269
270 static int is_Const_1(ir_node *node) {
271         return is_Const(node) && is_Const_one(node);
272 }
273
274 static int is_Const_Minus_1(ir_node *node) {
275         return is_Const(node) && is_Const_all_one(node);
276 }
277
278 /**
279  * returns true if constant can be created with a simple float command
280  */
281 static int is_simple_x87_Const(ir_node *node)
282 {
283         tarval *tv = get_Const_tarval(node);
284         if (tarval_is_null(tv) || tarval_is_one(tv))
285                 return 1;
286
287         /* TODO: match all the other float constants */
288         return 0;
289 }
290
291 /**
292  * returns true if constant can be created with a simple float command
293  */
294 static int is_simple_sse_Const(ir_node *node)
295 {
296         tarval  *tv   = get_Const_tarval(node);
297         ir_mode *mode = get_tarval_mode(tv);
298
299         if (mode == mode_F)
300                 return 1;
301
302         if (tarval_is_null(tv) || tarval_is_one(tv))
303                 return 1;
304
305         if (mode == mode_D) {
306                 unsigned val = get_tarval_sub_bits(tv, 0) |
307                         (get_tarval_sub_bits(tv, 1) << 8) |
308                         (get_tarval_sub_bits(tv, 2) << 16) |
309                         (get_tarval_sub_bits(tv, 3) << 24);
310                 if (val == 0)
311                         /* lower 32bit are zero, really a 32bit constant */
312                         return 1;
313         }
314
315         /* TODO: match all the other float constants */
316         return 0;
317 }
318
319 /**
320  * Transforms a Const.
321  */
322 static ir_node *gen_Const(ir_node *node) {
323         ir_graph        *irg   = current_ir_graph;
324         ir_node         *old_block = get_nodes_block(node);
325         ir_node         *block = be_transform_node(old_block);
326         dbg_info        *dbgi  = get_irn_dbg_info(node);
327         ir_mode         *mode  = get_irn_mode(node);
328
329         assert(is_Const(node));
330
331         if (mode_is_float(mode)) {
332                 ir_node   *res   = NULL;
333                 ir_node   *noreg = ia32_new_NoReg_gp(env_cg);
334                 ir_node   *nomem = new_NoMem();
335                 ir_node   *load;
336                 ir_entity *floatent;
337
338                 if (ia32_cg_config.use_sse2) {
339                         tarval *tv = get_Const_tarval(node);
340                         if (tarval_is_null(tv)) {
341                                 load = new_rd_ia32_xZero(dbgi, irg, block);
342                                 set_ia32_ls_mode(load, mode);
343                                 res  = load;
344                         } else if (tarval_is_one(tv)) {
345                                 int     cnst  = mode == mode_F ? 26 : 55;
346                                 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
347                                 ir_node *imm2 = create_Immediate(NULL, 0, 2);
348                                 ir_node *pslld, *psrld;
349
350                                 load = new_rd_ia32_xAllOnes(dbgi, irg, block);
351                                 set_ia32_ls_mode(load, mode);
352                                 pslld = new_rd_ia32_xPslld(dbgi, irg, block, load, imm1);
353                                 set_ia32_ls_mode(pslld, mode);
354                                 psrld = new_rd_ia32_xPsrld(dbgi, irg, block, pslld, imm2);
355                                 set_ia32_ls_mode(psrld, mode);
356                                 res = psrld;
357                         } else if (mode == mode_F) {
358                                 /* we can place any 32bit constant by using a movd gp, sse */
359                                 unsigned val = get_tarval_sub_bits(tv, 0) |
360                                                (get_tarval_sub_bits(tv, 1) << 8) |
361                                                (get_tarval_sub_bits(tv, 2) << 16) |
362                                                (get_tarval_sub_bits(tv, 3) << 24);
363                                 ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
364                                 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
365                                 set_ia32_ls_mode(load, mode);
366                                 res = load;
367                         } else {
368                                 if (mode == mode_D) {
369                                         unsigned val = get_tarval_sub_bits(tv, 0) |
370                                                 (get_tarval_sub_bits(tv, 1) << 8) |
371                                                 (get_tarval_sub_bits(tv, 2) << 16) |
372                                                 (get_tarval_sub_bits(tv, 3) << 24);
373                                         if (val == 0) {
374                                                 ir_node *imm32 = create_Immediate(NULL, 0, 32);
375                                                 ir_node *cnst, *psllq;
376
377                                                 /* fine, lower 32bit are zero, produce 32bit value */
378                                                 val = get_tarval_sub_bits(tv, 4) |
379                                                         (get_tarval_sub_bits(tv, 5) << 8) |
380                                                         (get_tarval_sub_bits(tv, 6) << 16) |
381                                                         (get_tarval_sub_bits(tv, 7) << 24);
382                                                 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
383                                                 load = new_rd_ia32_xMovd(dbgi, irg, block, cnst);
384                                                 set_ia32_ls_mode(load, mode);
385                                                 psllq = new_rd_ia32_xPsllq(dbgi, irg, block, load, imm32);
386                                                 set_ia32_ls_mode(psllq, mode);
387                                                 res = psllq;
388                                                 goto end;
389                                         }
390                                 }
391                                 floatent = create_float_const_entity(node);
392
393                                 load     = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
394                                                              mode);
395                                 set_ia32_op_type(load, ia32_AddrModeS);
396                                 set_ia32_am_sc(load, floatent);
397                                 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
398                                 res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
399                         }
400                 } else {
401                         if (is_Const_null(node)) {
402                                 load = new_rd_ia32_vfldz(dbgi, irg, block);
403                                 res  = load;
404                                 set_ia32_ls_mode(load, mode);
405                         } else if (is_Const_one(node)) {
406                                 load = new_rd_ia32_vfld1(dbgi, irg, block);
407                                 res  = load;
408                                 set_ia32_ls_mode(load, mode);
409                         } else {
410                                 floatent = create_float_const_entity(node);
411
412                                 load     = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
413                                 set_ia32_op_type(load, ia32_AddrModeS);
414                                 set_ia32_am_sc(load, floatent);
415                                 set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
416                                 res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
417                                 /* take the mode from the entity */
418                                 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
419                         }
420                 }
421 end:
422                 /* Const Nodes before the initial IncSP are a bad idea, because
423                  * they could be spilled and we have no SP ready at that point yet.
424                  * So add a dependency to the initial frame pointer calculation to
425                  * avoid that situation.
426                  */
427                 if (get_irg_start_block(irg) == block) {
428                         add_irn_dep(load, get_irg_frame(irg));
429                 }
430
431                 SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
432                 return res;
433         } else { /* non-float mode */
434                 ir_node *cnst;
435                 tarval  *tv = get_Const_tarval(node);
436                 long     val;
437
438                 tv = tarval_convert_to(tv, mode_Iu);
439
440                 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
441                     tv == NULL) {
442                         panic("couldn't convert constant tarval (%+F)", node);
443                 }
444                 val = get_tarval_long(tv);
445
446                 cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
447                 SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
448
449                 /* see above */
450                 if (get_irg_start_block(irg) == block) {
451                         add_irn_dep(cnst, get_irg_frame(irg));
452                 }
453
454                 return cnst;
455         }
456 }
457
458 /**
459  * Transforms a SymConst.
460  */
461 static ir_node *gen_SymConst(ir_node *node) {
462         ir_graph *irg   = current_ir_graph;
463         ir_node  *old_block = get_nodes_block(node);
464         ir_node  *block = be_transform_node(old_block);
465         dbg_info *dbgi  = get_irn_dbg_info(node);
466         ir_mode  *mode  = get_irn_mode(node);
467         ir_node  *cnst;
468
469         if (mode_is_float(mode)) {
470                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
471                 ir_node *nomem = new_NoMem();
472
473                 if (ia32_cg_config.use_sse2)
474                         cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
475                 else
476                         cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
477                 set_ia32_am_sc(cnst, get_SymConst_entity(node));
478                 set_ia32_use_frame(cnst);
479         } else {
480                 ir_entity *entity;
481
482                 if(get_SymConst_kind(node) != symconst_addr_ent) {
483                         panic("backend only support symconst_addr_ent (at %+F)", node);
484                 }
485                 entity = get_SymConst_entity(node);
486                 cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
487         }
488
489         /* Const Nodes before the initial IncSP are a bad idea, because
490          * they could be spilled and we have no SP ready at that point yet
491          */
492         if (get_irg_start_block(irg) == block) {
493                 add_irn_dep(cnst, get_irg_frame(irg));
494         }
495
496         SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
497
498         return cnst;
499 }
500
501 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
502 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
503         static const struct {
504                 const char *tp_name;
505                 const char *ent_name;
506                 const char *cnst_str;
507                 char mode;
508                 char align;
509         } names [ia32_known_const_max] = {
510                 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN,   0, 16 },       /* ia32_SSIGN */
511                 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN,   1, 16 },       /* ia32_DSIGN */
512                 { TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS,    0, 16 },       /* ia32_SABS */
513                 { TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS,    1, 16 },       /* ia32_DABS */
514                 { TP_INT_MAX,  ENT_INT_MAX,  DFP_INTMAX, 2, 4 }         /* ia32_INTMAX */
515         };
516         static ir_entity *ent_cache[ia32_known_const_max];
517
518         const char    *tp_name, *ent_name, *cnst_str;
519         ir_type       *tp;
520         ir_node       *cnst;
521         ir_graph      *rem;
522         ir_entity     *ent;
523         tarval        *tv;
524         ir_mode       *mode;
525
526         ent_name = names[kct].ent_name;
527         if (! ent_cache[kct]) {
528                 tp_name  = names[kct].tp_name;
529                 cnst_str = names[kct].cnst_str;
530
531                 switch (names[kct].mode) {
532                 case 0:  mode = mode_Iu; break;
533                 case 1:  mode = mode_Lu; break;
534                 default: mode = mode_F; break;
535                 }
536                 tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
537                 tp  = new_type_primitive(new_id_from_str(tp_name), mode);
538                 /* set the specified alignment */
539                 set_type_alignment_bytes(tp, names[kct].align);
540
541                 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
542
543                 set_entity_ld_ident(ent, get_entity_ident(ent));
544                 set_entity_visibility(ent, visibility_local);
545                 set_entity_variability(ent, variability_constant);
546                 set_entity_allocation(ent, allocation_static);
547
548                 /* we create a new entity here: It's initialization must resist on the
549                     const code irg */
550                 rem = current_ir_graph;
551                 current_ir_graph = get_const_code_irg();
552                 cnst = new_Const(mode, tv);
553                 current_ir_graph = rem;
554
555                 set_atomic_ent_value(ent, cnst);
556
557                 /* cache the entry */
558                 ent_cache[kct] = ent;
559         }
560
561         return ent_cache[kct];
562 }
563
564 #ifndef NDEBUG
565 /**
566  * Prints the old node name on cg obst and returns a pointer to it.
567  */
568 const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
569         ia32_isa_t *isa = (ia32_isa_t *)cg->arch_env->isa;
570
571         lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
572         obstack_1grow(isa->name_obst, 0);
573         return obstack_finish(isa->name_obst);
574 }
575 #endif /* NDEBUG */
576
577 /**
578  * return true if the node is a Proj(Load) and could be used in source address
579  * mode for another node. Will return only true if the @p other node is not
580  * dependent on the memory of the Load (for binary operations use the other
581  * input here, for unary operations use NULL).
582  */
583 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
584                                         ir_node *other, ir_node *other2, 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 #if 0
764 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
765 {
766         ir_mode  *mode = get_irn_mode(node);
767         ir_node  *block;
768         ir_mode  *tgt_mode;
769         dbg_info *dbgi;
770
771         if(mode_is_signed(mode)) {
772                 tgt_mode = mode_Is;
773         } else {
774                 tgt_mode = mode_Iu;
775         }
776         block = get_nodes_block(node);
777         dbgi  = get_irn_dbg_info(node);
778
779         return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
780 }
781 #endif
782
783 /**
784  * matches operands of a node into ia32 addressing/operand modes. This covers
785  * usage of source address mode, immediates, operations with non 32-bit modes,
786  * ...
787  * The resulting data is filled into the @p am struct. block is the block
788  * of the node whose arguments are matched. op1, op2 are the first and second
789  * input that are matched (op1 may be NULL). other_op is another unrelated
790  * input that is not matched! but which is needed sometimes to check if AM
791  * for op1/op2 is legal.
792  * @p flags describes the supported modes of the operation in detail.
793  */
794 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
795                             ir_node *op1, ir_node *op2, ir_node *other_op,
796                             match_flags_t flags)
797 {
798         ia32_address_t *addr      = &am->addr;
799         ir_mode        *mode      = get_irn_mode(op2);
800         int             mode_bits = get_mode_size_bits(mode);
801         ir_node        *noreg_gp, *new_op1, *new_op2;
802         int             use_am;
803         unsigned        commutative;
804         int             use_am_and_immediates;
805         int             use_immediate;
806
807         memset(am, 0, sizeof(am[0]));
808
809         commutative           = (flags & match_commutative) != 0;
810         use_am_and_immediates = (flags & match_am_and_immediates) != 0;
811         use_am                = (flags & match_am) != 0;
812         use_immediate         = (flags & match_immediate) != 0;
813         assert(!use_am_and_immediates || use_immediate);
814
815         assert(op2 != NULL);
816         assert(!commutative || op1 != NULL);
817         assert(use_am || !(flags & match_8bit_am));
818         assert(use_am || !(flags & match_16bit_am));
819
820         if (mode_bits == 8) {
821                 if (!(flags & match_8bit_am))
822                         use_am = 0;
823                 /* we don't automatically add upconvs yet */
824                 assert((flags & match_mode_neutral) || (flags & match_8bit));
825         } else if (mode_bits == 16) {
826                 if (!(flags & match_16bit_am))
827                         use_am = 0;
828                 /* we don't automatically add upconvs yet */
829                 assert((flags & match_mode_neutral) || (flags & match_16bit));
830         }
831
832         /* we can simply skip downconvs for mode neutral nodes: the upper bits
833          * can be random for these operations */
834         if (flags & match_mode_neutral) {
835                 op2 = ia32_skip_downconv(op2);
836                 if (op1 != NULL) {
837                         op1 = ia32_skip_downconv(op1);
838                 }
839         }
840
841         /* match immediates. firm nodes are normalized: constants are always on the
842          * op2 input */
843         new_op2 = NULL;
844         if (!(flags & match_try_am) && use_immediate) {
845                 new_op2 = try_create_Immediate(op2, 0);
846         }
847
848         noreg_gp = ia32_new_NoReg_gp(env_cg);
849         if (new_op2 == NULL &&
850             use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
851                 build_address(am, op2);
852                 new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
853                 if (mode_is_float(mode)) {
854                         new_op2 = ia32_new_NoReg_vfp(env_cg);
855                 } else {
856                         new_op2 = noreg_gp;
857                 }
858                 am->op_type = ia32_AddrModeS;
859         } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
860                        use_am &&
861                        ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
862                 ir_node *noreg;
863                 build_address(am, op1);
864
865                 if (mode_is_float(mode)) {
866                         noreg = ia32_new_NoReg_vfp(env_cg);
867                 } else {
868                         noreg = noreg_gp;
869                 }
870
871                 if (new_op2 != NULL) {
872                         new_op1 = noreg;
873                 } else {
874                         new_op1 = be_transform_node(op2);
875                         new_op2 = noreg;
876                         am->ins_permuted = 1;
877                 }
878                 am->op_type = ia32_AddrModeS;
879         } else {
880                 if (flags & match_try_am) {
881                         am->new_op1 = NULL;
882                         am->new_op2 = NULL;
883                         am->op_type = ia32_Normal;
884                         return;
885                 }
886
887                 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
888                 if (new_op2 == NULL)
889                         new_op2 = be_transform_node(op2);
890                 am->op_type = ia32_Normal;
891                 am->ls_mode = get_irn_mode(op2);
892                 if (flags & match_mode_neutral)
893                         am->ls_mode = mode_Iu;
894         }
895         if (addr->base == NULL)
896                 addr->base = noreg_gp;
897         if (addr->index == NULL)
898                 addr->index = noreg_gp;
899         if (addr->mem == NULL)
900                 addr->mem = new_NoMem();
901
902         am->new_op1     = new_op1;
903         am->new_op2     = new_op2;
904         am->commutative = commutative;
905 }
906
907 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
908 {
909         ir_mode  *mode;
910         ir_node  *load;
911
912         if (am->mem_proj == NULL)
913                 return node;
914
915         /* we have to create a mode_T so the old MemProj can attach to us */
916         mode = get_irn_mode(node);
917         load = get_Proj_pred(am->mem_proj);
918
919         mark_irn_visited(load);
920         be_set_transformed_node(load, node);
921
922         if (mode != mode_T) {
923                 set_irn_mode(node, mode_T);
924                 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
925         } else {
926                 return node;
927         }
928 }
929
930 /**
931  * Construct a standard binary operation, set AM and immediate if required.
932  *
933  * @param node  The original node for which the binop is created
934  * @param op1   The first operand
935  * @param op2   The second operand
936  * @param func  The node constructor function
937  * @return The constructed ia32 node.
938  */
939 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
940                           construct_binop_func *func, match_flags_t flags)
941 {
942         dbg_info            *dbgi;
943         ir_node             *block, *new_block, *new_node;
944         ia32_address_mode_t  am;
945         ia32_address_t      *addr = &am.addr;
946
947         block = get_nodes_block(node);
948         match_arguments(&am, block, op1, op2, NULL, flags);
949
950         dbgi      = get_irn_dbg_info(node);
951         new_block = be_transform_node(block);
952         new_node  = func(dbgi, current_ir_graph, new_block,
953                          addr->base, addr->index, addr->mem,
954                          am.new_op1, am.new_op2);
955         set_am_attributes(new_node, &am);
956         /* we can't use source address mode anymore when using immediates */
957         if (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
958                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
959         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
960
961         new_node = fix_mem_proj(new_node, &am);
962
963         return new_node;
964 }
965
966 enum {
967         n_ia32_l_binop_left,
968         n_ia32_l_binop_right,
969         n_ia32_l_binop_eflags
970 };
971 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Adc_left,       n_Adc_left)
972 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Adc_right,      n_Adc_right)
973 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags,     n_Adc_eflags)
974 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Sbb_minuend,    n_Sbb_minuend)
975 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
976 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags,     n_Sbb_eflags)
977
978 /**
979  * Construct a binary operation which also consumes the eflags.
980  *
981  * @param node  The node to transform
982  * @param func  The node constructor function
983  * @param flags The match flags
984  * @return      The constructor ia32 node
985  */
986 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
987                                 match_flags_t flags)
988 {
989         ir_node             *src_block  = get_nodes_block(node);
990         ir_node             *op1        = get_irn_n(node, n_ia32_l_binop_left);
991         ir_node             *op2        = get_irn_n(node, n_ia32_l_binop_right);
992         dbg_info            *dbgi;
993         ir_node             *block, *new_node, *eflags, *new_eflags;
994         ia32_address_mode_t  am;
995         ia32_address_t      *addr       = &am.addr;
996
997         match_arguments(&am, src_block, op1, op2, NULL, flags);
998
999         dbgi       = get_irn_dbg_info(node);
1000         block      = be_transform_node(src_block);
1001         eflags     = get_irn_n(node, n_ia32_l_binop_eflags);
1002         new_eflags = be_transform_node(eflags);
1003         new_node   = func(dbgi, current_ir_graph, block, addr->base, addr->index,
1004                         addr->mem, am.new_op1, am.new_op2, new_eflags);
1005         set_am_attributes(new_node, &am);
1006         /* we can't use source address mode anymore when using immediates */
1007         if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
1008                 set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
1009         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1010
1011         new_node = fix_mem_proj(new_node, &am);
1012
1013         return new_node;
1014 }
1015
1016 static ir_node *get_fpcw(void)
1017 {
1018         ir_node *fpcw;
1019         if (initial_fpcw != NULL)
1020                 return initial_fpcw;
1021
1022         fpcw         = be_abi_get_ignore_irn(env_cg->birg->abi,
1023                                              &ia32_fp_cw_regs[REG_FPCW]);
1024         initial_fpcw = be_transform_node(fpcw);
1025
1026         return initial_fpcw;
1027 }
1028
1029 /**
1030  * Construct a standard binary operation, set AM and immediate if required.
1031  *
1032  * @param op1   The first operand
1033  * @param op2   The second operand
1034  * @param func  The node constructor function
1035  * @return The constructed ia32 node.
1036  */
1037 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
1038                                     construct_binop_float_func *func,
1039                                     match_flags_t flags)
1040 {
1041         ir_mode             *mode  = get_irn_mode(node);
1042         dbg_info            *dbgi;
1043         ir_node             *block, *new_block, *new_node;
1044         ia32_address_mode_t  am;
1045         ia32_address_t      *addr = &am.addr;
1046
1047         /* cannot use address mode with long double on x87 */
1048         if (get_mode_size_bits(mode) > 64)
1049                 flags &= ~match_am;
1050
1051         block = get_nodes_block(node);
1052         match_arguments(&am, block, op1, op2, NULL, flags);
1053
1054         dbgi      = get_irn_dbg_info(node);
1055         new_block = be_transform_node(block);
1056         new_node  = func(dbgi, current_ir_graph, new_block,
1057                          addr->base, addr->index, addr->mem,
1058                          am.new_op1, am.new_op2, get_fpcw());
1059         set_am_attributes(new_node, &am);
1060
1061         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
1062
1063         new_node = fix_mem_proj(new_node, &am);
1064
1065         return new_node;
1066 }
1067
1068 /**
1069  * Construct a shift/rotate binary operation, sets AM and immediate if required.
1070  *
1071  * @param op1   The first operand
1072  * @param op2   The second operand
1073  * @param func  The node constructor function
1074  * @return The constructed ia32 node.
1075  */
1076 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
1077                                 construct_shift_func *func,
1078                                 match_flags_t flags)
1079 {
1080         dbg_info *dbgi;
1081         ir_node  *block, *new_block, *new_op1, *new_op2, *new_node;
1082
1083         assert(! mode_is_float(get_irn_mode(node)));
1084         assert(flags & match_immediate);
1085         assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
1086
1087         if (flags & match_mode_neutral) {
1088                 op1 = ia32_skip_downconv(op1);
1089         } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
1090                 panic("right shifting of non-32bit values not supported, yet");
1091         }
1092         new_op1 = be_transform_node(op1);
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                 /* convs (and strict-convs) before stores are unnecessary if the mode
2517                    is the same */
2518                 while (is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2519                         val = get_Conv_op(val);
2520                 }
2521                 new_val = be_transform_node(val);
2522                 if (ia32_cg_config.use_sse2) {
2523                         new_node = new_rd_ia32_xStore(dbgi, irg, new_block, addr.base,
2524                                                       addr.index, addr.mem, new_val);
2525                 } else {
2526                         new_node = new_rd_ia32_vfst(dbgi, irg, new_block, addr.base,
2527                                                     addr.index, addr.mem, new_val, mode);
2528                 }
2529                 store = new_node;
2530         } else if (is_float_to_int32_conv(val)) {
2531                 val = get_Conv_op(val);
2532
2533                 /* convs (and strict-convs) before stores are unnecessary if the mode
2534                    is the same */
2535                 while(is_Conv(val) && mode == get_irn_mode(get_Conv_op(val))) {
2536                         val = get_Conv_op(val);
2537                 }
2538                 new_val  = be_transform_node(val);
2539                 new_node = gen_vfist(dbgi, irg, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2540         } else {
2541                 new_val = create_immediate_or_transform(val, 0);
2542                 assert(mode != mode_b);
2543
2544                 if (get_mode_size_bits(mode) == 8) {
2545                         new_node = new_rd_ia32_Store8Bit(dbgi, irg, new_block, addr.base,
2546                                                          addr.index, addr.mem, new_val);
2547                 } else {
2548                         new_node = new_rd_ia32_Store(dbgi, irg, new_block, addr.base,
2549                                                      addr.index, addr.mem, new_val);
2550                 }
2551                 store = new_node;
2552         }
2553
2554         set_irn_pinned(store, get_irn_pinned(node));
2555         set_ia32_op_type(store, ia32_AddrModeD);
2556         set_ia32_ls_mode(store, mode);
2557
2558         set_address(store, &addr);
2559         SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
2560
2561         return new_node;
2562 }
2563
2564 /**
2565  * Transforms a Store.
2566  *
2567  * @return the created ia32 Store node
2568  */
2569 static ir_node *gen_Store(ir_node *node)
2570 {
2571         ir_node  *val  = get_Store_value(node);
2572         ir_mode  *mode = get_irn_mode(val);
2573
2574         if (mode_is_float(mode) && is_Const(val)) {
2575                 int transform = 1;
2576
2577                 /* we are storing a floating point constant */
2578                 if (ia32_cg_config.use_sse2) {
2579                         transform = !is_simple_sse_Const(val);
2580                 } else {
2581                         transform = !is_simple_x87_Const(val);
2582                 }
2583                 if (transform)
2584                         return gen_float_const_Store(node, val);
2585         }
2586         return gen_normal_Store(node);
2587 }
2588
2589 /**
2590  * Transforms a Switch.
2591  *
2592  * @return the created ia32 SwitchJmp node
2593  */
2594 static ir_node *create_Switch(ir_node *node)
2595 {
2596         ir_graph *irg        = current_ir_graph;
2597         dbg_info *dbgi       = get_irn_dbg_info(node);
2598         ir_node  *block      = be_transform_node(get_nodes_block(node));
2599         ir_node  *sel        = get_Cond_selector(node);
2600         ir_node  *new_sel    = be_transform_node(sel);
2601         int       switch_min = INT_MAX;
2602         int       switch_max = INT_MIN;
2603         long      default_pn = get_Cond_defaultProj(node);
2604         ir_node  *new_node;
2605         const ir_edge_t *edge;
2606
2607         assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2608
2609         /* determine the smallest switch case value */
2610         foreach_out_edge(node, edge) {
2611                 ir_node *proj = get_edge_src_irn(edge);
2612                 long     pn   = get_Proj_proj(proj);
2613                 if(pn == default_pn)
2614                         continue;
2615
2616                 if(pn < switch_min)
2617                         switch_min = pn;
2618                 if(pn > switch_max)
2619                         switch_max = pn;
2620         }
2621
2622         if((unsigned) (switch_max - switch_min) > 256000) {
2623                 panic("Size of switch %+F bigger than 256000", node);
2624         }
2625
2626         if (switch_min != 0) {
2627                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2628
2629                 /* if smallest switch case is not 0 we need an additional sub */
2630                 new_sel = new_rd_ia32_Lea(dbgi, irg, block, new_sel, noreg);
2631                 add_ia32_am_offs_int(new_sel, -switch_min);
2632                 set_ia32_op_type(new_sel, ia32_AddrModeS);
2633
2634                 SET_IA32_ORIG_NODE(new_sel, ia32_get_old_node_name(env_cg, node));
2635         }
2636
2637         new_node = new_rd_ia32_SwitchJmp(dbgi, irg, block, new_sel, default_pn);
2638         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2639
2640         return new_node;
2641 }
2642
2643 /**
2644  * Transform a Cond node.
2645  */
2646 static ir_node *gen_Cond(ir_node *node) {
2647         ir_node  *block     = get_nodes_block(node);
2648         ir_node  *new_block = be_transform_node(block);
2649         ir_graph *irg       = current_ir_graph;
2650         dbg_info *dbgi      = get_irn_dbg_info(node);
2651         ir_node  *sel       = get_Cond_selector(node);
2652         ir_mode  *sel_mode  = get_irn_mode(sel);
2653         ir_node  *flags     = NULL;
2654         ir_node  *new_node;
2655         pn_Cmp    pnc;
2656
2657         if (sel_mode != mode_b) {
2658                 return create_Switch(node);
2659         }
2660
2661         /* we get flags from a Cmp */
2662         flags = get_flags_node(sel, &pnc);
2663
2664         new_node = new_rd_ia32_Jcc(dbgi, irg, new_block, flags, pnc);
2665         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2666
2667         return new_node;
2668 }
2669
2670 /**
2671  * Transforms a CopyB node.
2672  *
2673  * @return The transformed node.
2674  */
2675 static ir_node *gen_CopyB(ir_node *node) {
2676         ir_node  *block    = be_transform_node(get_nodes_block(node));
2677         ir_node  *src      = get_CopyB_src(node);
2678         ir_node  *new_src  = be_transform_node(src);
2679         ir_node  *dst      = get_CopyB_dst(node);
2680         ir_node  *new_dst  = be_transform_node(dst);
2681         ir_node  *mem      = get_CopyB_mem(node);
2682         ir_node  *new_mem  = be_transform_node(mem);
2683         ir_node  *res      = NULL;
2684         ir_graph *irg      = current_ir_graph;
2685         dbg_info *dbgi     = get_irn_dbg_info(node);
2686         int      size      = get_type_size_bytes(get_CopyB_type(node));
2687         int      rem;
2688
2689         /* If we have to copy more than 32 bytes, we use REP MOVSx and */
2690         /* then we need the size explicitly in ECX.                    */
2691         if (size >= 32 * 4) {
2692                 rem = size & 0x3; /* size % 4 */
2693                 size >>= 2;
2694
2695                 res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
2696                 add_irn_dep(res, get_irg_frame(irg));
2697
2698                 res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
2699         } else {
2700                 if(size == 0) {
2701                         ir_fprintf(stderr, "Optimisation warning copyb %+F with size <4\n",
2702                                    node);
2703                 }
2704                 res = new_rd_ia32_CopyB_i(dbgi, irg, block, new_dst, new_src, new_mem, size);
2705         }
2706
2707         SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
2708
2709         return res;
2710 }
2711
2712 static ir_node *gen_be_Copy(ir_node *node)
2713 {
2714         ir_node *new_node = be_duplicate_node(node);
2715         ir_mode *mode     = get_irn_mode(new_node);
2716
2717         if (mode_needs_gp_reg(mode)) {
2718                 set_irn_mode(new_node, mode_Iu);
2719         }
2720
2721         return new_node;
2722 }
2723
2724 static ir_node *create_Fucom(ir_node *node)
2725 {
2726         ir_graph *irg       = current_ir_graph;
2727         dbg_info *dbgi      = get_irn_dbg_info(node);
2728         ir_node  *block     = get_nodes_block(node);
2729         ir_node  *new_block = be_transform_node(block);
2730         ir_node  *left      = get_Cmp_left(node);
2731         ir_node  *new_left  = be_transform_node(left);
2732         ir_node  *right     = get_Cmp_right(node);
2733         ir_node  *new_right;
2734         ir_node  *new_node;
2735
2736         if(ia32_cg_config.use_fucomi) {
2737                 new_right = be_transform_node(right);
2738                 new_node  = new_rd_ia32_vFucomi(dbgi, irg, new_block, new_left,
2739                                                 new_right, 0);
2740                 set_ia32_commutative(new_node);
2741                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2742         } else {
2743                 if(ia32_cg_config.use_ftst && is_Const_0(right)) {
2744                         new_node = new_rd_ia32_vFtstFnstsw(dbgi, irg, new_block, new_left,
2745                                                            0);
2746                 } else {
2747                         new_right = be_transform_node(right);
2748                         new_node  = new_rd_ia32_vFucomFnstsw(dbgi, irg, new_block, new_left,
2749                                                                                                  new_right, 0);
2750                 }
2751
2752                 set_ia32_commutative(new_node);
2753
2754                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2755
2756                 new_node = new_rd_ia32_Sahf(dbgi, irg, new_block, new_node);
2757                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2758         }
2759
2760         return new_node;
2761 }
2762
2763 static ir_node *create_Ucomi(ir_node *node)
2764 {
2765         ir_graph *irg       = current_ir_graph;
2766         dbg_info *dbgi      = get_irn_dbg_info(node);
2767         ir_node  *src_block = get_nodes_block(node);
2768         ir_node  *new_block = be_transform_node(src_block);
2769         ir_node  *left      = get_Cmp_left(node);
2770         ir_node  *right     = get_Cmp_right(node);
2771         ir_node  *new_node;
2772         ia32_address_mode_t  am;
2773         ia32_address_t      *addr = &am.addr;
2774
2775         match_arguments(&am, src_block, left, right, NULL,
2776                         match_commutative | match_am);
2777
2778         new_node = new_rd_ia32_Ucomi(dbgi, irg, new_block, addr->base, addr->index,
2779                                      addr->mem, am.new_op1, am.new_op2,
2780                                      am.ins_permuted);
2781         set_am_attributes(new_node, &am);
2782
2783         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2784
2785         new_node = fix_mem_proj(new_node, &am);
2786
2787         return new_node;
2788 }
2789
2790 /**
2791  * helper function: checks wether all Cmp projs are Lg or Eq which is needed
2792  * to fold an and into a test node
2793  */
2794 static int can_fold_test_and(ir_node *node)
2795 {
2796         const ir_edge_t *edge;
2797
2798         /** we can only have eq and lg projs */
2799         foreach_out_edge(node, edge) {
2800                 ir_node *proj = get_edge_src_irn(edge);
2801                 pn_Cmp   pnc  = get_Proj_proj(proj);
2802                 if(pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2803                         return 0;
2804         }
2805
2806         return 1;
2807 }
2808
2809 /**
2810  * Generate code for a Cmp.
2811  */
2812 static ir_node *gen_Cmp(ir_node *node)
2813 {
2814         ir_graph *irg       = current_ir_graph;
2815         dbg_info *dbgi      = get_irn_dbg_info(node);
2816         ir_node  *block     = get_nodes_block(node);
2817         ir_node  *new_block = be_transform_node(block);
2818         ir_node  *left      = get_Cmp_left(node);
2819         ir_node  *right     = get_Cmp_right(node);
2820         ir_mode  *cmp_mode  = get_irn_mode(left);
2821         ir_node  *new_node;
2822         ia32_address_mode_t  am;
2823         ia32_address_t      *addr = &am.addr;
2824         int                  cmp_unsigned;
2825
2826         if(mode_is_float(cmp_mode)) {
2827                 if (ia32_cg_config.use_sse2) {
2828                         return create_Ucomi(node);
2829                 } else {
2830                         return create_Fucom(node);
2831                 }
2832         }
2833
2834         assert(mode_needs_gp_reg(cmp_mode));
2835
2836         /* we prefer the Test instruction where possible except cases where
2837          * we can use SourceAM */
2838         cmp_unsigned = !mode_is_signed(cmp_mode);
2839         if (is_Const_0(right)) {
2840                 if (is_And(left) &&
2841                                 get_irn_n_edges(left) == 1 &&
2842                                 can_fold_test_and(node)) {
2843                         /* Test(and_left, and_right) */
2844                         ir_node *and_left  = get_And_left(left);
2845                         ir_node *and_right = get_And_right(left);
2846                         ir_mode *mode      = get_irn_mode(and_left);
2847
2848                         match_arguments(&am, block, and_left, and_right, NULL,
2849                                         match_commutative |
2850                                         match_am | match_8bit_am | match_16bit_am |
2851                                         match_am_and_immediates | match_immediate |
2852                                         match_8bit | match_16bit);
2853                         if (get_mode_size_bits(mode) == 8) {
2854                                 new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2855                                                                 addr->index, addr->mem, am.new_op1,
2856                                                                 am.new_op2, am.ins_permuted,
2857                                                                 cmp_unsigned);
2858                         } else {
2859                                 new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base,
2860                                                             addr->index, addr->mem, am.new_op1,
2861                                                             am.new_op2, am.ins_permuted, cmp_unsigned);
2862                         }
2863                 } else {
2864                         match_arguments(&am, block, NULL, left, NULL,
2865                                         match_am | match_8bit_am | match_16bit_am |
2866                                         match_8bit | match_16bit);
2867                         if (am.op_type == ia32_AddrModeS) {
2868                                 /* Cmp(AM, 0) */
2869                                 ir_node *imm_zero = try_create_Immediate(right, 0);
2870                                 if (get_mode_size_bits(cmp_mode) == 8) {
2871                                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2872                                                                        addr->index, addr->mem, am.new_op2,
2873                                                                        imm_zero, am.ins_permuted,
2874                                                                        cmp_unsigned);
2875                                 } else {
2876                                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2877                                                                    addr->index, addr->mem, am.new_op2,
2878                                                                    imm_zero, am.ins_permuted, cmp_unsigned);
2879                                 }
2880                         } else {
2881                                 /* Test(left, left) */
2882                                 if (get_mode_size_bits(cmp_mode) == 8) {
2883                                         new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base,
2884                                                                         addr->index, addr->mem, am.new_op2,
2885                                                                         am.new_op2, am.ins_permuted,
2886                                                                         cmp_unsigned);
2887                                 } else {
2888                                         new_node = new_rd_ia32_Test(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                                 }
2893                         }
2894                 }
2895         } else {
2896                 /* Cmp(left, right) */
2897                 match_arguments(&am, block, left, right, NULL,
2898                                 match_commutative | match_am | match_8bit_am |
2899                                 match_16bit_am | match_am_and_immediates |
2900                                 match_immediate | match_8bit | match_16bit);
2901                 if (get_mode_size_bits(cmp_mode) == 8) {
2902                         new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base,
2903                                                        addr->index, addr->mem, am.new_op1,
2904                                                        am.new_op2, am.ins_permuted,
2905                                                        cmp_unsigned);
2906                 } else {
2907                         new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base,
2908                                                    addr->index, addr->mem, am.new_op1,
2909                                                    am.new_op2, am.ins_permuted, cmp_unsigned);
2910                 }
2911         }
2912         set_am_attributes(new_node, &am);
2913         assert(cmp_mode != NULL);
2914         set_ia32_ls_mode(new_node, cmp_mode);
2915
2916         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2917
2918         new_node = fix_mem_proj(new_node, &am);
2919
2920         return new_node;
2921 }
2922
2923 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2924                             pn_Cmp pnc)
2925 {
2926         ir_graph            *irg           = current_ir_graph;
2927         dbg_info            *dbgi          = get_irn_dbg_info(node);
2928         ir_node             *block         = get_nodes_block(node);
2929         ir_node             *new_block     = be_transform_node(block);
2930         ir_node             *val_true      = get_Psi_val(node, 0);
2931         ir_node             *val_false     = get_Psi_default(node);
2932         ir_node             *new_node;
2933         match_flags_t        match_flags;
2934         ia32_address_mode_t  am;
2935         ia32_address_t      *addr;
2936
2937         assert(ia32_cg_config.use_cmov);
2938         assert(mode_needs_gp_reg(get_irn_mode(val_true)));
2939
2940         addr = &am.addr;
2941
2942         match_flags = match_commutative | match_am | match_16bit_am |
2943                       match_mode_neutral;
2944
2945         match_arguments(&am, block, val_false, val_true, flags, match_flags);
2946
2947         new_node = new_rd_ia32_CMov(dbgi, irg, new_block, addr->base, addr->index,
2948                                     addr->mem, am.new_op1, am.new_op2, new_flags,
2949                                     am.ins_permuted, pnc);
2950         set_am_attributes(new_node, &am);
2951
2952         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
2953
2954         new_node = fix_mem_proj(new_node, &am);
2955
2956         return new_node;
2957 }
2958
2959 /**
2960  * Creates a ia32 Setcc instruction.
2961  */
2962 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2963                                  ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2964                                  int ins_permuted)
2965 {
2966         ir_graph *irg   = current_ir_graph;
2967         ir_node  *noreg = ia32_new_NoReg_gp(env_cg);
2968         ir_node  *nomem = new_NoMem();
2969         ir_mode  *mode  = get_irn_mode(orig_node);
2970         ir_node  *new_node;
2971
2972         new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted);
2973         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2974
2975         /* we might need to conv the result up */
2976         if (get_mode_size_bits(mode) > 8) {
2977                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg,
2978                                                     nomem, new_node, mode_Bu);
2979                 SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node));
2980         }
2981
2982         return new_node;
2983 }
2984
2985 /**
2986  * Create instruction for an unsigned Difference or Zero.
2987  */
2988 static ir_node *create_Doz(ir_node *psi, ir_node *new_block, ir_node *a, ir_node *b) {
2989         ir_graph *irg   = current_ir_graph;
2990         ir_mode  *mode  = get_irn_mode(psi);
2991         ir_node  *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2992         dbg_info *dbgi;
2993
2994         new_node = gen_binop(psi, a, b, new_rd_ia32_Sub,
2995                 match_mode_neutral | match_am | match_immediate | match_two_users);
2996
2997         block = get_nodes_block(new_node);
2998
2999         if (is_Proj(new_node)) {
3000                 sub = get_Proj_pred(new_node);
3001                 assert(is_ia32_Sub(sub));
3002         } else {
3003                 sub = new_node;
3004                 set_irn_mode(sub, mode_T);
3005                 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
3006         }
3007         eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3008
3009         dbgi   = get_irn_dbg_info(psi);
3010         noreg  = ia32_new_NoReg_gp(env_cg);
3011         tmpreg = new_rd_ia32_ProduceVal(dbgi, irg, block);
3012         nomem  = new_NoMem();
3013         sbb    = new_rd_ia32_Sbb(dbgi, irg, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
3014
3015         new_node = new_rd_ia32_And(dbgi, irg, block, noreg, noreg, nomem, new_node, sbb);
3016         set_ia32_commutative(new_node);
3017         return new_node;
3018 }
3019
3020 /**
3021  * Transforms a Psi node into CMov.
3022  *
3023  * @return The transformed node.
3024  */
3025 static ir_node *gen_Psi(ir_node *node)
3026 {
3027         dbg_info *dbgi        = get_irn_dbg_info(node);
3028         ir_node  *block       = get_nodes_block(node);
3029         ir_node  *new_block   = be_transform_node(block);
3030         ir_node  *psi_true    = get_Psi_val(node, 0);
3031         ir_node  *psi_default = get_Psi_default(node);
3032         ir_node  *cond        = get_Psi_cond(node, 0);
3033         ir_mode  *mode        = get_irn_mode(node);
3034         ir_node  *cmp         = get_Proj_pred(cond);
3035         ir_node  *cmp_left    = get_Cmp_left(cmp);
3036         ir_node  *cmp_right   = get_Cmp_right(cmp);
3037         pn_Cmp   pnc          = get_Proj_proj(cond);
3038
3039         assert(get_Psi_n_conds(node) == 1);
3040         assert(get_irn_mode(cond) == mode_b);
3041
3042         /* Note: a Psi node uses a Load two times IFF it's used in the compare AND in the result */
3043         if (mode_is_float(mode)) {
3044                 if (ia32_cg_config.use_sse2) {
3045                         if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
3046                                 if (cmp_left == psi_true && cmp_right == psi_default) {
3047                                         /* psi(a <= b, a, b) => MIN */
3048                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3049                                          match_commutative | match_am | match_two_users);
3050                                 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3051                                         /* psi(a <= b, b, a) => MAX */
3052                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3053                                          match_commutative | match_am | match_two_users);
3054                                 }
3055                         } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
3056                                 if (cmp_left == psi_true && cmp_right == psi_default) {
3057                                         /* psi(a >= b, a, b) => MAX */
3058                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMax,
3059                                          match_commutative | match_am | match_two_users);
3060                                 } else if (cmp_left == psi_default && cmp_right == psi_true) {
3061                                         /* psi(a >= b, b, a) => MIN */
3062                                         return gen_binop(node, cmp_left, cmp_right, new_rd_ia32_xMin,
3063                                          match_commutative | match_am | match_two_users);
3064                                 }
3065                         }
3066                 }
3067                 panic("cannot transform floating point Psi");
3068
3069         } else {
3070                 ir_node *flags;
3071                 ir_node *new_node;
3072
3073                 assert(mode_needs_gp_reg(mode));
3074
3075                 /* check for unsigned Doz first */
3076                 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
3077                     is_Const_0(psi_default) && is_Sub(psi_true) &&
3078                     get_Sub_left(psi_true) == cmp_left && get_Sub_right(psi_true) == cmp_right) {
3079                         /* Psi(a >=u b, a - b, 0) unsigned Doz */
3080                         return create_Doz(node, new_block, cmp_left, cmp_right);
3081                 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
3082                                    is_Const_0(psi_true) && is_Sub(psi_default) &&
3083                                    get_Sub_left(psi_default) == cmp_left && get_Sub_right(psi_default) == cmp_right) {
3084                         /* Psi(a <=u b, 0, a - b) unsigned Doz */
3085                         return create_Doz(node, new_block, cmp_left, cmp_right);
3086                 }
3087
3088                 flags = get_flags_node(cond, &pnc);
3089
3090                 if (is_Const(psi_true) && is_Const(psi_default)) {
3091                         /* both are const, good */
3092                         if (is_Const_1(psi_true) && is_Const_0(psi_default)) {
3093                                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
3094                         } else if (is_Const_0(psi_true) && is_Const_1(psi_default)) {
3095                                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3096                         } else {
3097                                 /* Not that simple. */
3098                         }
3099                 } else {
3100                         new_node = create_CMov(node, cond, flags, pnc);
3101                 }
3102                 return new_node;
3103         }
3104 }
3105
3106
3107 /**
3108  * Create a conversion from x87 state register to general purpose.
3109  */
3110 static ir_node *gen_x87_fp_to_gp(ir_node *node) {
3111         ir_node         *block      = be_transform_node(get_nodes_block(node));
3112         ir_node         *op         = get_Conv_op(node);
3113         ir_node         *new_op     = be_transform_node(op);
3114         ia32_code_gen_t *cg         = env_cg;
3115         ir_graph        *irg        = current_ir_graph;
3116         dbg_info        *dbgi       = get_irn_dbg_info(node);
3117         ir_node         *noreg      = ia32_new_NoReg_gp(cg);
3118         ir_mode         *mode       = get_irn_mode(node);
3119         ir_node         *fist, *load, *mem;
3120
3121         mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3122         set_irn_pinned(fist, op_pin_state_floats);
3123         set_ia32_use_frame(fist);
3124         set_ia32_op_type(fist, ia32_AddrModeD);
3125
3126         assert(get_mode_size_bits(mode) <= 32);
3127         /* exception we can only store signed 32 bit integers, so for unsigned
3128            we store a 64bit (signed) integer and load the lower bits */
3129         if(get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3130                 set_ia32_ls_mode(fist, mode_Ls);
3131         } else {
3132                 set_ia32_ls_mode(fist, mode_Is);
3133         }
3134         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(cg, node));
3135
3136         /* do a Load */
3137         load = new_rd_ia32_Load(dbgi, irg, block, get_irg_frame(irg), noreg, mem);
3138
3139         set_irn_pinned(load, op_pin_state_floats);
3140         set_ia32_use_frame(load);
3141         set_ia32_op_type(load, ia32_AddrModeS);
3142         set_ia32_ls_mode(load, mode_Is);
3143         if(get_ia32_ls_mode(fist) == mode_Ls) {
3144                 ia32_attr_t *attr = get_ia32_attr(load);
3145                 attr->data.need_64bit_stackent = 1;
3146         } else {
3147                 ia32_attr_t *attr = get_ia32_attr(load);
3148                 attr->data.need_32bit_stackent = 1;
3149         }
3150         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(cg, node));
3151
3152         return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3153 }
3154
3155 /**
3156  * Creates a x87 strict Conv by placing a Sore and a Load
3157  */
3158 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3159 {
3160         ir_node  *block    = get_nodes_block(node);
3161         ir_graph *irg      = current_ir_graph;
3162         dbg_info *dbgi     = get_irn_dbg_info(node);
3163         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
3164         ir_node  *nomem    = new_NoMem();
3165         ir_node  *frame    = get_irg_frame(irg);
3166         ir_node  *store, *load;
3167         ir_node  *new_node;
3168
3169         store = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, nomem, node,
3170                                  tgt_mode);
3171         set_ia32_use_frame(store);
3172         set_ia32_op_type(store, ia32_AddrModeD);
3173         SET_IA32_ORIG_NODE(store, ia32_get_old_node_name(env_cg, node));
3174
3175         load = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, store,
3176                                 tgt_mode);
3177         set_ia32_use_frame(load);
3178         set_ia32_op_type(load, ia32_AddrModeS);
3179         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
3180
3181         new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3182         return new_node;
3183 }
3184
3185 /**
3186  * Create a conversion from general purpose to x87 register
3187  */
3188 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode) {
3189         ir_node  *src_block = get_nodes_block(node);
3190         ir_node  *block     = be_transform_node(src_block);
3191         ir_graph *irg       = current_ir_graph;
3192         dbg_info *dbgi      = get_irn_dbg_info(node);
3193         ir_node  *op        = get_Conv_op(node);
3194         ir_node  *new_op    = NULL;
3195         ir_node  *noreg;
3196         ir_node  *nomem;
3197         ir_mode  *mode;
3198         ir_mode  *store_mode;
3199         ir_node  *fild;
3200         ir_node  *store;
3201         ir_node  *new_node;
3202         int       src_bits;
3203
3204         /* fild can use source AM if the operand is a signed 32bit integer */
3205         if (src_mode == mode_Is) {
3206                 ia32_address_mode_t am;
3207
3208                 match_arguments(&am, src_block, NULL, op, NULL,
3209                                 match_am | match_try_am);
3210                 if (am.op_type == ia32_AddrModeS) {
3211                         ia32_address_t *addr = &am.addr;
3212
3213                         fild     = new_rd_ia32_vfild(dbgi, irg, block, addr->base,
3214                                                      addr->index, addr->mem);
3215                         new_node = new_r_Proj(irg, block, fild, mode_vfp,
3216                                               pn_ia32_vfild_res);
3217
3218                         set_am_attributes(fild, &am);
3219                         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
3220
3221                         fix_mem_proj(fild, &am);
3222
3223                         return new_node;
3224                 }
3225         }
3226         if(new_op == NULL) {
3227                 new_op = be_transform_node(op);
3228         }
3229
3230         noreg  = ia32_new_NoReg_gp(env_cg);
3231         nomem  = new_NoMem();
3232         mode   = get_irn_mode(op);
3233
3234         /* first convert to 32 bit signed if necessary */
3235         src_bits = get_mode_size_bits(src_mode);
3236         if (src_bits == 8) {
3237                 new_op = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, block, noreg, noreg, nomem,
3238                                                   new_op, src_mode);
3239                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3240                 mode = mode_Is;
3241         } else if (src_bits < 32) {
3242                 new_op = new_rd_ia32_Conv_I2I(dbgi, irg, block, noreg, noreg, nomem,
3243                                               new_op, src_mode);
3244                 SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
3245                 mode = mode_Is;
3246         }
3247
3248         assert(get_mode_size_bits(mode) == 32);
3249
3250         /* do a store */
3251         store = new_rd_ia32_Store(dbgi, irg, block, get_irg_frame(irg), noreg, nomem,
3252                                   new_op);
3253
3254         set_ia32_use_frame(store);
3255         set_ia32_op_type(store, ia32_AddrModeD);
3256         set_ia32_ls_mode(store, mode_Iu);
3257
3258         /* exception for 32bit unsigned, do a 64bit spill+load */
3259         if(!mode_is_signed(mode)) {
3260                 ir_node *in[2];
3261                 /* store a zero */
3262                 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3263
3264                 ir_node *zero_store = new_rd_ia32_Store(dbgi, irg, block,
3265                                                         get_irg_frame(irg), noreg, nomem,
3266                                                         zero_const);
3267
3268                 set_ia32_use_frame(zero_store);
3269                 set_ia32_op_type(zero_store, ia32_AddrModeD);
3270                 add_ia32_am_offs_int(zero_store, 4);
3271                 set_ia32_ls_mode(zero_store, mode_Iu);
3272
3273                 in[0] = zero_store;
3274                 in[1] = store;
3275
3276                 store      = new_rd_Sync(dbgi, irg, block, 2, in);
3277                 store_mode = mode_Ls;
3278         } else {
3279                 store_mode = mode_Is;
3280         }
3281
3282         /* do a fild */
3283         fild = new_rd_ia32_vfild(dbgi, irg, block, get_irg_frame(irg), noreg, store);
3284
3285         set_ia32_use_frame(fild);
3286         set_ia32_op_type(fild, ia32_AddrModeS);
3287         set_ia32_ls_mode(fild, store_mode);
3288
3289         new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3290
3291         return new_node;
3292 }
3293
3294 /**
3295  * Create a conversion from one integer mode into another one
3296  */
3297 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3298                                 dbg_info *dbgi, ir_node *block, ir_node *op,
3299                                 ir_node *node)
3300 {
3301         ir_graph *irg       = current_ir_graph;
3302         int       src_bits  = get_mode_size_bits(src_mode);
3303         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3304         ir_node  *new_block = be_transform_node(block);
3305         ir_node  *new_node;
3306         ir_mode  *smaller_mode;
3307         int       smaller_bits;
3308         ia32_address_mode_t  am;
3309         ia32_address_t      *addr = &am.addr;
3310
3311         (void) node;
3312         if (src_bits < tgt_bits) {
3313                 smaller_mode = src_mode;
3314                 smaller_bits = src_bits;
3315         } else {
3316                 smaller_mode = tgt_mode;
3317                 smaller_bits = tgt_bits;
3318         }
3319
3320 #ifdef DEBUG_libfirm
3321         if(is_Const(op)) {
3322                 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3323                            op);
3324         }
3325 #endif
3326
3327         match_arguments(&am, block, NULL, op, NULL,
3328                         match_8bit | match_16bit |
3329                         match_am | match_8bit_am | match_16bit_am);
3330         if (smaller_bits == 8) {
3331                 new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, addr->base,
3332                                                     addr->index, addr->mem, am.new_op2,
3333                                                     smaller_mode);
3334         } else {
3335                 new_node = new_rd_ia32_Conv_I2I(dbgi, irg, new_block, addr->base,
3336                                                 addr->index, addr->mem, am.new_op2,
3337                                                 smaller_mode);
3338         }
3339         set_am_attributes(new_node, &am);
3340         /* match_arguments assume that out-mode = in-mode, this isn't true here
3341          * so fix it */
3342         set_ia32_ls_mode(new_node, smaller_mode);
3343         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
3344         new_node = fix_mem_proj(new_node, &am);
3345         return new_node;
3346 }
3347
3348 /**
3349  * Transforms a Conv node.
3350  *
3351  * @return The created ia32 Conv node
3352  */
3353 static ir_node *gen_Conv(ir_node *node) {
3354         ir_node  *block     = get_nodes_block(node);
3355         ir_node  *new_block = be_transform_node(block);
3356         ir_node  *op        = get_Conv_op(node);
3357         ir_node  *new_op    = NULL;
3358         ir_graph *irg       = current_ir_graph;
3359         dbg_info *dbgi      = get_irn_dbg_info(node);
3360         ir_mode  *src_mode  = get_irn_mode(op);
3361         ir_mode  *tgt_mode  = get_irn_mode(node);
3362         int       src_bits  = get_mode_size_bits(src_mode);
3363         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3364         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
3365         ir_node  *nomem     = new_rd_NoMem(irg);
3366         ir_node  *res       = NULL;
3367
3368         if (src_mode == mode_b) {
3369                 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3370                 /* nothing to do, we already model bools as 0/1 ints */
3371                 return be_transform_node(op);
3372         }
3373
3374         if (src_mode == tgt_mode) {
3375                 if (get_Conv_strict(node)) {
3376                         if (ia32_cg_config.use_sse2) {
3377                                 /* when we are in SSE mode, we can kill all strict no-op conversion */
3378                                 return be_transform_node(op);
3379                         }
3380                 } else {
3381                         /* this should be optimized already, but who knows... */
3382                         DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3383                         DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3384                         return be_transform_node(op);
3385                 }
3386         }
3387
3388         if (mode_is_float(src_mode)) {
3389                 new_op = be_transform_node(op);
3390                 /* we convert from float ... */
3391                 if (mode_is_float(tgt_mode)) {
3392                         if(src_mode == mode_E && tgt_mode == mode_D
3393                                         && !get_Conv_strict(node)) {
3394                                 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3395                                 return new_op;
3396                         }
3397
3398                         /* ... to float */
3399                         if (ia32_cg_config.use_sse2) {
3400                                 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3401                                 res = new_rd_ia32_Conv_FP2FP(dbgi, irg, new_block, noreg, noreg,
3402                                                              nomem, new_op);
3403                                 set_ia32_ls_mode(res, tgt_mode);
3404                         } else {
3405                                 if(get_Conv_strict(node)) {
3406                                         res = gen_x87_strict_conv(tgt_mode, new_op);
3407                                         SET_IA32_ORIG_NODE(get_Proj_pred(res), ia32_get_old_node_name(env_cg, node));
3408                                         return res;
3409                                 }
3410                                 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3411                                 return new_op;
3412                         }
3413                 } else {
3414                         /* ... to int */
3415                         DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3416                         if (ia32_cg_config.use_sse2) {
3417                                 res = new_rd_ia32_Conv_FP2I(dbgi, irg, new_block, noreg, noreg,
3418                                                             nomem, new_op);
3419                                 set_ia32_ls_mode(res, src_mode);
3420                         } else {
3421                                 return gen_x87_fp_to_gp(node);
3422                         }
3423                 }
3424         } else {
3425                 /* we convert from int ... */
3426                 if (mode_is_float(tgt_mode)) {
3427                         /* ... to float */
3428                         DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3429                         if (ia32_cg_config.use_sse2) {
3430                                 new_op = be_transform_node(op);
3431                                 res = new_rd_ia32_Conv_I2FP(dbgi, irg, new_block, noreg, noreg,
3432                                                             nomem, new_op);
3433                                 set_ia32_ls_mode(res, tgt_mode);
3434                         } else {
3435                                 res = gen_x87_gp_to_fp(node, src_mode);
3436                                 if(get_Conv_strict(node)) {
3437                                         res = gen_x87_strict_conv(tgt_mode, res);
3438                                         SET_IA32_ORIG_NODE(get_Proj_pred(res),
3439                                                            ia32_get_old_node_name(env_cg, node));
3440                                 }
3441                                 return res;
3442                         }
3443                 } else if(tgt_mode == mode_b) {
3444                         /* mode_b lowering already took care that we only have 0/1 values */
3445                         DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3446                             src_mode, tgt_mode));
3447                         return be_transform_node(op);
3448                 } else {
3449                         /* to int */
3450                         if (src_bits == tgt_bits) {
3451                                 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3452                                     src_mode, tgt_mode));
3453                                 return be_transform_node(op);
3454                         }
3455
3456                         res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3457                         return res;
3458                 }
3459         }
3460
3461         return res;
3462 }
3463
3464 static int check_immediate_constraint(long val, char immediate_constraint_type)
3465 {
3466         switch (immediate_constraint_type) {
3467         case 0:
3468                 return 1;
3469         case 'I':
3470                 return val >= 0 && val <= 32;
3471         case 'J':
3472                 return val >= 0 && val <= 63;
3473         case 'K':
3474                 return val >= -128 && val <= 127;
3475         case 'L':
3476                 return val == 0xff || val == 0xffff;
3477         case 'M':
3478                 return val >= 0 && val <= 3;
3479         case 'N':
3480                 return val >= 0 && val <= 255;
3481         case 'O':
3482                 return val >= 0 && val <= 127;
3483         default:
3484                 break;
3485         }
3486         panic("Invalid immediate constraint found");
3487         return 0;
3488 }
3489
3490 static ir_node *try_create_Immediate(ir_node *node,
3491                                      char immediate_constraint_type)
3492 {
3493         int          minus         = 0;
3494         tarval      *offset        = NULL;
3495         int          offset_sign   = 0;
3496         long         val = 0;
3497         ir_entity   *symconst_ent  = NULL;
3498         int          symconst_sign = 0;
3499         ir_mode     *mode;
3500         ir_node     *cnst          = NULL;
3501         ir_node     *symconst      = NULL;
3502         ir_node     *new_node;
3503
3504         mode = get_irn_mode(node);
3505         if(!mode_is_int(mode) && !mode_is_reference(mode)) {
3506                 return NULL;
3507         }
3508
3509         if(is_Minus(node)) {
3510                 minus = 1;
3511                 node  = get_Minus_op(node);
3512         }
3513
3514         if(is_Const(node)) {
3515                 cnst        = node;
3516                 symconst    = NULL;
3517                 offset_sign = minus;
3518         } else if(is_SymConst(node)) {
3519                 cnst          = NULL;
3520                 symconst      = node;
3521                 symconst_sign = minus;
3522         } else if(is_Add(node)) {
3523                 ir_node *left  = get_Add_left(node);
3524                 ir_node *right = get_Add_right(node);
3525                 if(is_Const(left) && is_SymConst(right)) {
3526                         cnst          = left;
3527                         symconst      = right;
3528                         symconst_sign = minus;
3529                         offset_sign   = minus;
3530                 } else if(is_SymConst(left) && is_Const(right)) {
3531                         cnst          = right;
3532                         symconst      = left;
3533                         symconst_sign = minus;
3534                         offset_sign   = minus;
3535                 }
3536         } else if(is_Sub(node)) {
3537                 ir_node *left  = get_Sub_left(node);
3538                 ir_node *right = get_Sub_right(node);
3539                 if(is_Const(left) && is_SymConst(right)) {
3540                         cnst          = left;
3541                         symconst      = right;
3542                         symconst_sign = !minus;
3543                         offset_sign   = minus;
3544                 } else if(is_SymConst(left) && is_Const(right)) {
3545                         cnst          = right;
3546                         symconst      = left;
3547                         symconst_sign = minus;
3548                         offset_sign   = !minus;
3549                 }
3550         } else {
3551                 return NULL;
3552         }
3553
3554         if(cnst != NULL) {
3555                 offset = get_Const_tarval(cnst);
3556                 if(tarval_is_long(offset)) {
3557                         val = get_tarval_long(offset);
3558                 } else {
3559                         ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
3560                                    "long?\n", cnst);
3561                         return NULL;
3562                 }
3563
3564                 if(!check_immediate_constraint(val, immediate_constraint_type))
3565                         return NULL;
3566         }
3567         if(symconst != NULL) {
3568                 if(immediate_constraint_type != 0) {
3569                         /* we need full 32bits for symconsts */
3570                         return NULL;
3571                 }
3572
3573                 /* unfortunately the assembler/linker doesn't support -symconst */
3574                 if(symconst_sign)
3575                         return NULL;
3576
3577                 if(get_SymConst_kind(symconst) != symconst_addr_ent)
3578                         return NULL;
3579                 symconst_ent = get_SymConst_entity(symconst);
3580         }
3581         if(cnst == NULL && symconst == NULL)
3582                 return NULL;
3583
3584         if(offset_sign && offset != NULL) {
3585                 offset = tarval_neg(offset);
3586         }
3587
3588         new_node = create_Immediate(symconst_ent, symconst_sign, val);
3589
3590         return new_node;
3591 }
3592
3593 static ir_node *create_immediate_or_transform(ir_node *node,
3594                                               char immediate_constraint_type)
3595 {
3596         ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3597         if (new_node == NULL) {
3598                 new_node = be_transform_node(node);
3599         }
3600         return new_node;
3601 }
3602
3603 static const arch_register_req_t no_register_req = {
3604         arch_register_req_type_none,
3605         NULL,                         /* regclass */
3606         NULL,                         /* limit bitset */
3607         0,                            /* same pos */
3608         0                             /* different pos */
3609 };
3610
3611 /**
3612  * An assembler constraint.
3613  */
3614 typedef struct constraint_t constraint_t;
3615 struct constraint_t {
3616         int                         is_in;
3617         int                         n_outs;
3618         const arch_register_req_t **out_reqs;
3619
3620         const arch_register_req_t  *req;
3621         unsigned                    immediate_possible;
3622         char                        immediate_type;
3623 };
3624
3625 static void parse_asm_constraint(int pos, constraint_t *constraint, const char *c)
3626 {
3627         int                          immediate_possible = 0;
3628         char                         immediate_type     = 0;
3629         unsigned                     limited            = 0;
3630         const arch_register_class_t *cls                = NULL;
3631         ir_graph                    *irg = current_ir_graph;
3632         struct obstack              *obst = get_irg_obstack(irg);
3633         arch_register_req_t         *req;
3634         unsigned                    *limited_ptr = NULL;
3635         int                          p;
3636         int                          same_as = -1;
3637
3638         /* TODO: replace all the asserts with nice error messages */
3639
3640         if(*c == 0) {
3641                 /* a memory constraint: no need to do anything in backend about it
3642                  * (the dependencies are already respected by the memory edge of
3643                  * the node) */
3644                 constraint->req = &no_register_req;
3645                 return;
3646         }
3647
3648         while(*c != 0) {
3649                 switch(*c) {
3650                 case ' ':
3651                 case '\t':
3652                 case '\n':
3653                         break;
3654
3655                 case 'a':
3656                         assert(cls == NULL ||
3657                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3658                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3659                         limited |= 1 << REG_EAX;
3660                         break;
3661                 case 'b':
3662                         assert(cls == NULL ||
3663                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3664                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3665                         limited |= 1 << REG_EBX;
3666                         break;
3667                 case 'c':
3668                         assert(cls == NULL ||
3669                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3670                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3671                         limited |= 1 << REG_ECX;
3672                         break;
3673                 case 'd':
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_EDX;
3678                         break;
3679                 case 'D':
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_EDI;
3684                         break;
3685                 case 'S':
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_ESI;
3690                         break;
3691                 case 'Q':
3692                 case 'q': /* q means lower part of the regs only, this makes no
3693                                    * difference to Q for us (we only assigne whole registers) */
3694                         assert(cls == NULL ||
3695                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3696                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3697                         limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3698                                    1 << REG_EDX;
3699                         break;
3700                 case 'A':
3701                         assert(cls == NULL ||
3702                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3703                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3704                         limited |= 1 << REG_EAX | 1 << REG_EDX;
3705                         break;
3706                 case 'l':
3707                         assert(cls == NULL ||
3708                                         (cls == &ia32_reg_classes[CLASS_ia32_gp] && limited != 0));
3709                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3710                         limited |= 1 << REG_EAX | 1 << REG_EBX | 1 << REG_ECX |
3711                                    1 << REG_EDX | 1 << REG_ESI | 1 << REG_EDI |
3712                                    1 << REG_EBP;
3713                         break;
3714
3715                 case 'R':
3716                 case 'r':
3717                 case 'p':
3718                         assert(cls == NULL);
3719                         cls      = &ia32_reg_classes[CLASS_ia32_gp];
3720                         break;
3721
3722                 case 'f':
3723                 case 't':
3724                 case 'u':
3725                         /* TODO: mark values so the x87 simulator knows about t and u */
3726                         assert(cls == NULL);
3727                         cls = &ia32_reg_classes[CLASS_ia32_vfp];
3728                         break;
3729
3730                 case 'Y':
3731                 case 'x':
3732                         assert(cls == NULL);
3733                         /* TODO: check that sse2 is supported */
3734                         cls = &ia32_reg_classes[CLASS_ia32_xmm];
3735                         break;
3736
3737                 case 'I':
3738                 case 'J':
3739                 case 'K':
3740                 case 'L':
3741                 case 'M':
3742                 case 'N':
3743                 case 'O':
3744                         assert(!immediate_possible);
3745                         immediate_possible = 1;
3746                         immediate_type     = *c;
3747                         break;
3748                 case 'n':
3749                 case 'i':
3750                         assert(!immediate_possible);
3751                         immediate_possible = 1;
3752                         break;
3753
3754                 case 'g':
3755                         assert(!immediate_possible && cls == NULL);
3756                         immediate_possible = 1;
3757                         cls                = &ia32_reg_classes[CLASS_ia32_gp];
3758                         break;
3759
3760                 case '0':
3761                 case '1':
3762                 case '2':
3763                 case '3':
3764                 case '4':
3765                 case '5':
3766                 case '6':
3767                 case '7':
3768                 case '8':
3769                 case '9':
3770                         assert(constraint->is_in && "can only specify same constraint "
3771                                "on input");
3772
3773                         sscanf(c, "%d%n", &same_as, &p);
3774                         if(same_as >= 0) {
3775                                 c += p;
3776                                 continue;
3777                         }
3778                         break;
3779
3780                 case 'm':
3781                         /* memory constraint no need to do anything in backend about it
3782                          * (the dependencies are already respected by the memory edge of
3783                          * the node) */
3784                         constraint->req    = &no_register_req;
3785                         return;
3786
3787                 case 'E': /* no float consts yet */
3788                 case 'F': /* no float consts yet */
3789                 case 's': /* makes no sense on x86 */
3790                 case 'X': /* we can't support that in firm */
3791                 case 'o':
3792                 case 'V':
3793                 case '<': /* no autodecrement on x86 */
3794                 case '>': /* no autoincrement on x86 */
3795                 case 'C': /* sse constant not supported yet */
3796                 case 'G': /* 80387 constant not supported yet */
3797                 case 'y': /* we don't support mmx registers yet */
3798                 case 'Z': /* not available in 32 bit mode */
3799                 case 'e': /* not available in 32 bit mode */
3800                         panic("unsupported asm constraint '%c' found in (%+F)",
3801                               *c, current_ir_graph);
3802                         break;
3803                 default:
3804                         panic("unknown asm constraint '%c' found in (%+F)", *c,
3805                               current_ir_graph);
3806                         break;
3807                 }
3808                 ++c;
3809         }
3810
3811         if(same_as >= 0) {
3812                 const arch_register_req_t *other_constr;
3813
3814                 assert(cls == NULL && "same as and register constraint not supported");
3815                 assert(!immediate_possible && "same as and immediate constraint not "
3816                        "supported");
3817                 assert(same_as < constraint->n_outs && "wrong constraint number in "
3818                        "same_as constraint");
3819
3820                 other_constr         = constraint->out_reqs[same_as];
3821
3822                 req                  = obstack_alloc(obst, sizeof(req[0]));
3823                 req->cls             = other_constr->cls;
3824                 req->type            = arch_register_req_type_should_be_same;
3825                 req->limited         = NULL;
3826                 req->other_same      = 1U << pos;
3827                 req->other_different = 0;
3828
3829                 /* switch constraints. This is because in firm we have same_as
3830                  * constraints on the output constraints while in the gcc asm syntax
3831                  * they are specified on the input constraints */
3832                 constraint->req               = other_constr;
3833                 constraint->out_reqs[same_as] = req;
3834                 constraint->immediate_possible = 0;
3835                 return;
3836         }
3837
3838         if(immediate_possible && cls == NULL) {
3839                 cls = &ia32_reg_classes[CLASS_ia32_gp];
3840         }
3841         assert(!immediate_possible || cls == &ia32_reg_classes[CLASS_ia32_gp]);
3842         assert(cls != NULL);
3843
3844         if(immediate_possible) {
3845                 assert(constraint->is_in
3846                        && "immediate make no sense for output constraints");
3847         }
3848         /* todo: check types (no float input on 'r' constrained in and such... */
3849
3850         if(limited != 0) {
3851                 req          = obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
3852                 limited_ptr  = (unsigned*) (req+1);
3853         } else {
3854                 req = obstack_alloc(obst, sizeof(req[0]));
3855         }
3856         memset(req, 0, sizeof(req[0]));
3857
3858         if(limited != 0) {
3859                 req->type    = arch_register_req_type_limited;
3860                 *limited_ptr = limited;
3861                 req->limited = limited_ptr;
3862         } else {
3863                 req->type    = arch_register_req_type_normal;
3864         }
3865         req->cls = cls;
3866
3867         constraint->req                = req;
3868         constraint->immediate_possible = immediate_possible;
3869         constraint->immediate_type     = immediate_type;
3870 }
3871
3872 static void parse_clobber(ir_node *node, int pos, constraint_t *constraint,
3873                           const char *clobber)
3874 {
3875         ir_graph                    *irg  = get_irn_irg(node);
3876         struct obstack              *obst = get_irg_obstack(irg);
3877         const arch_register_t       *reg  = NULL;
3878         int                          c;
3879         size_t                       r;
3880         arch_register_req_t         *req;
3881         const arch_register_class_t *cls;
3882         unsigned                    *limited;
3883
3884         (void) pos;
3885
3886         /* TODO: construct a hashmap instead of doing linear search for clobber
3887          * register */
3888         for(c = 0; c < N_CLASSES; ++c) {
3889                 cls = & ia32_reg_classes[c];
3890                 for(r = 0; r < cls->n_regs; ++r) {
3891                         const arch_register_t *temp_reg = arch_register_for_index(cls, r);
3892                         if(strcmp(temp_reg->name, clobber) == 0
3893                                         || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) {
3894                                 reg = temp_reg;
3895                                 break;
3896                         }
3897                 }
3898                 if(reg != NULL)
3899                         break;
3900         }
3901         if(reg == NULL) {
3902                 panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
3903                 return;
3904         }
3905
3906         assert(reg->index < 32);
3907
3908         limited  = obstack_alloc(obst, sizeof(limited[0]));
3909         *limited = 1 << reg->index;
3910
3911         req          = obstack_alloc(obst, sizeof(req[0]));
3912         memset(req, 0, sizeof(req[0]));
3913         req->type    = arch_register_req_type_limited;
3914         req->cls     = cls;
3915         req->limited = limited;
3916
3917         constraint->req                = req;
3918         constraint->immediate_possible = 0;
3919         constraint->immediate_type     = 0;
3920 }
3921
3922 static int is_memory_op(const ir_asm_constraint *constraint)
3923 {
3924         ident      *id  = constraint->constraint;
3925         const char *str = get_id_str(id);
3926         const char *c;
3927
3928         for(c = str; *c != '\0'; ++c) {
3929                 if(*c == 'm')
3930                         return 1;
3931         }
3932
3933         return 0;
3934 }
3935
3936 /**
3937  * generates code for a ASM node
3938  */
3939 static ir_node *gen_ASM(ir_node *node)
3940 {
3941         int                         i, arity;
3942         ir_graph                   *irg       = current_ir_graph;
3943         ir_node                    *block     = get_nodes_block(node);
3944         ir_node                    *new_block = be_transform_node(block);
3945         dbg_info                   *dbgi      = get_irn_dbg_info(node);
3946         ir_node                   **in;
3947         ir_node                    *new_node;
3948         int                         out_arity;
3949         int                         n_out_constraints;
3950         int                         n_clobbers;
3951         const arch_register_req_t **out_reg_reqs;
3952         const arch_register_req_t **in_reg_reqs;
3953         ia32_asm_reg_t             *register_map;
3954         unsigned                    reg_map_size = 0;
3955         struct obstack             *obst;
3956         const ir_asm_constraint    *in_constraints;
3957         const ir_asm_constraint    *out_constraints;
3958         ident                     **clobbers;
3959         constraint_t                parsed_constraint;
3960
3961         arity = get_irn_arity(node);
3962         in    = alloca(arity * sizeof(in[0]));
3963         memset(in, 0, arity * sizeof(in[0]));
3964
3965         n_out_constraints = get_ASM_n_output_constraints(node);
3966         n_clobbers        = get_ASM_n_clobbers(node);
3967         out_arity         = n_out_constraints + n_clobbers;
3968         /* hack to keep space for mem proj */
3969         if(n_clobbers > 0)
3970                 out_arity += 1;
3971
3972         in_constraints  = get_ASM_input_constraints(node);
3973         out_constraints = get_ASM_output_constraints(node);
3974         clobbers        = get_ASM_clobbers(node);
3975
3976         /* construct output constraints */
3977         obst         = get_irg_obstack(irg);
3978         out_reg_reqs = obstack_alloc(obst, out_arity * sizeof(out_reg_reqs[0]));
3979         parsed_constraint.out_reqs = out_reg_reqs;
3980         parsed_constraint.n_outs   = n_out_constraints;
3981         parsed_constraint.is_in    = 0;
3982
3983         for(i = 0; i < out_arity; ++i) {
3984                 const char   *c;
3985
3986                 if(i < n_out_constraints) {
3987                         const ir_asm_constraint *constraint = &out_constraints[i];
3988                         c = get_id_str(constraint->constraint);
3989                         parse_asm_constraint(i, &parsed_constraint, c);
3990
3991                         if(constraint->pos > reg_map_size)
3992                                 reg_map_size = constraint->pos;
3993
3994                         out_reg_reqs[i] = parsed_constraint.req;
3995                 } else if(i < out_arity - 1) {
3996                         ident *glob_id = clobbers [i - n_out_constraints];
3997                         assert(glob_id != NULL);
3998                         c = get_id_str(glob_id);
3999                         parse_clobber(node, i, &parsed_constraint, c);
4000
4001                         out_reg_reqs[i+1] = parsed_constraint.req;
4002                 }
4003         }
4004         if(n_clobbers > 1)
4005                 out_reg_reqs[n_out_constraints] = &no_register_req;
4006
4007         /* construct input constraints */
4008         in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0]));
4009         parsed_constraint.is_in = 1;
4010         for(i = 0; i < arity; ++i) {
4011                 const ir_asm_constraint   *constraint = &in_constraints[i];
4012                 ident                     *constr_id  = constraint->constraint;
4013                 const char                *c          = get_id_str(constr_id);
4014
4015                 parse_asm_constraint(i, &parsed_constraint, c);
4016                 in_reg_reqs[i] = parsed_constraint.req;
4017
4018                 if(constraint->pos > reg_map_size)
4019                         reg_map_size = constraint->pos;
4020
4021                 if(parsed_constraint.immediate_possible) {
4022                         ir_node *pred      = get_irn_n(node, i);
4023                         char     imm_type  = parsed_constraint.immediate_type;
4024                         ir_node *immediate = try_create_Immediate(pred, imm_type);
4025
4026                         if(immediate != NULL) {
4027                                 in[i] = immediate;
4028                         }
4029                 }
4030         }
4031         reg_map_size++;
4032
4033         register_map = NEW_ARR_D(ia32_asm_reg_t, obst, reg_map_size);
4034         memset(register_map, 0, reg_map_size * sizeof(register_map[0]));
4035
4036         for(i = 0; i < n_out_constraints; ++i) {
4037                 const ir_asm_constraint *constraint = &out_constraints[i];
4038                 unsigned                 pos        = constraint->pos;
4039
4040                 assert(pos < reg_map_size);
4041                 register_map[pos].use_input = 0;
4042                 register_map[pos].valid     = 1;
4043                 register_map[pos].memory    = is_memory_op(constraint);
4044                 register_map[pos].inout_pos = i;
4045                 register_map[pos].mode      = constraint->mode;
4046         }
4047
4048         /* transform inputs */
4049         for(i = 0; i < arity; ++i) {
4050                 const ir_asm_constraint *constraint = &in_constraints[i];
4051                 unsigned                 pos        = constraint->pos;
4052                 ir_node                 *pred       = get_irn_n(node, i);
4053                 ir_node                 *transformed;
4054
4055                 assert(pos < reg_map_size);
4056                 register_map[pos].use_input = 1;
4057                 register_map[pos].valid     = 1;
4058                 register_map[pos].memory    = is_memory_op(constraint);
4059                 register_map[pos].inout_pos = i;
4060                 register_map[pos].mode      = constraint->mode;
4061
4062                 if(in[i] != NULL)
4063                         continue;
4064
4065                 transformed = be_transform_node(pred);
4066                 in[i]       = transformed;
4067         }
4068
4069         new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
4070                                    get_ASM_text(node), register_map);
4071
4072         set_ia32_out_req_all(new_node, out_reg_reqs);
4073         set_ia32_in_req_all(new_node, in_reg_reqs);
4074
4075         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4076
4077         return new_node;
4078 }
4079
4080 /**
4081  * Transforms a FrameAddr into an ia32 Add.
4082  */
4083 static ir_node *gen_be_FrameAddr(ir_node *node) {
4084         ir_node  *block  = be_transform_node(get_nodes_block(node));
4085         ir_node  *op     = be_get_FrameAddr_frame(node);
4086         ir_node  *new_op = be_transform_node(op);
4087         ir_graph *irg    = current_ir_graph;
4088         dbg_info *dbgi   = get_irn_dbg_info(node);
4089         ir_node  *noreg  = ia32_new_NoReg_gp(env_cg);
4090         ir_node  *new_node;
4091
4092         new_node = new_rd_ia32_Lea(dbgi, irg, block, new_op, noreg);
4093         set_ia32_frame_ent(new_node, arch_get_frame_entity(env_cg->arch_env, node));
4094         set_ia32_use_frame(new_node);
4095
4096         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4097
4098         return new_node;
4099 }
4100
4101 /**
4102  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
4103  */
4104 static ir_node *gen_be_Return(ir_node *node) {
4105         ir_graph  *irg     = current_ir_graph;
4106         ir_node   *ret_val = get_irn_n(node, be_pos_Return_val);
4107         ir_node   *ret_mem = get_irn_n(node, be_pos_Return_mem);
4108         ir_entity *ent     = get_irg_entity(irg);
4109         ir_type   *tp      = get_entity_type(ent);
4110         dbg_info  *dbgi;
4111         ir_node   *block;
4112         ir_type   *res_type;
4113         ir_mode   *mode;
4114         ir_node   *frame, *sse_store, *fld, *mproj, *barrier;
4115         ir_node   *new_barrier, *new_ret_val, *new_ret_mem;
4116         ir_node   *noreg;
4117         ir_node   **in;
4118         int       pn_ret_val, pn_ret_mem, arity, i;
4119
4120         assert(ret_val != NULL);
4121         if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
4122                 return be_duplicate_node(node);
4123         }
4124
4125         res_type = get_method_res_type(tp, 0);
4126
4127         if (! is_Primitive_type(res_type)) {
4128                 return be_duplicate_node(node);
4129         }
4130
4131         mode = get_type_mode(res_type);
4132         if (! mode_is_float(mode)) {
4133                 return be_duplicate_node(node);
4134         }
4135
4136         assert(get_method_n_ress(tp) == 1);
4137
4138         pn_ret_val = get_Proj_proj(ret_val);
4139         pn_ret_mem = get_Proj_proj(ret_mem);
4140
4141         /* get the Barrier */
4142         barrier = get_Proj_pred(ret_val);
4143
4144         /* get result input of the Barrier */
4145         ret_val     = get_irn_n(barrier, pn_ret_val);
4146         new_ret_val = be_transform_node(ret_val);
4147
4148         /* get memory input of the Barrier */
4149         ret_mem     = get_irn_n(barrier, pn_ret_mem);
4150         new_ret_mem = be_transform_node(ret_mem);
4151
4152         frame = get_irg_frame(irg);
4153
4154         dbgi  = get_irn_dbg_info(barrier);
4155         block = be_transform_node(get_nodes_block(barrier));
4156
4157         noreg = ia32_new_NoReg_gp(env_cg);
4158
4159         /* store xmm0 onto stack */
4160         sse_store = new_rd_ia32_xStoreSimple(dbgi, irg, block, frame, noreg,
4161                                              new_ret_mem, new_ret_val);
4162         set_ia32_ls_mode(sse_store, mode);
4163         set_ia32_op_type(sse_store, ia32_AddrModeD);
4164         set_ia32_use_frame(sse_store);
4165
4166         /* load into x87 register */
4167         fld = new_rd_ia32_vfld(dbgi, irg, block, frame, noreg, sse_store, mode);
4168         set_ia32_op_type(fld, ia32_AddrModeS);
4169         set_ia32_use_frame(fld);
4170
4171         mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
4172         fld   = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
4173
4174         /* create a new barrier */
4175         arity = get_irn_arity(barrier);
4176         in = alloca(arity * sizeof(in[0]));
4177         for (i = 0; i < arity; ++i) {
4178                 ir_node *new_in;
4179
4180                 if (i == pn_ret_val) {
4181                         new_in = fld;
4182                 } else if (i == pn_ret_mem) {
4183                         new_in = mproj;
4184                 } else {
4185                         ir_node *in = get_irn_n(barrier, i);
4186                         new_in = be_transform_node(in);
4187                 }
4188                 in[i] = new_in;
4189         }
4190
4191         new_barrier = new_ir_node(dbgi, irg, block,
4192                                   get_irn_op(barrier), get_irn_mode(barrier),
4193                                   arity, in);
4194         copy_node_attr(barrier, new_barrier);
4195         be_duplicate_deps(barrier, new_barrier);
4196         be_set_transformed_node(barrier, new_barrier);
4197         mark_irn_visited(barrier);
4198
4199         /* transform normally */
4200         return be_duplicate_node(node);
4201 }
4202
4203 /**
4204  * Transform a be_AddSP into an ia32_SubSP.
4205  */
4206 static ir_node *gen_be_AddSP(ir_node *node)
4207 {
4208         ir_node  *sz = get_irn_n(node, be_pos_AddSP_size);
4209         ir_node  *sp = get_irn_n(node, be_pos_AddSP_old_sp);
4210
4211         return gen_binop(node, sp, sz, new_rd_ia32_SubSP, match_am);
4212 }
4213
4214 /**
4215  * Transform a be_SubSP into an ia32_AddSP
4216  */
4217 static ir_node *gen_be_SubSP(ir_node *node)
4218 {
4219         ir_node  *sz = get_irn_n(node, be_pos_SubSP_size);
4220         ir_node  *sp = get_irn_n(node, be_pos_SubSP_old_sp);
4221
4222         return gen_binop(node, sp, sz, new_rd_ia32_AddSP, match_am);
4223 }
4224
4225 /**
4226  * This function just sets the register for the Unknown node
4227  * as this is not done during register allocation because Unknown
4228  * is an "ignore" node.
4229  */
4230 static ir_node *gen_Unknown(ir_node *node) {
4231         ir_mode *mode = get_irn_mode(node);
4232
4233         if (mode_is_float(mode)) {
4234                 if (ia32_cg_config.use_sse2) {
4235                         return ia32_new_Unknown_xmm(env_cg);
4236                 } else {
4237                         /* Unknown nodes are buggy in x87 simulator, use zero for now... */
4238                         ir_graph *irg   = current_ir_graph;
4239                         dbg_info *dbgi  = get_irn_dbg_info(node);
4240                         ir_node  *block = get_irg_start_block(irg);
4241                         ir_node  *ret   = new_rd_ia32_vfldz(dbgi, irg, block);
4242
4243                         /* Const Nodes before the initial IncSP are a bad idea, because
4244                          * they could be spilled and we have no SP ready at that point yet.
4245                          * So add a dependency to the initial frame pointer calculation to
4246                          * avoid that situation.
4247                          */
4248                         add_irn_dep(ret, get_irg_frame(irg));
4249                         return ret;
4250                 }
4251         } else if (mode_needs_gp_reg(mode)) {
4252                 return ia32_new_Unknown_gp(env_cg);
4253         } else {
4254                 panic("unsupported Unknown-Mode");
4255         }
4256         return NULL;
4257 }
4258
4259 /**
4260  * Change some phi modes
4261  */
4262 static ir_node *gen_Phi(ir_node *node) {
4263         ir_node  *block = be_transform_node(get_nodes_block(node));
4264         ir_graph *irg   = current_ir_graph;
4265         dbg_info *dbgi  = get_irn_dbg_info(node);
4266         ir_mode  *mode  = get_irn_mode(node);
4267         ir_node  *phi;
4268
4269         if(mode_needs_gp_reg(mode)) {
4270                 /* we shouldn't have any 64bit stuff around anymore */
4271                 assert(get_mode_size_bits(mode) <= 32);
4272                 /* all integer operations are on 32bit registers now */
4273                 mode = mode_Iu;
4274         } else if(mode_is_float(mode)) {
4275                 if (ia32_cg_config.use_sse2) {
4276                         mode = mode_xmm;
4277                 } else {
4278                         mode = mode_vfp;
4279                 }
4280         }
4281
4282         /* phi nodes allow loops, so we use the old arguments for now
4283          * and fix this later */
4284         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
4285                           get_irn_in(node) + 1);
4286         copy_node_attr(node, phi);
4287         be_duplicate_deps(node, phi);
4288
4289         be_set_transformed_node(node, phi);
4290         be_enqueue_preds(node);
4291
4292         return phi;
4293 }
4294
4295 /**
4296  * Transform IJmp
4297  */
4298 static ir_node *gen_IJmp(ir_node *node)
4299 {
4300         ir_node  *block     = get_nodes_block(node);
4301         ir_node  *new_block = be_transform_node(block);
4302         ir_graph *irg       = current_ir_graph;
4303         dbg_info *dbgi      = get_irn_dbg_info(node);
4304         ir_node  *op        = get_IJmp_target(node);
4305         ir_node  *new_node;
4306         ia32_address_mode_t  am;
4307         ia32_address_t      *addr = &am.addr;
4308
4309         assert(get_irn_mode(op) == mode_P);
4310
4311         match_arguments(&am, block, NULL, op, NULL,
4312                         match_am | match_8bit_am | match_16bit_am |
4313                         match_immediate | match_8bit | match_16bit);
4314
4315         new_node = new_rd_ia32_IJmp(dbgi, irg, new_block, addr->base, addr->index,
4316                                     addr->mem, am.new_op2);
4317         set_am_attributes(new_node, &am);
4318         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4319
4320         new_node = fix_mem_proj(new_node, &am);
4321
4322         return new_node;
4323 }
4324
4325 typedef ir_node *construct_load_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4326                                      ir_node *mem);
4327
4328 typedef ir_node *construct_store_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
4329                                       ir_node *val, ir_node *mem);
4330
4331 /**
4332  * Transforms a lowered Load into a "real" one.
4333  */
4334 static ir_node *gen_lowered_Load(ir_node *node, construct_load_func func)
4335 {
4336         ir_node  *block   = be_transform_node(get_nodes_block(node));
4337         ir_node  *ptr     = get_irn_n(node, 0);
4338         ir_node  *new_ptr = be_transform_node(ptr);
4339         ir_node  *mem     = get_irn_n(node, 1);
4340         ir_node  *new_mem = be_transform_node(mem);
4341         ir_graph *irg     = current_ir_graph;
4342         dbg_info *dbgi    = get_irn_dbg_info(node);
4343         ir_mode  *mode    = get_ia32_ls_mode(node);
4344         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
4345         ir_node  *new_op;
4346
4347         new_op  = func(dbgi, irg, block, new_ptr, noreg, new_mem);
4348
4349         set_ia32_op_type(new_op, ia32_AddrModeS);
4350         set_ia32_am_offs_int(new_op, get_ia32_am_offs_int(node));
4351         set_ia32_am_scale(new_op, get_ia32_am_scale(node));
4352         set_ia32_am_sc(new_op, get_ia32_am_sc(node));
4353         if (is_ia32_am_sc_sign(node))
4354                 set_ia32_am_sc_sign(new_op);
4355         set_ia32_ls_mode(new_op, mode);
4356         if (is_ia32_use_frame(node)) {
4357                 set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4358                 set_ia32_use_frame(new_op);
4359         }
4360
4361         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4362
4363         return new_op;
4364 }
4365
4366 /**
4367  * Transforms a lowered Store into a "real" one.
4368  */
4369 static ir_node *gen_lowered_Store(ir_node *node, construct_store_func func)
4370 {
4371         ir_node  *block   = be_transform_node(get_nodes_block(node));
4372         ir_node  *ptr     = get_irn_n(node, 0);
4373         ir_node  *new_ptr = be_transform_node(ptr);
4374         ir_node  *val     = get_irn_n(node, 1);
4375         ir_node  *new_val = be_transform_node(val);
4376         ir_node  *mem     = get_irn_n(node, 2);
4377         ir_node  *new_mem = be_transform_node(mem);
4378         ir_graph *irg     = current_ir_graph;
4379         dbg_info *dbgi    = get_irn_dbg_info(node);
4380         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
4381         ir_mode  *mode    = get_ia32_ls_mode(node);
4382         ir_node  *new_op;
4383         long     am_offs;
4384
4385         new_op = func(dbgi, irg, block, new_ptr, noreg, new_val, new_mem);
4386
4387         am_offs = get_ia32_am_offs_int(node);
4388         add_ia32_am_offs_int(new_op, am_offs);
4389
4390         set_ia32_op_type(new_op, ia32_AddrModeD);
4391         set_ia32_ls_mode(new_op, mode);
4392         set_ia32_frame_ent(new_op, get_ia32_frame_ent(node));
4393         set_ia32_use_frame(new_op);
4394
4395         SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
4396
4397         return new_op;
4398 }
4399
4400 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
4401 {
4402         ir_node *left  = get_irn_n(node, n_ia32_l_ShlDep_val);
4403         ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
4404
4405         return gen_shift_binop(node, left, right, new_rd_ia32_Shl,
4406                                match_immediate | match_mode_neutral);
4407 }
4408
4409 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
4410 {
4411         ir_node *left  = get_irn_n(node, n_ia32_l_ShrDep_val);
4412         ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
4413         return gen_shift_binop(node, left, right, new_rd_ia32_Shr,
4414                                match_immediate);
4415 }
4416
4417 static ir_node *gen_ia32_l_SarDep(ir_node *node)
4418 {
4419         ir_node *left  = get_irn_n(node, n_ia32_l_SarDep_val);
4420         ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
4421         return gen_shift_binop(node, left, right, new_rd_ia32_Sar,
4422                                match_immediate);
4423 }
4424
4425 static ir_node *gen_ia32_l_Add(ir_node *node) {
4426         ir_node *left    = get_irn_n(node, n_ia32_l_Add_left);
4427         ir_node *right   = get_irn_n(node, n_ia32_l_Add_right);
4428         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Add,
4429                         match_commutative | match_am | match_immediate |
4430                         match_mode_neutral);
4431
4432         if(is_Proj(lowered)) {
4433                 lowered = get_Proj_pred(lowered);
4434         } else {
4435                 assert(is_ia32_Add(lowered));
4436                 set_irn_mode(lowered, mode_T);
4437         }
4438
4439         return lowered;
4440 }
4441
4442 static ir_node *gen_ia32_l_Adc(ir_node *node)
4443 {
4444         return gen_binop_flags(node, new_rd_ia32_Adc,
4445                         match_commutative | match_am | match_immediate |
4446                         match_mode_neutral);
4447 }
4448
4449 /**
4450  * Transforms an ia32_l_vfild into a "real" ia32_vfild node
4451  *
4452  * @param node   The node to transform
4453  * @return the created ia32 vfild node
4454  */
4455 static ir_node *gen_ia32_l_vfild(ir_node *node) {
4456         return gen_lowered_Load(node, new_rd_ia32_vfild);
4457 }
4458
4459 /**
4460  * Transforms an ia32_l_Load into a "real" ia32_Load node
4461  *
4462  * @param node   The node to transform
4463  * @return the created ia32 Load node
4464  */
4465 static ir_node *gen_ia32_l_Load(ir_node *node) {
4466         return gen_lowered_Load(node, new_rd_ia32_Load);
4467 }
4468
4469 /**
4470  * Transforms an ia32_l_Store into a "real" ia32_Store node
4471  *
4472  * @param node   The node to transform
4473  * @return the created ia32 Store node
4474  */
4475 static ir_node *gen_ia32_l_Store(ir_node *node) {
4476         return gen_lowered_Store(node, new_rd_ia32_Store);
4477 }
4478
4479 /**
4480  * Transforms a l_vfist into a "real" vfist node.
4481  *
4482  * @param node   The node to transform
4483  * @return the created ia32 vfist node
4484  */
4485 static ir_node *gen_ia32_l_vfist(ir_node *node) {
4486         ir_node  *block      = be_transform_node(get_nodes_block(node));
4487         ir_node  *ptr        = get_irn_n(node, 0);
4488         ir_node  *new_ptr    = be_transform_node(ptr);
4489         ir_node  *val        = get_irn_n(node, 1);
4490         ir_node  *new_val    = be_transform_node(val);
4491         ir_node  *mem        = get_irn_n(node, 2);
4492         ir_node  *new_mem    = be_transform_node(mem);
4493         ir_graph *irg        = current_ir_graph;
4494         dbg_info *dbgi       = get_irn_dbg_info(node);
4495         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
4496         ir_mode  *mode       = get_ia32_ls_mode(node);
4497         ir_node  *memres, *fist;
4498         long     am_offs;
4499
4500         memres = gen_vfist(dbgi, irg, block, new_ptr, noreg, new_mem, new_val, &fist);
4501         am_offs = get_ia32_am_offs_int(node);
4502         add_ia32_am_offs_int(fist, am_offs);
4503
4504         set_ia32_op_type(fist, ia32_AddrModeD);
4505         set_ia32_ls_mode(fist, mode);
4506         set_ia32_frame_ent(fist, get_ia32_frame_ent(node));
4507         set_ia32_use_frame(fist);
4508
4509         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4510
4511         return memres;
4512 }
4513
4514 /**
4515  * Transforms a l_MulS into a "real" MulS node.
4516  *
4517  * @return the created ia32 Mul node
4518  */
4519 static ir_node *gen_ia32_l_Mul(ir_node *node) {
4520         ir_node *left  = get_binop_left(node);
4521         ir_node *right = get_binop_right(node);
4522
4523         return gen_binop(node, left, right, new_rd_ia32_Mul,
4524                          match_commutative | match_am | match_mode_neutral);
4525 }
4526
4527 /**
4528  * Transforms a l_IMulS into a "real" IMul1OPS node.
4529  *
4530  * @return the created ia32 IMul1OP node
4531  */
4532 static ir_node *gen_ia32_l_IMul(ir_node *node) {
4533         ir_node  *left  = get_binop_left(node);
4534         ir_node  *right = get_binop_right(node);
4535
4536         return gen_binop(node, left, right, new_rd_ia32_IMul1OP,
4537                          match_commutative | match_am | match_mode_neutral);
4538 }
4539
4540 static ir_node *gen_ia32_l_Sub(ir_node *node) {
4541         ir_node *left    = get_irn_n(node, n_ia32_l_Sub_minuend);
4542         ir_node *right   = get_irn_n(node, n_ia32_l_Sub_subtrahend);
4543         ir_node *lowered = gen_binop(node, left, right, new_rd_ia32_Sub,
4544                         match_am | match_immediate | match_mode_neutral);
4545
4546         if(is_Proj(lowered)) {
4547                 lowered = get_Proj_pred(lowered);
4548         } else {
4549                 assert(is_ia32_Sub(lowered));
4550                 set_irn_mode(lowered, mode_T);
4551         }
4552
4553         return lowered;
4554 }
4555
4556 static ir_node *gen_ia32_l_Sbb(ir_node *node) {
4557         return gen_binop_flags(node, new_rd_ia32_Sbb,
4558                         match_am | match_immediate | match_mode_neutral);
4559 }
4560
4561 /**
4562  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
4563  * op1 - target to be shifted
4564  * op2 - contains bits to be shifted into target
4565  * op3 - shift count
4566  * Only op3 can be an immediate.
4567  */
4568 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
4569                                          ir_node *low, ir_node *count)
4570 {
4571         ir_node  *block     = get_nodes_block(node);
4572         ir_node  *new_block = be_transform_node(block);
4573         ir_graph *irg       = current_ir_graph;
4574         dbg_info *dbgi      = get_irn_dbg_info(node);
4575         ir_node  *new_high  = be_transform_node(high);
4576         ir_node  *new_low   = be_transform_node(low);
4577         ir_node  *new_count;
4578         ir_node  *new_node;
4579
4580         /* the shift amount can be any mode that is bigger than 5 bits, since all
4581          * other bits are ignored anyway */
4582         while (is_Conv(count) && get_irn_n_edges(count) == 1) {
4583                 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
4584                 count = get_Conv_op(count);
4585         }
4586         new_count = create_immediate_or_transform(count, 0);
4587
4588         if (is_ia32_l_ShlD(node)) {
4589                 new_node = new_rd_ia32_ShlD(dbgi, irg, new_block, new_high, new_low,
4590                                             new_count);
4591         } else {
4592                 new_node = new_rd_ia32_ShrD(dbgi, irg, new_block, new_high, new_low,
4593                                             new_count);
4594         }
4595         SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
4596
4597         return new_node;
4598 }
4599
4600 static ir_node *gen_ia32_l_ShlD(ir_node *node)
4601 {
4602         ir_node *high  = get_irn_n(node, n_ia32_l_ShlD_val_high);
4603         ir_node *low   = get_irn_n(node, n_ia32_l_ShlD_val_low);
4604         ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
4605         return gen_lowered_64bit_shifts(node, high, low, count);
4606 }
4607
4608 static ir_node *gen_ia32_l_ShrD(ir_node *node)
4609 {
4610         ir_node *high  = get_irn_n(node, n_ia32_l_ShrD_val_high);
4611         ir_node *low   = get_irn_n(node, n_ia32_l_ShrD_val_low);
4612         ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
4613         return gen_lowered_64bit_shifts(node, high, low, count);
4614 }
4615
4616 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node) {
4617         ir_node  *src_block    = get_nodes_block(node);
4618         ir_node  *block        = be_transform_node(src_block);
4619         ir_graph *irg          = current_ir_graph;
4620         dbg_info *dbgi         = get_irn_dbg_info(node);
4621         ir_node  *frame        = get_irg_frame(irg);
4622         ir_node  *noreg        = ia32_new_NoReg_gp(env_cg);
4623         ir_node  *nomem        = new_NoMem();
4624         ir_node  *val_low      = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
4625         ir_node  *val_high     = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
4626         ir_node  *new_val_low  = be_transform_node(val_low);
4627         ir_node  *new_val_high = be_transform_node(val_high);
4628         ir_node  *in[2];
4629         ir_node  *sync;
4630         ir_node  *fild;
4631         ir_node  *store_low;
4632         ir_node  *store_high;
4633
4634         if(!mode_is_signed(get_irn_mode(val_high))) {
4635                 panic("unsigned long long -> float not supported yet (%+F)", node);
4636         }
4637
4638         /* do a store */
4639         store_low = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4640                                       new_val_low);
4641         store_high = new_rd_ia32_Store(dbgi, irg, block, frame, noreg, nomem,
4642                                        new_val_high);
4643         SET_IA32_ORIG_NODE(store_low, ia32_get_old_node_name(env_cg, node));
4644         SET_IA32_ORIG_NODE(store_high, ia32_get_old_node_name(env_cg, node));
4645
4646         set_ia32_use_frame(store_low);
4647         set_ia32_use_frame(store_high);
4648         set_ia32_op_type(store_low, ia32_AddrModeD);
4649         set_ia32_op_type(store_high, ia32_AddrModeD);
4650         set_ia32_ls_mode(store_low, mode_Iu);
4651         set_ia32_ls_mode(store_high, mode_Is);
4652         add_ia32_am_offs_int(store_high, 4);
4653
4654         in[0] = store_low;
4655         in[1] = store_high;
4656         sync  = new_rd_Sync(dbgi, irg, block, 2, in);
4657
4658         /* do a fild */
4659         fild = new_rd_ia32_vfild(dbgi, irg, block, frame, noreg, sync);
4660
4661         set_ia32_use_frame(fild);
4662         set_ia32_op_type(fild, ia32_AddrModeS);
4663         set_ia32_ls_mode(fild, mode_Ls);
4664
4665         SET_IA32_ORIG_NODE(fild, ia32_get_old_node_name(env_cg, node));
4666
4667         return new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
4668 }
4669
4670 static ir_node *gen_ia32_l_FloattoLL(ir_node *node) {
4671         ir_node  *src_block  = get_nodes_block(node);
4672         ir_node  *block      = be_transform_node(src_block);
4673         ir_graph *irg        = current_ir_graph;
4674         dbg_info *dbgi       = get_irn_dbg_info(node);
4675         ir_node  *frame      = get_irg_frame(irg);
4676         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
4677         ir_node  *nomem      = new_NoMem();
4678         ir_node  *val        = get_irn_n(node, n_ia32_l_FloattoLL_val);
4679         ir_node  *new_val    = be_transform_node(val);
4680         ir_node  *fist, *mem;
4681
4682         mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
4683         SET_IA32_ORIG_NODE(fist, ia32_get_old_node_name(env_cg, node));
4684         set_ia32_use_frame(fist);
4685         set_ia32_op_type(fist, ia32_AddrModeD);
4686         set_ia32_ls_mode(fist, mode_Ls);
4687
4688         return mem;
4689 }
4690
4691 /**
4692  * the BAD transformer.
4693  */
4694 static ir_node *bad_transform(ir_node *node) {
4695         panic("No transform function for %+F available.\n", node);
4696         return NULL;
4697 }
4698
4699 static ir_node *gen_Proj_l_FloattoLL(ir_node *node) {
4700         ir_graph *irg      = current_ir_graph;
4701         ir_node  *block    = be_transform_node(get_nodes_block(node));
4702         ir_node  *pred     = get_Proj_pred(node);
4703         ir_node  *new_pred = be_transform_node(pred);
4704         ir_node  *frame    = get_irg_frame(irg);
4705         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
4706         dbg_info *dbgi     = get_irn_dbg_info(node);
4707         long      pn       = get_Proj_proj(node);
4708         ir_node  *load;
4709         ir_node  *proj;
4710         ia32_attr_t *attr;
4711
4712         load = new_rd_ia32_Load(dbgi, irg, block, frame, noreg, new_pred);
4713         SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
4714         set_ia32_use_frame(load);
4715         set_ia32_op_type(load, ia32_AddrModeS);
4716         set_ia32_ls_mode(load, mode_Iu);
4717         /* we need a 64bit stackslot (fist stores 64bit) even though we only load
4718          * 32 bit from it with this particular load */
4719         attr = get_ia32_attr(load);
4720         attr->data.need_64bit_stackent = 1;
4721
4722         if (pn == pn_ia32_l_FloattoLL_res_high) {
4723                 add_ia32_am_offs_int(load, 4);
4724         } else {
4725                 assert(pn == pn_ia32_l_FloattoLL_res_low);
4726         }
4727
4728         proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
4729
4730         return proj;
4731 }
4732
4733 /**
4734  * Transform the Projs of an AddSP.
4735  */
4736 static ir_node *gen_Proj_be_AddSP(ir_node *node) {
4737         ir_node  *block    = be_transform_node(get_nodes_block(node));
4738         ir_node  *pred     = get_Proj_pred(node);
4739         ir_node  *new_pred = be_transform_node(pred);
4740         ir_graph *irg      = current_ir_graph;
4741         dbg_info *dbgi     = get_irn_dbg_info(node);
4742         long     proj      = get_Proj_proj(node);
4743
4744         if (proj == pn_be_AddSP_sp) {
4745                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4746                                            pn_ia32_SubSP_stack);
4747                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4748                 return res;
4749         } else if(proj == pn_be_AddSP_res) {
4750                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4751                                    pn_ia32_SubSP_addr);
4752         } else if (proj == pn_be_AddSP_M) {
4753                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
4754         }
4755
4756         assert(0);
4757         return new_rd_Unknown(irg, get_irn_mode(node));
4758 }
4759
4760 /**
4761  * Transform the Projs of a SubSP.
4762  */
4763 static ir_node *gen_Proj_be_SubSP(ir_node *node) {
4764         ir_node  *block    = be_transform_node(get_nodes_block(node));
4765         ir_node  *pred     = get_Proj_pred(node);
4766         ir_node  *new_pred = be_transform_node(pred);
4767         ir_graph *irg      = current_ir_graph;
4768         dbg_info *dbgi     = get_irn_dbg_info(node);
4769         long     proj      = get_Proj_proj(node);
4770
4771         if (proj == pn_be_SubSP_sp) {
4772                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
4773                                            pn_ia32_AddSP_stack);
4774                 arch_set_irn_register(env_cg->arch_env, res, &ia32_gp_regs[REG_ESP]);
4775                 return res;
4776         } else if (proj == pn_be_SubSP_M) {
4777                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
4778         }
4779
4780         assert(0);
4781         return new_rd_Unknown(irg, get_irn_mode(node));
4782 }
4783
4784 /**
4785  * Transform and renumber the Projs from a Load.
4786  */
4787 static ir_node *gen_Proj_Load(ir_node *node) {
4788         ir_node  *new_pred;
4789         ir_node  *block    = be_transform_node(get_nodes_block(node));
4790         ir_node  *pred     = get_Proj_pred(node);
4791         ir_graph *irg      = current_ir_graph;
4792         dbg_info *dbgi     = get_irn_dbg_info(node);
4793         long     proj      = get_Proj_proj(node);
4794
4795
4796         /* loads might be part of source address mode matches, so we don't
4797            transform the ProjMs yet (with the exception of loads whose result is
4798            not used)
4799          */
4800         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4801                 ir_node *res;
4802
4803                 assert(pn_ia32_Load_M == 1); /* convention: mem-result of Source-AM
4804                                                                                 nodes is 1 */
4805                 /* this is needed, because sometimes we have loops that are only
4806                    reachable through the ProjM */
4807                 be_enqueue_preds(node);
4808                 /* do it in 2 steps, to silence firm verifier */
4809                 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4810                 set_Proj_proj(res, pn_ia32_Load_M);
4811                 return res;
4812         }
4813
4814         /* renumber the proj */
4815         new_pred = be_transform_node(pred);
4816         if (is_ia32_Load(new_pred)) {
4817                 switch (proj) {
4818                 case pn_Load_res:
4819                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4820                 case pn_Load_M:
4821                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4822                 case pn_Load_X_regular:
4823                         return new_rd_Jmp(dbgi, irg, block);
4824                 case pn_Load_X_except:
4825                         /* This Load might raise an exception. Mark it. */
4826                         set_ia32_exc_label(new_pred, 1);
4827                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4828                 default:
4829                         break;
4830                 }
4831         } else if (is_ia32_Conv_I2I(new_pred) ||
4832                    is_ia32_Conv_I2I8Bit(new_pred)) {
4833                 set_irn_mode(new_pred, mode_T);
4834                 if (proj == pn_Load_res) {
4835                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4836                 } else if (proj == pn_Load_M) {
4837                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4838                 }
4839         } else if (is_ia32_xLoad(new_pred)) {
4840                 switch (proj) {
4841                 case pn_Load_res:
4842                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4843                 case pn_Load_M:
4844                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4845                 case pn_Load_X_regular:
4846                         return new_rd_Jmp(dbgi, irg, block);
4847                 case pn_Load_X_except:
4848                         /* This Load might raise an exception. Mark it. */
4849                         set_ia32_exc_label(new_pred, 1);
4850                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4851                 default:
4852                         break;
4853                 }
4854         } else if (is_ia32_vfld(new_pred)) {
4855                 switch (proj) {
4856                 case pn_Load_res:
4857                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4858                 case pn_Load_M:
4859                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_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 {
4870                 /* can happen for ProJMs when source address mode happened for the
4871                    node */
4872
4873                 /* however it should not be the result proj, as that would mean the
4874                    load had multiple users and should not have been used for
4875                    SourceAM */
4876                 if (proj != pn_Load_M) {
4877                         panic("internal error: transformed node not a Load");
4878                 }
4879                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4880         }
4881
4882         assert(0);
4883         return new_rd_Unknown(irg, get_irn_mode(node));
4884 }
4885
4886 /**
4887  * Transform and renumber the Projs from a DivMod like instruction.
4888  */
4889 static ir_node *gen_Proj_DivMod(ir_node *node) {
4890         ir_node  *block    = be_transform_node(get_nodes_block(node));
4891         ir_node  *pred     = get_Proj_pred(node);
4892         ir_node  *new_pred = be_transform_node(pred);
4893         ir_graph *irg      = current_ir_graph;
4894         dbg_info *dbgi     = get_irn_dbg_info(node);
4895         ir_mode  *mode     = get_irn_mode(node);
4896         long     proj      = get_Proj_proj(node);
4897
4898         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4899
4900         switch (get_irn_opcode(pred)) {
4901         case iro_Div:
4902                 switch (proj) {
4903                 case pn_Div_M:
4904                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4905                 case pn_Div_res:
4906                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4907                 case pn_Div_X_regular:
4908                         return new_rd_Jmp(dbgi, irg, block);
4909                 case pn_Div_X_except:
4910                         set_ia32_exc_label(new_pred, 1);
4911                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4912                 default:
4913                         break;
4914                 }
4915                 break;
4916         case iro_Mod:
4917                 switch (proj) {
4918                 case pn_Mod_M:
4919                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4920                 case pn_Mod_res:
4921                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4922                 case pn_Mod_X_except:
4923                         set_ia32_exc_label(new_pred, 1);
4924                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4925                 default:
4926                         break;
4927                 }
4928                 break;
4929         case iro_DivMod:
4930                 switch (proj) {
4931                 case pn_DivMod_M:
4932                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4933                 case pn_DivMod_res_div:
4934                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4935                 case pn_DivMod_res_mod:
4936                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4937                 case pn_DivMod_X_regular:
4938                         return new_rd_Jmp(dbgi, irg, block);
4939                 case pn_DivMod_X_except:
4940                         set_ia32_exc_label(new_pred, 1);
4941                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4942                 default:
4943                         break;
4944                 }
4945                 break;
4946         default:
4947                 break;
4948         }
4949
4950         assert(0);
4951         return new_rd_Unknown(irg, mode);
4952 }
4953
4954 /**
4955  * Transform and renumber the Projs from a CopyB.
4956  */
4957 static ir_node *gen_Proj_CopyB(ir_node *node) {
4958         ir_node  *block    = be_transform_node(get_nodes_block(node));
4959         ir_node  *pred     = get_Proj_pred(node);
4960         ir_node  *new_pred = be_transform_node(pred);
4961         ir_graph *irg      = current_ir_graph;
4962         dbg_info *dbgi     = get_irn_dbg_info(node);
4963         ir_mode  *mode     = get_irn_mode(node);
4964         long     proj      = get_Proj_proj(node);
4965
4966         switch(proj) {
4967         case pn_CopyB_M_regular:
4968                 if (is_ia32_CopyB_i(new_pred)) {
4969                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4970                 } else if (is_ia32_CopyB(new_pred)) {
4971                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4972                 }
4973                 break;
4974         default:
4975                 break;
4976         }
4977
4978         assert(0);
4979         return new_rd_Unknown(irg, mode);
4980 }
4981
4982 /**
4983  * Transform and renumber the Projs from a Quot.
4984  */
4985 static ir_node *gen_Proj_Quot(ir_node *node) {
4986         ir_node  *block    = be_transform_node(get_nodes_block(node));
4987         ir_node  *pred     = get_Proj_pred(node);
4988         ir_node  *new_pred = be_transform_node(pred);
4989         ir_graph *irg      = current_ir_graph;
4990         dbg_info *dbgi     = get_irn_dbg_info(node);
4991         ir_mode  *mode     = get_irn_mode(node);
4992         long     proj      = get_Proj_proj(node);
4993
4994         switch(proj) {
4995         case pn_Quot_M:
4996                 if (is_ia32_xDiv(new_pred)) {
4997                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4998                 } else if (is_ia32_vfdiv(new_pred)) {
4999                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
5000                 }
5001                 break;
5002         case pn_Quot_res:
5003                 if (is_ia32_xDiv(new_pred)) {
5004                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
5005                 } else if (is_ia32_vfdiv(new_pred)) {
5006                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
5007                 }
5008                 break;
5009         case pn_Quot_X_regular:
5010         case pn_Quot_X_except:
5011         default:
5012                 break;
5013         }
5014
5015         assert(0);
5016         return new_rd_Unknown(irg, mode);
5017 }
5018
5019 /**
5020  * Transform the Thread Local Storage Proj.
5021  */
5022 static ir_node *gen_Proj_tls(ir_node *node) {
5023         ir_node  *block = be_transform_node(get_nodes_block(node));
5024         ir_graph *irg   = current_ir_graph;
5025         dbg_info *dbgi  = NULL;
5026         ir_node  *res   = new_rd_ia32_LdTls(dbgi, irg, block, mode_Iu);
5027
5028         return res;
5029 }
5030
5031 static ir_node *gen_be_Call(ir_node *node) {
5032         ir_node *res = be_duplicate_node(node);
5033         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5034
5035         return res;
5036 }
5037
5038 static ir_node *gen_be_IncSP(ir_node *node) {
5039         ir_node *res = be_duplicate_node(node);
5040         be_node_add_flags(res, -1, arch_irn_flags_modify_flags);
5041
5042         return res;
5043 }
5044
5045 /**
5046  * Transform the Projs from a be_Call.
5047  */
5048 static ir_node *gen_Proj_be_Call(ir_node *node) {
5049         ir_node  *block       = be_transform_node(get_nodes_block(node));
5050         ir_node  *call        = get_Proj_pred(node);
5051         ir_node  *new_call    = be_transform_node(call);
5052         ir_graph *irg         = current_ir_graph;
5053         dbg_info *dbgi        = get_irn_dbg_info(node);
5054         ir_type  *method_type = be_Call_get_type(call);
5055         int       n_res       = get_method_n_ress(method_type);
5056         long      proj        = get_Proj_proj(node);
5057         ir_mode  *mode        = get_irn_mode(node);
5058         ir_node  *sse_load;
5059         const arch_register_class_t *cls;
5060
5061         /* The following is kinda tricky: If we're using SSE, then we have to
5062          * move the result value of the call in floating point registers to an
5063          * xmm register, we therefore construct a GetST0 -> xLoad sequence
5064          * after the call, we have to make sure to correctly make the
5065          * MemProj and the result Proj use these 2 nodes
5066          */
5067         if (proj == pn_be_Call_M_regular) {
5068                 // get new node for result, are we doing the sse load/store hack?
5069                 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
5070                 ir_node *call_res_new;
5071                 ir_node *call_res_pred = NULL;
5072
5073                 if (call_res != NULL) {
5074                         call_res_new  = be_transform_node(call_res);
5075                         call_res_pred = get_Proj_pred(call_res_new);
5076                 }
5077
5078                 if (call_res_pred == NULL || be_is_Call(call_res_pred)) {
5079                         return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5080                                            pn_be_Call_M_regular);
5081                 } else {
5082                         assert(is_ia32_xLoad(call_res_pred));
5083                         return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
5084                                            pn_ia32_xLoad_M);
5085                 }
5086         }
5087         if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
5088                         && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
5089                 ir_node *fstp;
5090                 ir_node *frame = get_irg_frame(irg);
5091                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
5092                 //ir_node *p;
5093                 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
5094                 ir_node *call_res;
5095
5096                 /* in case there is no memory output: create one to serialize the copy
5097                    FPU -> SSE */
5098                 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
5099                                        pn_be_Call_M_regular);
5100                 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
5101                                        pn_be_Call_first_res);
5102
5103                 /* store st(0) onto stack */
5104                 fstp = new_rd_ia32_vfst(dbgi, irg, block, frame, noreg, call_mem,
5105                                         call_res, mode);
5106                 set_ia32_op_type(fstp, ia32_AddrModeD);
5107                 set_ia32_use_frame(fstp);
5108
5109                 /* load into SSE register */
5110                 sse_load = new_rd_ia32_xLoad(dbgi, irg, block, frame, noreg, fstp,
5111                                              mode);
5112                 set_ia32_op_type(sse_load, ia32_AddrModeS);
5113                 set_ia32_use_frame(sse_load);
5114
5115                 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
5116                                        pn_ia32_xLoad_res);
5117
5118                 return sse_load;
5119         }
5120
5121         /* transform call modes */
5122         if (mode_is_data(mode)) {
5123                 cls  = arch_get_irn_reg_class(env_cg->arch_env, node, -1);
5124                 mode = cls->mode;
5125         }
5126
5127         return new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
5128 }
5129
5130 /**
5131  * Transform the Projs from a Cmp.
5132  */
5133 static ir_node *gen_Proj_Cmp(ir_node *node)
5134 {
5135         /* this probably means not all mode_b nodes were lowered... */
5136         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
5137               node);
5138 }
5139
5140 /**
5141  * Transform and potentially renumber Proj nodes.
5142  */
5143 static ir_node *gen_Proj(ir_node *node) {
5144         ir_node  *pred = get_Proj_pred(node);
5145         if (is_Store(pred)) {
5146                 long proj = get_Proj_proj(node);
5147                 if (proj == pn_Store_M) {
5148                         return be_transform_node(pred);
5149                 } else {
5150                         assert(0);
5151                         return new_r_Bad(current_ir_graph);
5152                 }
5153         } else if (is_Load(pred)) {
5154                 return gen_Proj_Load(node);
5155         } else if (is_Div(pred) || is_Mod(pred) || is_DivMod(pred)) {
5156                 return gen_Proj_DivMod(node);
5157         } else if (is_CopyB(pred)) {
5158                 return gen_Proj_CopyB(node);
5159         } else if (is_Quot(pred)) {
5160                 return gen_Proj_Quot(node);
5161         } else if (be_is_SubSP(pred)) {
5162                 return gen_Proj_be_SubSP(node);
5163         } else if (be_is_AddSP(pred)) {
5164                 return gen_Proj_be_AddSP(node);
5165         } else if (be_is_Call(pred)) {
5166                 return gen_Proj_be_Call(node);
5167         } else if (is_Cmp(pred)) {
5168                 return gen_Proj_Cmp(node);
5169         } else if (get_irn_op(pred) == op_Start) {
5170                 long proj = get_Proj_proj(node);
5171                 if (proj == pn_Start_X_initial_exec) {
5172                         ir_node *block = get_nodes_block(pred);
5173                         dbg_info *dbgi = get_irn_dbg_info(node);
5174                         ir_node *jump;
5175
5176                         /* we exchange the ProjX with a jump */
5177                         block = be_transform_node(block);
5178                         jump  = new_rd_Jmp(dbgi, current_ir_graph, block);
5179                         return jump;
5180                 }
5181                 if (node == be_get_old_anchor(anchor_tls)) {
5182                         return gen_Proj_tls(node);
5183                 }
5184         } else if (is_ia32_l_FloattoLL(pred)) {
5185                 return gen_Proj_l_FloattoLL(node);
5186 #ifdef FIRM_EXT_GRS
5187         } else if(!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
5188 #else
5189         } else {
5190 #endif
5191                 ir_mode *mode = get_irn_mode(node);
5192                 if (mode_needs_gp_reg(mode)) {
5193                         ir_node *new_pred = be_transform_node(pred);
5194                         ir_node *block    = be_transform_node(get_nodes_block(node));
5195                         ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
5196                                                        mode_Iu, get_Proj_proj(node));
5197 #ifdef DEBUG_libfirm
5198                         new_proj->node_nr = node->node_nr;
5199 #endif
5200                         return new_proj;
5201                 }
5202         }
5203
5204         return be_duplicate_node(node);
5205 }
5206
5207 /**
5208  * Enters all transform functions into the generic pointer
5209  */
5210 static void register_transformers(void)
5211 {
5212         ir_op *op_Mulh;
5213
5214         /* first clear the generic function pointer for all ops */
5215         clear_irp_opcodes_generic_func();
5216
5217 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
5218 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
5219
5220         GEN(Add);
5221         GEN(Sub);
5222         GEN(Mul);
5223         GEN(And);
5224         GEN(Or);
5225         GEN(Eor);
5226
5227         GEN(Shl);
5228         GEN(Shr);
5229         GEN(Shrs);
5230         GEN(Rot);
5231
5232         GEN(Quot);
5233
5234         GEN(Div);
5235         GEN(Mod);
5236         GEN(DivMod);
5237
5238         GEN(Minus);
5239         GEN(Conv);
5240         GEN(Abs);
5241         GEN(Not);
5242
5243         GEN(Load);
5244         GEN(Store);
5245         GEN(Cond);
5246
5247         GEN(Cmp);
5248         GEN(ASM);
5249         GEN(CopyB);
5250         BAD(Mux);
5251         GEN(Psi);
5252         GEN(Proj);
5253         GEN(Phi);
5254         GEN(IJmp);
5255
5256         /* transform ops from intrinsic lowering */
5257         GEN(ia32_l_Add);
5258         GEN(ia32_l_Adc);
5259         GEN(ia32_l_Mul);
5260         GEN(ia32_l_IMul);
5261         GEN(ia32_l_ShlDep);
5262         GEN(ia32_l_ShrDep);
5263         GEN(ia32_l_SarDep);
5264         GEN(ia32_l_ShlD);
5265         GEN(ia32_l_ShrD);
5266         GEN(ia32_l_Sub);
5267         GEN(ia32_l_Sbb);
5268         GEN(ia32_l_vfild);
5269         GEN(ia32_l_Load);
5270         GEN(ia32_l_vfist);
5271         GEN(ia32_l_Store);
5272         GEN(ia32_l_LLtoFloat);
5273         GEN(ia32_l_FloattoLL);
5274
5275         GEN(Const);
5276         GEN(SymConst);
5277         GEN(Unknown);
5278
5279         /* we should never see these nodes */
5280         BAD(Raise);
5281         BAD(Sel);
5282         BAD(InstOf);
5283         BAD(Cast);
5284         BAD(Free);
5285         BAD(Tuple);
5286         BAD(Id);
5287         //BAD(Bad);
5288         BAD(Confirm);
5289         BAD(Filter);
5290         BAD(CallBegin);
5291         BAD(EndReg);
5292         BAD(EndExcept);
5293
5294         /* handle generic backend nodes */
5295         GEN(be_FrameAddr);
5296         GEN(be_Call);
5297         GEN(be_IncSP);
5298         GEN(be_Return);
5299         GEN(be_AddSP);
5300         GEN(be_SubSP);
5301         GEN(be_Copy);
5302
5303         op_Mulh = get_op_Mulh();
5304         if (op_Mulh)
5305                 GEN(Mulh);
5306
5307 #undef GEN
5308 #undef BAD
5309 }
5310
5311 /**
5312  * Pre-transform all unknown and noreg nodes.
5313  */
5314 static void ia32_pretransform_node(void *arch_cg) {
5315         ia32_code_gen_t *cg = arch_cg;
5316
5317         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
5318         cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
5319         cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
5320         cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
5321         cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
5322         cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
5323         get_fpcw();
5324 }
5325
5326 /**
5327  * Walker, checks if all ia32 nodes producing more than one result have
5328  * its Projs, other wise creates new projs and keep them using a be_Keep node.
5329  */
5330 static void add_missing_keep_walker(ir_node *node, void *data)
5331 {
5332         int              n_outs, i;
5333         unsigned         found_projs = 0;
5334         const ir_edge_t *edge;
5335         ir_mode         *mode = get_irn_mode(node);
5336         ir_node         *last_keep;
5337         (void) data;
5338         if(mode != mode_T)
5339                 return;
5340         if(!is_ia32_irn(node))
5341                 return;
5342
5343         n_outs = get_ia32_n_res(node);
5344         if(n_outs <= 0)
5345                 return;
5346         if(is_ia32_SwitchJmp(node))
5347                 return;
5348
5349         assert(n_outs < (int) sizeof(unsigned) * 8);
5350         foreach_out_edge(node, edge) {
5351                 ir_node *proj = get_edge_src_irn(edge);
5352                 int      pn   = get_Proj_proj(proj);
5353
5354                 assert(get_irn_mode(proj) == mode_M || pn < n_outs);
5355                 found_projs |= 1 << pn;
5356         }
5357
5358
5359         /* are keeps missing? */
5360         last_keep = NULL;
5361         for(i = 0; i < n_outs; ++i) {
5362                 ir_node                     *block;
5363                 ir_node                     *in[1];
5364                 const arch_register_req_t   *req;
5365                 const arch_register_class_t *class;
5366
5367                 if(found_projs & (1 << i)) {
5368                         continue;
5369                 }
5370
5371                 req   = get_ia32_out_req(node, i);
5372                 class = req->cls;
5373                 if(class == NULL) {
5374                         continue;
5375                 }
5376                 if(class == &ia32_reg_classes[CLASS_ia32_flags]) {
5377                         continue;
5378                 }
5379
5380                 block = get_nodes_block(node);
5381                 in[0] = new_r_Proj(current_ir_graph, block, node,
5382                                    arch_register_class_mode(class), i);
5383                 if(last_keep != NULL) {
5384                         be_Keep_add_node(last_keep, class, in[0]);
5385                 } else {
5386                         last_keep = be_new_Keep(class, current_ir_graph, block, 1, in);
5387                         if(sched_is_scheduled(node)) {
5388                                 sched_add_after(node, last_keep);
5389                         }
5390                 }
5391         }
5392 }
5393
5394 /**
5395  * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
5396  * and keeps them.
5397  */
5398 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
5399 {
5400         ir_graph *irg = be_get_birg_irg(cg->birg);
5401         irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
5402 }
5403
5404 /* do the transformation */
5405 void ia32_transform_graph(ia32_code_gen_t *cg) {
5406         int cse_last;
5407         ir_graph *irg = cg->irg;
5408
5409         register_transformers();
5410         env_cg       = cg;
5411         initial_fpcw = NULL;
5412
5413 BE_TIMER_PUSH(t_heights);
5414         heights      = heights_new(irg);
5415 BE_TIMER_POP(t_heights);
5416         ia32_calculate_non_address_mode_nodes(cg->birg);
5417
5418         /* the transform phase is not safe for CSE (yet) because several nodes get
5419          * attributes set after their creation */
5420         cse_last = get_opt_cse();
5421         set_opt_cse(0);
5422
5423         be_transform_graph(cg->birg, ia32_pretransform_node, cg);
5424
5425         set_opt_cse(cse_last);
5426
5427         ia32_free_non_address_mode_nodes();
5428         heights_free(heights);
5429         heights = NULL;
5430 }
5431
5432 void ia32_init_transform(void)
5433 {
5434         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
5435 }