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