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