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