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