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