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