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