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